39 #ifdef G4VIS_BUILD_OI_DRIVER 
   42 #include "HEPVis/nodes/SoTrap.h" 
   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> 
   59 #include "HEPVis/SbMath.h" 
   62 SO_NODE_SOURCE(SoTrap)
 
   67   SO_NODE_CONSTRUCTOR(SoTrap);
 
   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);
 
   92 void SoTrap::initClass(){
 
   94   SO_NODE_INIT_CLASS(SoTrap,SoShape,
"Shape");
 
   99 void SoTrap::generatePrimitives(SoAction *action) {
 
  101   SoPrimitiveVertex pv;
 
  104   SoState *state = action->getState();
 
  108   SbBool useTexFunction=
 
  109     (SoTextureCoordinateElement::getType(state) == 
 
  110      SoTextureCoordinateElement::FUNCTION);
 
  115   const SoTextureCoordinateElement *tce = NULL;
 
  117   if (useTexFunction) {
 
  118     tce = SoTextureCoordinateElement::getInstance(state);
 
  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);       \ 
  139   pv.setPoint(point);                      \ 
  140   pv.setNormal(normal);                    \ 
  141   pv.setTextureCoords(texCoord);           \ 
  146   const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
 
  147   int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,  
 
  148                            4,5,6,7, SO_END_FACE_INDEX,  
 
  149                            0,1,5,4, SO_END_FACE_INDEX,  
 
  150                            1,2,6,5, SO_END_FACE_INDEX,  
 
  151                            2,3,7,6, SO_END_FACE_INDEX,  
 
  152                            3,0,4,7, SO_END_FACE_INDEX}; 
 
  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());
 
  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();
 
  165   points[1][0] = -pDx2.getValue()+pDy1.getValue()*Talp1;
 
  166   points[1][1] =  pDy1.getValue();
 
  167   points[1][2] = -pDz.getValue();
 
  169   points[2][0] = -pDx1.getValue()-pDy1.getValue()*Talp1;
 
  170   points[2][1] = -pDy1.getValue();
 
  171   points[2][2] = -pDz.getValue();
 
  173   points[3][0] =  pDx1.getValue()-pDy1.getValue()*Talp1;
 
  174   points[3][1] = -pDy1.getValue();
 
  175   points[3][2] = -pDz.getValue();
 
  177   points[4][0] =  pDx4.getValue()+pDy2.getValue()*Talp2;
 
  178   points[4][1] =  pDy2.getValue();
 
  179   points[4][2] =  pDz.getValue();
 
  181   points[5][0] = -pDx4.getValue()+pDy2.getValue()*Talp2;
 
  182   points[5][1] =  pDy2.getValue();
 
  183   points[5][2] =  pDz.getValue();
 
  185   points[6][0] = -pDx3.getValue()-pDy2.getValue()*Talp2;
 
  186   points[6][1] = -pDy2.getValue();
 
  187   points[6][2] =  pDz.getValue();
 
  189   points[7][0] =  pDx3.getValue()-pDy2.getValue()*Talp2;
 
  190   points[7][1] = -pDy2.getValue();
 
  191   points[7][2] =  pDz.getValue();
 
  195     points[i][0] -= pDz.getValue()*TthetaCphi;
 
  196     points[i][1] -= pDz.getValue()*TthetaSphi;
 
  199     points[i][0] += pDz.getValue()*TthetaCphi;
 
  200     points[i][1] += pDz.getValue()*TthetaSphi;
 
  203   SbVec3f normals[NFACES];
 
  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();
 
  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]);   
 
  245 SoChildList *SoTrap::getChildren()
 const {
 
  251 void SoTrap::computeBBox(SoAction *, SbBox3f &box, SbVec3f ¢er ){
 
  252   float pDx= pDx1.getValue(),pDy=pDy1.getValue();
 
  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());
 
  265   pDy += FFABS(TthetaSphi*pDz.getValue());  
 
  268   center.setValue(0,0,0);
 
  269   box.setBounds(SbVec3f(-pDx,-pDy,-pDz.getValue()),
 
  270           SbVec3f( pDx, pDy, pDz.getValue()));
 
  277 void SoTrap::updateChildren() {
 
  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));
 
  289   const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
 
  290   float points[NPOINTS][3];
 
  297   indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, 
 
  298                      4,5,6,7, SO_END_FACE_INDEX, 
 
  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};
 
  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());
 
  311   points[0][0] =  pDx2.getValue()+pDy1.getValue()*Talp1;
 
  312   points[0][1] =  pDy1.getValue();
 
  313   points[0][2] = -pDz.getValue();
 
  315   points[1][0] = -pDx2.getValue()+pDy1.getValue()*Talp1;
 
  316   points[1][1] =  pDy1.getValue();
 
  317   points[1][2] = -pDz.getValue();
 
  319   points[2][0] = -pDx1.getValue()-pDy1.getValue()*Talp1;
 
  320   points[2][1] = -pDy1.getValue();
 
  321   points[2][2] = -pDz.getValue();
 
  323   points[3][0] =  pDx1.getValue()-pDy1.getValue()*Talp1;
 
  324   points[3][1] = -pDy1.getValue();
 
  325   points[3][2] = -pDz.getValue();
 
  327   points[4][0] =  pDx4.getValue()+pDy2.getValue()*Talp2;
 
  328   points[4][1] =  pDy2.getValue();
 
  329   points[4][2] =  pDz.getValue();
 
  331   points[5][0] = -pDx4.getValue()+pDy2.getValue()*Talp2;
 
  332   points[5][1] =  pDy2.getValue();
 
  333   points[5][2] =  pDz.getValue();
 
  335   points[6][0] = -pDx3.getValue()-pDy2.getValue()*Talp2;
 
  336   points[6][1] = -pDy2.getValue();
 
  337   points[6][2] =  pDz.getValue();
 
  339   points[7][0] =  pDx3.getValue()-pDy2.getValue()*Talp2;
 
  340   points[7][1] = -pDy2.getValue();
 
  341   points[7][2] =  pDz.getValue();
 
  345     points[i][0] -= pDz.getValue()*TthetaCphi;
 
  346     points[i][1] -= pDz.getValue()*TthetaSphi;
 
  349     points[i][0] += pDz.getValue()*TthetaCphi;
 
  350     points[i][1] += pDz.getValue()*TthetaSphi;
 
  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);
 
  367     theNormals->vector.set1Value(
n,normal);
 
  369   theNormalBinding->value=SoNormalBinding::PER_FACE;
 
  373 void SoTrap::generateChildren() {
 
  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();
 
  389   sep->addChild(theCoordinates);
 
  390   sep->addChild(theNormals);
 
  391   sep->addChild(theNormalBinding);
 
  392   sep->addChild(theFaceSet);
 
  393   children->append(sep);
 
  397 void SoTrap::generateAlternateRep() {
 
  402   if (children->getLength() == 0) generateChildren();
 
  404   alternateRep.setValue((SoSeparator *)  ( *children)[0]);
 
  408 void SoTrap::clearAlternateRep() {
 
  409   alternateRep.setValue(NULL);
 
static double normal(HepRandomEngine *eptr)
 
const G4double x[NPOINTSGL]