Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/OpenInventor/src/SoTrap.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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
 59 SO_NODE_SOURCE(SoTrap)
 60 
 61 // Constructor
 62 SoTrap::SoTrap() {
 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
 83 SoTrap::~SoTrap() {
 84  delete children;
 85 }
 86 
 87 
 88 // initClass
 89 void SoTrap::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
100 void 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
246 SoChildList *SoTrap::getChildren() const {
247   return children;
248 }
249 
250 
251 // computeBBox
252 void 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
278 void 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
374 void 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
398 void SoTrap::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
409 void SoTrap::clearAlternateRep() {
410   alternateRep.setValue(NULL);
411 }
412