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