Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SoTrd.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28// $Id$
29//
30/*-----------------------------HEPVis---------------------------------------*/
31/* */
32/* Node: SoTrd */
33/* Description: Represents the G4Trd Geant Geometry entity */
34/* Author: Joe Boudreau Nov 11 1996 */
35/* */
36/*--------------------------------------------------------------------------*/
37
38#ifdef G4VIS_BUILD_OI_DRIVER
39
40#include <assert.h>
41#include <cmath>
42
43#include <Inventor/SbBox.h>
44#include <Inventor/actions/SoAction.h>
45#include <Inventor/fields/SoSFFloat.h>
46#include <Inventor/misc/SoChildList.h>
47#include <Inventor/nodes/SoSeparator.h>
48#include <Inventor/nodes/SoIndexedFaceSet.h>
49#include <Inventor/nodes/SoNormal.h>
50#include <Inventor/nodes/SoCoordinate3.h>
51#include <Inventor/nodes/SoNormalBinding.h>
52#include <Inventor/SoPrimitiveVertex.h>
53#include <Inventor/elements/SoTextureCoordinateElement.h>
54
55#include "HEPVis/SbMath.h"
56#include "HEPVis/nodes/SoTrd.h"
57
58// This statement is required
59SO_NODE_SOURCE(SoTrd)
60
61// initClass
62void SoTrd::initClass(){
63 SO_NODE_INIT_CLASS(SoTrd,SoShape,"Shape");
64}
65// Constructor
67 // This statement is required
68 SO_NODE_CONSTRUCTOR(SoTrd);
69 // Data fields are initialized like this:
70 SO_NODE_ADD_FIELD(fDx1,(1.0));
71 SO_NODE_ADD_FIELD(fDx2,(1.0));
72 SO_NODE_ADD_FIELD(fDy1,(1.0));
73 SO_NODE_ADD_FIELD(fDy2,(1.0));
74 SO_NODE_ADD_FIELD(fDz,(1.0));
75 SO_NODE_ADD_FIELD(alternateRep,(NULL));
76 children = new SoChildList(this);
77}
78// Destructor
80 delete children;
81}
82// generatePrimitives
83void SoTrd::generatePrimitives(SoAction *action) {
84 // This variable is used to store each vertex
85 SoPrimitiveVertex pv;
86
87 // Access the stat from the action
88 SoState *state = action->getState();
89
90 // See if we have to use a texture coordinate function,
91 // rather than generating explicit texture coordinates.
92 SbBool useTexFunction=
93 (SoTextureCoordinateElement::getType(state) ==
94 SoTextureCoordinateElement::FUNCTION);
95
96 // If we need to generate texture coordinates with a function,
97 // we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
98 // set up the coordinates directly.
99 const SoTextureCoordinateElement *tce = NULL;
100 SbVec4f texCoord;
101 if (useTexFunction) {
102 tce = SoTextureCoordinateElement::getInstance(state);
103 }
104 else {
105 texCoord[2] = 0.0;
106 texCoord[3] = 1.0;
107 }
108 SbVec3f point, normal;
109
110
111 //////////////////////////////////////////
112 //----------------------------------------
113#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
114 point.setValue(x,y,z); \
115 normal.setValue(nx,ny,nz); \
116 if (useTexFunction) { \
117 texCoord=tce->get(point,normal); \
118 } \
119 else { \
120 texCoord[0]=s; \
121 texCoord[1]=t; \
122 } \
123 pv.setPoint(point); \
124 pv.setNormal(normal); \
125 pv.setTextureCoords(texCoord); \
126 shapeVertex(&pv);
127 //----------------------------------------
128 //////////////////////////////////////////
129
130 const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
131 int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, //z back.
132 4,5,6,7, SO_END_FACE_INDEX, //z front.
133 0,1,5,4, SO_END_FACE_INDEX, //y up.
134 1,2,6,5, SO_END_FACE_INDEX, //x left.
135 2,3,7,6, SO_END_FACE_INDEX, //y down.
136 3,0,4,7, SO_END_FACE_INDEX}; //x right.
137
138
139 // points for the eight vertices
140 float points[NPOINTS][3];
141 points[0][0] = fDx1.getValue();
142 points[0][1] = fDy1.getValue();
143 points[0][2] = -fDz.getValue();
144
145 points[1][0] = -fDx1.getValue();
146 points[1][1] = fDy1.getValue();
147 points[1][2] = -fDz.getValue();
148
149 points[2][0] = -fDx1.getValue();
150 points[2][1] = -fDy1.getValue();
151 points[2][2] = -fDz.getValue();
152
153 points[3][0] = fDx1.getValue();
154 points[3][1] = -fDy1.getValue();
155 points[3][2] = -fDz.getValue();
156
157 points[4][0] = fDx2.getValue();
158 points[4][1] = fDy2.getValue();
159 points[4][2] = fDz.getValue();
160
161 points[5][0] = -fDx2.getValue();
162 points[5][1] = fDy2.getValue();
163 points[5][2] = fDz.getValue();
164
165 points[6][0] = -fDx2.getValue();
166 points[6][1] = -fDy2.getValue();
167 points[6][2] = fDz.getValue();
168
169 points[7][0] = fDx2.getValue();
170 points[7][1] = -fDy2.getValue();
171 points[7][2] = fDz.getValue();
172
173 float t1 = FATAN((fDx2.getValue()-fDx1.getValue())/(2*fDz.getValue()));
174 float t2 = FATAN((fDy2.getValue()-fDy1.getValue())/(2*fDz.getValue()));
175 float st1 = FSIN(t1);
176 float st2 = FSIN(t2);
177 float ct1 = FCOS(t1);
178 float ct2 = FCOS(t2);
179
180 float normals[NFACES][3];
181 //z back.
182 normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
183 //z front.
184 normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
185 //y up.
186 normals[2][0] = 0 ; normals[2][1] = ct2; normals [2][2] = -st2;
187 //x left.
188 normals[3][0] = -ct1; normals[3][1] = 0; normals [3][2] = -st1;
189 //y down.
190 normals[4][0] = 0 ; normals[4][1] = -ct2; normals [4][2] = -st2;
191 //x right.
192 normals[5][0] = ct1; normals[5][1] = 0; normals [5][2] = -st1;
193
194 float x,y,z;
195 int index;
196 for (int nf=0;nf<NFACES;nf++) {
197 beginShape(action,TRIANGLE_FAN);
198 index = indices[nf * 5];
199 x = points[index][0];
200 y = points[index][1];
201 z = points[index][2];
202 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
203 index = indices[nf * 5 + 1];
204 x = points[index][0];
205 y = points[index][1];
206 z = points[index][2];
207 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
208 index = indices[nf * 5 + 2];
209 x = points[index][0];
210 y = points[index][1];
211 z = points[index][2];
212 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
213 index = indices[nf * 5 + 3];
214 x = points[index][0];
215 y = points[index][1];
216 z = points[index][2];
217 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
218 endShape();
219 }
220}
221
222// getChildren
223SoChildList *SoTrd::getChildren() const {
224 return children;
225}
226
227
228// computeBBox
229void SoTrd::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
230 float fDx= fDx1.getValue(),fDy=fDy1.getValue();
231
232 if (fDx2.getValue() > fDx) fDx = fDx2.getValue();
233 if (fDy2.getValue() > fDy) fDy = fDy2.getValue();
234
235 SbVec3f vmin(-fDx,-fDy,-fDz.getValue()),
236 vmax( fDx, fDy, fDz.getValue());
237
238 center.setValue(0,0,0);
239 box.setBounds(vmin,vmax);
240}
241
242
243
244
245// updateChildren
246void SoTrd::updateChildren() {
247
248
249 // Redraw the G4Trd....
250
251 assert(children->getLength()==1);
252 SoSeparator *sep = (SoSeparator *) ( *children)[0];
253 SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
254 SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
255 SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
256 SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
257
258 const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
259 float points[NPOINTS][3];
260 float normals[NFACES][3]= {{0,0,-1}, {0,0,1}, {0,1,0}, {-1, 0, 0}, {0, -1, 0}, {1,0,0}};
261
262 // Indices for the eight faces
263#ifdef INVENTOR2_0
264 static long
265#else
266 static int32_t
267#endif
268 indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, // bottom
269 4,5,6,7, SO_END_FACE_INDEX, // top
270 0,1,5,4, SO_END_FACE_INDEX,
271 1,2,6,5, SO_END_FACE_INDEX,
272 2,3,7,6, SO_END_FACE_INDEX,
273 3,0,4,7, SO_END_FACE_INDEX};
274
275
276 // points for the eight vertices
277 points[0][0] = fDx1.getValue(); points[0][1] = fDy1.getValue(); points[0][2] = -fDz.getValue();
278 points[1][0] = -fDx1.getValue(); points[1][1] = fDy1.getValue(); points[1][2] = -fDz.getValue();
279 points[2][0] = -fDx1.getValue(); points[2][1] = -fDy1.getValue(); points[2][2] = -fDz.getValue();
280 points[3][0] = fDx1.getValue(); points[3][1] = -fDy1.getValue(); points[3][2] = -fDz.getValue();
281 points[4][0] = fDx2.getValue(); points[4][1] = fDy2.getValue(); points[4][2] = fDz.getValue();
282 points[5][0] = -fDx2.getValue(); points[5][1] = fDy2.getValue(); points[5][2] = fDz.getValue();
283 points[6][0] = -fDx2.getValue(); points[6][1] = -fDy2.getValue(); points[6][2] = fDz.getValue();
284 points[7][0] = fDx2.getValue(); points[7][1] = -fDy2.getValue(); points[7][2] = fDz.getValue();
285
286 float t1 = FATAN((fDx2.getValue()-fDx1.getValue())/(2*fDz.getValue()));
287 float t2 = FATAN((fDy2.getValue()-fDy1.getValue())/(2*fDz.getValue()));
288 float st1 = FSIN(t1);
289 float st2 = FSIN(t2);
290 float ct1 = FCOS(t1);
291 float ct2 = FCOS(t2);
292
293 normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
294 normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
295 normals[2][0] = 0 ; normals[2][1] = ct2; normals [2][2] = -st2;
296 normals[3][0] = -ct1; normals[3][1] = 0; normals [3][2] = -st1;
297 normals[4][0] = 0 ; normals[4][1] = -ct2; normals [4][2] = -st2;
298 normals[5][0] = ct1; normals[5][1] = 0; normals [5][2] = -st1;
299
300 for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
301 theFaceSet->coordIndex.setValues(0,NINDICES,indices);
302 for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
303 theNormalBinding->value=SoNormalBinding::PER_FACE;
304}
305
306// generateChildren
307void SoTrd::generateChildren() {
308
309 // This routines creates one SoSeparator, one SoCoordinate3, and
310 // one SoLineSet, and puts it in the child list. This is done only
311 // once, whereas redrawing the position of the coordinates occurs each
312 // time an update is necessary, in the updateChildren routine.
313
314 assert(children->getLength() ==0);
315 SoSeparator *sep = new SoSeparator();
316 SoCoordinate3 *theCoordinates = new SoCoordinate3();
317 SoNormal *theNormals = new SoNormal();
318 SoNormalBinding *theNormalBinding = new SoNormalBinding();
319 SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
320 //
321 // This line costs some in render quality! but gives speed.
322 //
323 sep->addChild(theCoordinates);
324 sep->addChild(theNormals);
325 sep->addChild(theNormalBinding);
326 sep->addChild(theFaceSet);
327 children->append(sep);
328}
329
330// generateAlternateRep
332
333 // This routine sets the alternate representation to the child
334 // list of this mode.
335
336 if (children->getLength() == 0) generateChildren();
337 updateChildren();
338 alternateRep.setValue((SoSeparator *) ( *children)[0]);
339}
340
341// clearAlternateRep
343 alternateRep.setValue(NULL);
344}
345
346#endif
#define FCOS(x)
Definition: SbMath.h:41
#define FSIN(x)
Definition: SbMath.h:42
#define FATAN(x)
Definition: SbMath.h:46
Definition: SoTrd.h:63
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
compute bounding Box, required
SoSFFloat fDx2
half-length of x, at +fDz
Definition: SoTrd.h:80
virtual void generateAlternateRep()
virtual void clearAlternateRep()
We better be able to clear it, too!
SoTrd()
Constructor, required.
virtual void generatePrimitives(SoAction *action)
Generate Primitives, required.
virtual ~SoTrd()
Destructor, required.
SoSFFloat fDy2
half-length of y, at +fDz
Definition: SoTrd.h:90
SoSFFloat fDy1
half-length of y, at -fDz
Definition: SoTrd.h:85
SoSFNode alternateRep
Alternate rep - required.
Definition: SoTrd.h:100
static void initClass()
Class Initializer, required.
SoSFFloat fDx1
half-length of x, at -fDz
Definition: SoTrd.h:75
virtual SoChildList * getChildren() const
GetChildList, required whenever the class has hidden children.
SoSFFloat fDz
half-length along Z
Definition: SoTrd.h:95