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