38 #ifdef G4VIS_BUILD_OI_DRIVER 
   46 #include <Inventor/SbBox.h> 
   47 #include <Inventor/actions/SoGLRenderAction.h> 
   48 #include <Inventor/fields/SoSFFloat.h> 
   49 #include <Inventor/misc/SoChildList.h> 
   50 #include <Inventor/nodes/SoSeparator.h> 
   51 #include <Inventor/nodes/SoIndexedFaceSet.h> 
   52 #include <Inventor/nodes/SoNormal.h> 
   53 #include <Inventor/nodes/SoCoordinate3.h> 
   54 #include <Inventor/nodes/SoNormalBinding.h> 
   55 #include <Inventor/SoPrimitiveVertex.h> 
   56 #include <Inventor/elements/SoTextureCoordinateElement.h> 
   68   SO_NODE_CONSTRUCTOR(SoTubs);
 
   71   SO_NODE_ADD_FIELD(pRMin,               (0));
 
   72   SO_NODE_ADD_FIELD(pRMax,               (1));
 
   73   SO_NODE_ADD_FIELD(pDz,                 (10));
 
   74   SO_NODE_ADD_FIELD(pSPhi,               (0));
 
   75   SO_NODE_ADD_FIELD(pDPhi,               ((
float)(2*
M_PI)));
 
   76   SO_NODE_ADD_FIELD(alternateRep,        (NULL));
 
   77   children = 
new SoChildList(
this);
 
   89   SO_NODE_INIT_CLASS(SoTubs,SoShape,
"Shape");
 
   98   SoState *state = action->getState();
 
  102   SbBool useTexFunction=
 
  103     (SoTextureCoordinateElement::getType(state) == 
 
  104      SoTextureCoordinateElement::FUNCTION);
 
  109   const SoTextureCoordinateElement* tce = NULL;
 
  111   if (useTexFunction) {
 
  112     tce = SoTextureCoordinateElement::getInstance(state);
 
  118   SbVec3f point, normal;
 
  123 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz)               \ 
  124   point.setValue((float)(x),(float)(y),(float)(z));     \ 
  125   normal.setValue((float)(nx),(float)(ny),(float)(nz)); \ 
  126   if (useTexFunction) {                                 \ 
  127     texCoord=tce->get(point,normal);                    \ 
  129     texCoord[0]=(float)(s);                             \ 
  130     texCoord[1]=(float)(t);                             \ 
  132   pv.setPoint(point);                                   \ 
  133   pv.setNormal(normal);                                 \ 
  134   pv.setTextureCoords(texCoord);                        \ 
  139   int NPHI = (
int)(2+22*std::fabs(
pDPhi.getValue()/(2.0*
M_PI)));
 
  140   double deltaPhi = 
pDPhi.getValue()/NPHI, phi0 = 
pSPhi.getValue(),phi1=phi0+
pDPhi.getValue();
 
  141   double rMax=
pRMax.getValue(),rMin=
pRMin.getValue();
 
  142   double zMax=
pDz.getValue(),zMin=-zMax;
 
  143   double cosPhi0=std::cos(phi0), sinPhi0=std::sin(phi0);
 
  144   double cosPhi1=std::cos(phi1), sinPhi1=std::sin(phi1);
 
  145   double cosDeltaPhi=std::cos(deltaPhi),sinDeltaPhi=std::sin(deltaPhi);
 
  150   double sinPhi,cosPhi;
 
  151   beginShape(action,TRIANGLE_STRIP);
 
  154   for (i = 0; i<=NPHI; i++) {
 
  155     GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,0.0,0.0,cosPhi,sinPhi,0);   
 
  156     GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,cosPhi,sinPhi,0);   
 
  157     inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  164     beginShape(action,TRIANGLE_STRIP);
 
  167     for (i = 0; i<=NPHI; i++) {
 
  168       GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,0.0,0.0,-cosPhi,-sinPhi,0);   
 
  169       GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,1.0,1.0,-cosPhi,-sinPhi,0);   
 
  170       inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  174   if (std::fabs(deltaPhi)<2.0*
M_PI) { 
 
  178     beginShape(action,TRIANGLE_STRIP);
 
  181     GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);   
 
  182     GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);   
 
  183     GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);   
 
  184     GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);   
 
  189     beginShape(action,TRIANGLE_STRIP);
 
  192     GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);   
 
  193     GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);   
 
  194     GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);   
 
  195     GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);   
 
  202     beginShape(action,TRIANGLE_FAN);
 
  205     GEN_VERTEX(pv,0,0,zMax,0.0,0.0,0,0,1);   
 
  206     for (i = 0; i<=NPHI; i++) {
 
  207       GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,1.0,1.0,0,0,1);   
 
  208       inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  214     beginShape(action,TRIANGLE_FAN);
 
  217     GEN_VERTEX(pv,0,0,zMin,0.0,0.0,0,0,-1);   
 
  218     for (i = 0; i<=NPHI; i++) {
 
  219       GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,0,0,-1);   
 
  220       inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  224     beginShape(action,TRIANGLE_STRIP);
 
  227     for (i = 0; i<=NPHI; i++) {
 
  228       GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,0.0,0.0,0,0,1);   
 
  229       GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,1.0,1.0,0,0,1);   
 
  230       inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  236     beginShape(action,TRIANGLE_STRIP);
 
  239     for (i = 0; i<=NPHI; i++) {
 
  240       GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,0.0,0.0,0,0,-1);   
 
  241       GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,0,0,-1);   
 
  242       inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  256   SbVec3f vmin(-
pRMax.getValue(),-
pRMax.getValue(),-
pDz.getValue()), 
 
  258   center.setValue(0,0,0);
 
  259   box.setBounds(vmin,vmax);
 
  264 void SoTubs::updateChildren() {
 
  268   assert(children->getLength()==1);
 
  269   SoSeparator       *sep                = (SoSeparator *)  ( *children)[0];
 
  270   SoCoordinate3     *theCoordinates     = (SoCoordinate3 *)      ( sep->getChild(0));
 
  271   SoNormal          *theNormals         = (SoNormal *)           ( sep->getChild(1)); 
 
  272   SoNormalBinding   *theNormalBinding   = (SoNormalBinding *)    ( sep->getChild(2));
 
  273   SoIndexedFaceSet  *theFaceSet         = (SoIndexedFaceSet *)   ( sep->getChild(3));
 
  276   const int NPHI=24, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
 
  277   float points[NPOINTS][3],normals[NFACES][3];
 
  279   static long     indices[NINDICES];
 
  281   static int32_t  indices[NINDICES];
 
  285   double phi, 
pp, DeltaPhi;
 
  294     for (i = 0; i< NPHI; i++) {
 
  296       indices[5*i+0] =  2*i+0;
 
  297       indices[5*i+1] =  2*i+1;
 
  298       indices[5*i+2] =  2*i+3;
 
  299       indices[5*i+3] =  2*i+2;
 
  300       indices[5*i+4] = SO_END_FACE_INDEX;
 
  303     for (i=0;i<NPHI;i++) {
 
  304       indices[5*1*NPHI + 5*i+0] = 2*NPHI+2 + 2*i+0;  
 
  305       indices[5*1*NPHI + 5*i+1] = 2*NPHI+2 + 2*i+1;
 
  306       indices[5*1*NPHI + 5*i+2] = 2*NPHI+2 + 2*i+3;
 
  307       indices[5*1*NPHI + 5*i+3] = 2*NPHI+2 + 2*i+2;
 
  308       indices[5*1*NPHI + 5*i+4] = SO_END_FACE_INDEX;
 
  311     for (i=0;i<NPHI;i++) {
 
  312       indices[5*2*NPHI + 5*i+0] = 2*i+0;
 
  313       indices[5*2*NPHI + 5*i+1] = 2*i+2;
 
  314       indices[5*2*NPHI + 5*i+2] = NPOINTS - (2*i+4);
 
  315       indices[5*2*NPHI + 5*i+3] = NPOINTS - (2*i+2);
 
  316       indices[5*2*NPHI + 5*i+4] = SO_END_FACE_INDEX;
 
  319     for (i=0;i<NPHI;i++) {
 
  320       indices[5*3*NPHI + 5*i+0] = 2*i+1;
 
  321       indices[5*3*NPHI + 5*i+1] = NPOINTS - (2*i+1);
 
  322       indices[5*3*NPHI + 5*i+2] = NPOINTS - (2*i+3);
 
  323       indices[5*3*NPHI + 5*i+3] = 2*i+3;
 
  324       indices[5*3*NPHI + 5*i+4] = SO_END_FACE_INDEX;
 
  327     indices[5*4*NPHI +0] = 2*NPHI;
 
  328     indices[5*4*NPHI +1] = 2*NPHI+1;
 
  329     indices[5*4*NPHI +2] = 2*NPHI+3;
 
  330     indices[5*4*NPHI +3] = 2*NPHI+2;
 
  331     indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
 
  333     indices[5*4*NPHI +5 +0] = 0;
 
  334     indices[5*4*NPHI +5 +1] = NPOINTS-2;
 
  335     indices[5*4*NPHI +5 +2] = NPOINTS-1;
 
  336     indices[5*4*NPHI +5 +3] = 1;
 
  337     indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
 
  342     indices[5*4*NPHI +0] = 2*NPHI;
 
  343     indices[5*4*NPHI +1] = 2*NPHI+1;
 
  344     indices[5*4*NPHI +2] = 2*NPHI+3;
 
  345     indices[5*4*NPHI +3] = 2*NPHI+2;
 
  346     indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
 
  348     indices[5*4*NPHI +5 +0] = 0;
 
  349     indices[5*4*NPHI +5 +1] = NPOINTS-2;
 
  350     indices[5*4*NPHI +5 +2] = NPOINTS-1;
 
  351     indices[5*4*NPHI +5 +3] = 1;
 
  352     indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
 
  356     indices[5*4*NPHI +0] = SO_END_FACE_INDEX;
 
  357     indices[5*4*NPHI +1] = SO_END_FACE_INDEX;
 
  358     indices[5*4*NPHI +2] = SO_END_FACE_INDEX;
 
  359     indices[5*4*NPHI +3] = SO_END_FACE_INDEX;
 
  360     indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
 
  362     indices[5*4*NPHI +5 +0] = SO_END_FACE_INDEX;
 
  363     indices[5*4*NPHI +5 +1] = SO_END_FACE_INDEX;
 
  364     indices[5*4*NPHI +5 +2] = SO_END_FACE_INDEX;
 
  365     indices[5*4*NPHI +5 +3] = SO_END_FACE_INDEX;
 
  366     indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
 
  369   DeltaPhi = 
pDPhi.getValue()/NPHI, phi = 
pSPhi.getValue();
 
  370   for (i = 0; i<=NPHI; i++) {
 
  371     points[2*i+0][0] = 
pRMax.getValue()*
FCOS(phi); 
 
  372     points[2*i+0][1]= 
pRMax.getValue()*
FSIN(phi); 
 
  373     points[2*i+0][2] = +
pDz.getValue();
 
  375     points[2*i+1][0] = 
pRMax.getValue()*
FCOS(phi); 
 
  376     points[2*i+1][1]= 
pRMax.getValue()*
FSIN(phi); 
 
  377     points[2*i+1][2] = -
pDz.getValue();
 
  379     pp = phi+DeltaPhi/2.0;
 
  381       normals[i][0] = 
FCOS(pp); 
 
  382       normals[i][1] = 
FSIN(pp); 
 
  389   for (i = 0; i<=NPHI; i++) {
 
  390     points[2*NPHI+2+2*i+0][0] = 
pRMin.getValue()*
FCOS(phi); 
 
  391     points[2*NPHI+2+2*i+0][1] = 
pRMin.getValue()*
FSIN(phi); 
 
  392     points[2*NPHI+2+2*i+0][2] = +
pDz.getValue();
 
  393     points[2*NPHI+2+2*i+1][0] = 
pRMin.getValue()*
FCOS(phi); 
 
  394     points[2*NPHI+2+2*i+1][1] = 
pRMin.getValue()*
FSIN(phi); 
 
  395     points[2*NPHI+2+2*i+1][2] = -
pDz.getValue();
 
  396     pp = phi-DeltaPhi/2.0;
 
  398       normals[NPHI+i][0] = -
FCOS(pp); 
 
  399       normals[NPHI+i][1] = -
FSIN(pp); 
 
  400       normals[NPHI+i][2] = 0;
 
  405   for (i=0;i<NPHI;i++) {
 
  406     normals[2*NPHI+i][0]=normals[2*NPHI+i][1]=0; 
 
  407     normals[2*NPHI+i][2]=  1.0;
 
  410   for (i=0;i<NPHI;i++) {
 
  411     normals[3*NPHI+i][0]=normals[3*NPHI+i][1]=0; 
 
  412     normals[3*NPHI+i][2]= -1.0;
 
  415   phi = 
pSPhi.getValue(); 
 
  416   normals[4*NPHI+0][0]=  
FSIN(phi); 
 
  417   normals[4*NPHI+0][1]= -
FCOS(phi); 
 
  418   normals[4*NPHI+0][2]=0;
 
  422   normals[4*NPHI+1][0]= -
FSIN(phi); 
 
  423   normals[4*NPHI+1][1]= +
FCOS(phi); 
 
  424   normals[4*NPHI+1][2]=0;
 
  426   for (
int np=0;np<NPOINTS; np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
 
  427   for (
int ni=0;ni<NINDICES;ni++) theFaceSet->coordIndex.set1Value(ni,indices[ni]);
 
  428   for (
int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
 
  429   theNormalBinding->value=SoNormalBinding::PER_FACE;
 
  433 void SoTubs::generateChildren() {
 
  440   assert(children->getLength() ==0);
 
  441   SoSeparator      *sep              = 
new SoSeparator(); 
 
  442   SoCoordinate3    *theCoordinates   = 
new SoCoordinate3();
 
  443   SoNormal         *theNormals       = 
new SoNormal(); 
 
  444   SoNormalBinding  *theNormalBinding = 
new SoNormalBinding();
 
  445   SoIndexedFaceSet *theFaceSet       = 
new SoIndexedFaceSet();
 
  449   sep->addChild(theCoordinates);
 
  450   sep->addChild(theNormals);
 
  451   sep->addChild(theNormalBinding);
 
  452   sep->addChild(theFaceSet);
 
  453   children->append(sep);
 
  462   if (children->getLength() == 0) generateChildren();