00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 #ifdef G4VIS_BUILD_OI_DRIVER
00039 
00040 #include <assert.h>
00041 #include <cmath>
00042 
00043 #include <Inventor/SbBox.h>
00044 #include <Inventor/actions/SoAction.h>
00045 #include <Inventor/fields/SoSFFloat.h>
00046 #include <Inventor/misc/SoChildList.h>
00047 #include <Inventor/nodes/SoSeparator.h>
00048 #include <Inventor/nodes/SoIndexedFaceSet.h>
00049 #include <Inventor/nodes/SoNormal.h>
00050 #include <Inventor/nodes/SoCoordinate3.h>
00051 #include <Inventor/nodes/SoNormalBinding.h>
00052 #include <Inventor/SoPrimitiveVertex.h>
00053 #include <Inventor/elements/SoTextureCoordinateElement.h>
00054 
00055 #include "HEPVis/SbMath.h"
00056 #include "HEPVis/nodes/SoTrd.h"
00057 
00058 
00059 SO_NODE_SOURCE(SoTrd)
00060 
00061 
00062 void SoTrd::initClass(){
00063   SO_NODE_INIT_CLASS(SoTrd,SoShape,"Shape");
00064 }
00065 
00066 SoTrd::SoTrd() {
00067   
00068   SO_NODE_CONSTRUCTOR(SoTrd);
00069   
00070   SO_NODE_ADD_FIELD(fDx1,(1.0));
00071   SO_NODE_ADD_FIELD(fDx2,(1.0));
00072   SO_NODE_ADD_FIELD(fDy1,(1.0));
00073   SO_NODE_ADD_FIELD(fDy2,(1.0));
00074   SO_NODE_ADD_FIELD(fDz,(1.0));
00075   SO_NODE_ADD_FIELD(alternateRep,(NULL));
00076   children = new SoChildList(this);
00077 }
00078 
00079 SoTrd::~SoTrd() {
00080   delete children;
00081 }
00082 
00083 void SoTrd::generatePrimitives(SoAction *action) {
00084   
00085   SoPrimitiveVertex pv;
00086 
00087   
00088   SoState *state = action->getState();
00089 
00090   
00091   
00092   SbBool useTexFunction=
00093     (SoTextureCoordinateElement::getType(state) == 
00094      SoTextureCoordinateElement::FUNCTION);
00095 
00096   
00097   
00098   
00099   const SoTextureCoordinateElement *tce = NULL;
00100   SbVec4f texCoord;
00101   if (useTexFunction) {
00102     tce = SoTextureCoordinateElement::getInstance(state);
00103   }
00104   else {
00105     texCoord[2] = 0.0;
00106     texCoord[3] = 1.0;
00107   }
00108   SbVec3f point, normal;
00109 
00110 
00112   
00113 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz)  \
00114   point.setValue(x,y,z);                   \
00115   normal.setValue(nx,ny,nz);               \
00116   if (useTexFunction) {                    \
00117     texCoord=tce->get(point,normal);       \
00118   }                                        \
00119   else {                                   \
00120     texCoord[0]=s;                         \
00121     texCoord[1]=t;                         \
00122   }                                        \
00123   pv.setPoint(point);                      \
00124   pv.setNormal(normal);                    \
00125   pv.setTextureCoords(texCoord);           \
00126   shapeVertex(&pv);
00127   
00129 
00130   const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
00131   int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,  
00132                            4,5,6,7, SO_END_FACE_INDEX,  
00133                            0,1,5,4, SO_END_FACE_INDEX,  
00134                            1,2,6,5, SO_END_FACE_INDEX,  
00135                            2,3,7,6, SO_END_FACE_INDEX,  
00136                            3,0,4,7, SO_END_FACE_INDEX}; 
00137 
00138   
00139   
00140   float points[NPOINTS][3];
00141   points[0][0] =  fDx1.getValue(); 
00142   points[0][1] =  fDy1.getValue(); 
00143   points[0][2] = -fDz.getValue();
00144 
00145   points[1][0] = -fDx1.getValue();
00146   points[1][1] =  fDy1.getValue();
00147   points[1][2] = -fDz.getValue();
00148 
00149   points[2][0] = -fDx1.getValue(); 
00150   points[2][1] = -fDy1.getValue(); 
00151   points[2][2] = -fDz.getValue();
00152 
00153   points[3][0] =  fDx1.getValue(); 
00154   points[3][1] = -fDy1.getValue(); 
00155   points[3][2] = -fDz.getValue();
00156 
00157   points[4][0] =  fDx2.getValue(); 
00158   points[4][1] =  fDy2.getValue(); 
00159   points[4][2] =  fDz.getValue();
00160 
00161   points[5][0] = -fDx2.getValue(); 
00162   points[5][1] =  fDy2.getValue(); 
00163   points[5][2] =  fDz.getValue();
00164 
00165   points[6][0] = -fDx2.getValue(); 
00166   points[6][1] = -fDy2.getValue(); 
00167   points[6][2] =  fDz.getValue();
00168 
00169   points[7][0] =  fDx2.getValue(); 
00170   points[7][1] = -fDy2.getValue(); 
00171   points[7][2] =  fDz.getValue();
00172 
00173   float t1  = FATAN((fDx2.getValue()-fDx1.getValue())/(2*fDz.getValue()));
00174   float t2  = FATAN((fDy2.getValue()-fDy1.getValue())/(2*fDz.getValue()));
00175   float st1 = FSIN(t1);
00176   float st2 = FSIN(t2);
00177   float ct1 = FCOS(t1);
00178   float ct2 = FCOS(t2);
00179 
00180   float normals[NFACES][3];
00181   
00182   normals[0][0] = 0   ; normals[0][1] =    0; normals [0][2] =  -1;    
00183   
00184   normals[1][0] = 0   ; normals[1][1] =    0; normals [1][2] =   1;    
00185   
00186   normals[2][0] = 0   ; normals[2][1] =  ct2; normals [2][2] = -st2;    
00187   
00188   normals[3][0] = -ct1; normals[3][1] =    0; normals [3][2] = -st1;    
00189   
00190   normals[4][0] = 0   ; normals[4][1] = -ct2; normals [4][2] = -st2;    
00191   
00192   normals[5][0] =  ct1; normals[5][1] =    0; normals [5][2] = -st1;    
00193 
00194   float x,y,z;
00195   int   index;
00196   for (int nf=0;nf<NFACES;nf++) {
00197     beginShape(action,TRIANGLE_FAN);
00198     index = indices[nf * 5];   
00199     x = points[index][0];
00200     y = points[index][1];
00201     z = points[index][2];
00202     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
00203     index = indices[nf * 5 + 1];   
00204     x = points[index][0];
00205     y = points[index][1];
00206     z = points[index][2];
00207     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
00208     index = indices[nf * 5 + 2];   
00209     x = points[index][0];
00210     y = points[index][1];
00211     z = points[index][2];
00212     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
00213     index = indices[nf * 5 + 3];   
00214     x = points[index][0];
00215     y = points[index][1];
00216     z = points[index][2];
00217     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
00218     endShape();
00219   }
00220 }
00221 
00222 
00223 SoChildList *SoTrd::getChildren() const {
00224   return children;
00225 }
00226 
00227 
00228 
00229 void SoTrd::computeBBox(SoAction *, SbBox3f &box, SbVec3f ¢er ){
00230   float fDx= fDx1.getValue(),fDy=fDy1.getValue();
00231   
00232   if (fDx2.getValue() > fDx) fDx = fDx2.getValue(); 
00233   if (fDy2.getValue() > fDy) fDy = fDy2.getValue(); 
00234 
00235   SbVec3f vmin(-fDx,-fDy,-fDz.getValue()), 
00236           vmax( fDx, fDy, fDz.getValue());
00237 
00238   center.setValue(0,0,0);
00239   box.setBounds(vmin,vmax);
00240 }
00241 
00242 
00243 
00244 
00245 
00246 void SoTrd::updateChildren() {
00247 
00248 
00249   
00250 
00251   assert(children->getLength()==1);
00252   SoSeparator       *sep                = (SoSeparator *)  ( *children)[0];
00253   SoCoordinate3     *theCoordinates     = (SoCoordinate3 *)      ( sep->getChild(0));
00254   SoNormal          *theNormals         = (SoNormal *)           ( sep->getChild(1)); 
00255   SoNormalBinding   *theNormalBinding   = (SoNormalBinding *)    ( sep->getChild(2));
00256   SoIndexedFaceSet  *theFaceSet         = (SoIndexedFaceSet *)   ( sep->getChild(3));
00257 
00258   const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
00259   float points[NPOINTS][3];
00260   float normals[NFACES][3]= {{0,0,-1}, {0,0,1}, {0,1,0}, {-1, 0, 0}, {0, -1, 0}, {1,0,0}};
00261 
00262   
00263 #ifdef INVENTOR2_0
00264   static long  
00265 #else 
00266   static int32_t
00267 #endif
00268   indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, 
00269                                        4,5,6,7, SO_END_FACE_INDEX, 
00270                                        0,1,5,4, SO_END_FACE_INDEX, 
00271                                        1,2,6,5, SO_END_FACE_INDEX,
00272                                        2,3,7,6, SO_END_FACE_INDEX,
00273                                        3,0,4,7, SO_END_FACE_INDEX};
00274 
00275   
00276   
00277   points[0][0] =  fDx1.getValue(); points[0][1] =  fDy1.getValue(); points[0][2] = -fDz.getValue();
00278   points[1][0] = -fDx1.getValue(); points[1][1] =  fDy1.getValue(); points[1][2] = -fDz.getValue();
00279   points[2][0] = -fDx1.getValue(); points[2][1] = -fDy1.getValue(); points[2][2] = -fDz.getValue();
00280   points[3][0] =  fDx1.getValue(); points[3][1] = -fDy1.getValue(); points[3][2] = -fDz.getValue();
00281   points[4][0] =  fDx2.getValue(); points[4][1] =  fDy2.getValue(); points[4][2] =  fDz.getValue();
00282   points[5][0] = -fDx2.getValue(); points[5][1] =  fDy2.getValue(); points[5][2] =  fDz.getValue();
00283   points[6][0] = -fDx2.getValue(); points[6][1] = -fDy2.getValue(); points[6][2] =  fDz.getValue();
00284   points[7][0] =  fDx2.getValue(); points[7][1] = -fDy2.getValue(); points[7][2] =  fDz.getValue();
00285 
00286   float t1 = FATAN((fDx2.getValue()-fDx1.getValue())/(2*fDz.getValue()));
00287   float t2 = FATAN((fDy2.getValue()-fDy1.getValue())/(2*fDz.getValue()));
00288   float st1 = FSIN(t1);
00289   float st2 = FSIN(t2);
00290   float ct1 = FCOS(t1);
00291   float ct2 = FCOS(t2);
00292 
00293   normals[0][0] = 0   ; normals[0][1] =    0; normals [0][2] =  -1;    
00294   normals[1][0] = 0   ; normals[1][1] =    0; normals [1][2] =   1;    
00295   normals[2][0] = 0   ; normals[2][1] =  ct2; normals [2][2] = -st2;    
00296   normals[3][0] = -ct1; normals[3][1] =    0; normals [3][2] = -st1;    
00297   normals[4][0] = 0   ; normals[4][1] = -ct2; normals [4][2] = -st2;    
00298   normals[5][0] =  ct1; normals[5][1] =    0; normals [5][2] = -st1;    
00299 
00300   for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
00301   theFaceSet->coordIndex.setValues(0,NINDICES,indices);
00302   for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
00303   theNormalBinding->value=SoNormalBinding::PER_FACE;
00304 }
00305 
00306 
00307 void SoTrd::generateChildren() {
00308 
00309   
00310   
00311   
00312   
00313 
00314   assert(children->getLength() ==0);
00315   SoSeparator      *sep              = new SoSeparator(); 
00316   SoCoordinate3    *theCoordinates   = new SoCoordinate3();
00317   SoNormal         *theNormals       = new SoNormal(); 
00318   SoNormalBinding  *theNormalBinding = new SoNormalBinding();
00319   SoIndexedFaceSet *theFaceSet       = new SoIndexedFaceSet();
00320   
00321   
00322   
00323   sep->addChild(theCoordinates);
00324   sep->addChild(theNormals);
00325   sep->addChild(theNormalBinding);
00326   sep->addChild(theFaceSet);
00327   children->append(sep);
00328 }
00329 
00330 
00331 void SoTrd::generateAlternateRep() {
00332 
00333   
00334   
00335 
00336   if (children->getLength() == 0) generateChildren();
00337   updateChildren();
00338   alternateRep.setValue((SoSeparator *)  ( *children)[0]);
00339 }
00340 
00341 
00342 void SoTrd::clearAlternateRep() {
00343   alternateRep.setValue(NULL);
00344 }
00345 
00346 #endif