Geant4  10.02.p02
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: SoTrd.cc 66373 2012-12-18 09:41:34Z gcosmo $
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
59 SO_NODE_SOURCE(SoTrd)
60 
61 // initClass
62 void SoTrd::initClass(){
63  SO_NODE_INIT_CLASS(SoTrd,SoShape,"Shape");
64 }
65 // Constructor
66 SoTrd::SoTrd() {
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
79 SoTrd::~SoTrd() {
80  delete children;
81 }
82 // generatePrimitives
83 void 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 
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  //----------------------------------------
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
223 SoChildList *SoTrd::getChildren() const {
224  return children;
225 }
226 
227 
228 // computeBBox
229 void 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
246 void 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
307 void 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
331 void SoTrd::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
342 void SoTrd::clearAlternateRep() {
343  alternateRep.setValue(NULL);
344 }
345 
346 #endif
G4double z
Definition: TRTMaterials.hh:39
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
const G4double x[NPOINTSGL]