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