Geant4  10.02.p02
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: SoTrap.cc 66373 2012-12-18 09:41:34Z gcosmo $
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
62 SO_NODE_SOURCE(SoTrap)
63 
64 // Constructor
65 SoTrap::SoTrap() {
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
86 SoTrap::~SoTrap() {
87  delete children;
88 }
89 
90 
91 // initClass
92 void SoTrap::initClass(){
93  // This statement is required.
94  SO_NODE_INIT_CLASS(SoTrap,SoShape,"Shape");
95 }
96 
97 
98 // generatePrimitives
99 void 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 
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  //----------------------------------------
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
245 SoChildList *SoTrap::getChildren() const {
246  return children;
247 }
248 
249 
250 // computeBBox
251 void 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
277 void 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
373 void 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
397 void SoTrap::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
408 void SoTrap::clearAlternateRep() {
409  alternateRep.setValue(NULL);
410 }
411 
412 #endif
G4double z
Definition: TRTMaterials.hh:39
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
const G4int n
const G4double x[NPOINTSGL]