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