38 #ifdef G4VIS_BUILD_OI_DRIVER 
   45 #include <Inventor/SbBox.h> 
   46 #include <Inventor/actions/SoAction.h> 
   47 #include <Inventor/fields/SoSFFloat.h> 
   48 #include <Inventor/misc/SoChildList.h> 
   49 #include <Inventor/nodes/SoSeparator.h> 
   50 #include <Inventor/nodes/SoIndexedFaceSet.h> 
   51 #include <Inventor/nodes/SoNormal.h> 
   52 #include <Inventor/nodes/SoCoordinate3.h> 
   53 #include <Inventor/nodes/SoNormalBinding.h> 
   54 #include <Inventor/SoPrimitiveVertex.h> 
   55 #include <Inventor/elements/SoTextureCoordinateElement.h> 
   65   SO_NODE_CONSTRUCTOR(SoCons);
 
   68   SO_NODE_ADD_FIELD(fRmin1,               (0.0));
 
   69   SO_NODE_ADD_FIELD(fRmin2,               (0.0));
 
   70   SO_NODE_ADD_FIELD(fRmax1,               (1.0));
 
   71   SO_NODE_ADD_FIELD(fRmax2,               (1.0));
 
   72   SO_NODE_ADD_FIELD(fDz,                 (10.0));
 
   73   SO_NODE_ADD_FIELD(fSPhi,                (0.0));
 
   74   SO_NODE_ADD_FIELD(fDPhi,             ((
float)(2*
M_PI)));
 
   75   SO_NODE_ADD_FIELD(smoothDraw,          (
TRUE));
 
   76   SO_NODE_ADD_FIELD(alternateRep,        (NULL));
 
   77   children = 
new SoChildList(
this);
 
   89   SO_NODE_INIT_CLASS(SoCons,SoShape,
"Shape");
 
   99   SoState *state = action->getState();
 
  103   SbBool useTexFunction=
 
  104     (SoTextureCoordinateElement::getType(state) == 
 
  105      SoTextureCoordinateElement::FUNCTION);
 
  110   const SoTextureCoordinateElement *tce = NULL;
 
  112   if (useTexFunction) {
 
  113     tce = SoTextureCoordinateElement::getInstance(state);
 
  118   SbVec3f point, normal;
 
  122 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz)               \ 
  123   point.setValue((float)(x),(float)(y),(float)(z));     \ 
  124   normal.setValue((float)(nx),(float)(ny),(float)(nz)); \ 
  125   if (useTexFunction) {                                 \ 
  126     texCoord=tce->get(point,normal);                    \ 
  128     texCoord[0]=(float)(s);                             \ 
  129     texCoord[1]=(float)(t);                             \ 
  131   pv.setPoint(point);                                   \ 
  132   pv.setNormal(normal);                                 \ 
  133   pv.setTextureCoords(texCoord);                        \ 
  139   int NPHI = (
int)(2+22*std::fabs(
fDPhi.getValue()/(2.0*
M_PI)));
 
  140   double deltaPhi = 
fDPhi.getValue()/NPHI;
 
  141   double phi0     = 
fSPhi.getValue();
 
  142   double phi1     = phi0 + 
fDPhi.getValue();
 
  143   double rMax1    = 
fRmax1.getValue();
 
  144   double rMin1    = 
fRmin1.getValue();
 
  145   double rMax2    = 
fRmax2.getValue();
 
  146   double rMin2    = 
fRmin2.getValue();
 
  147   double zMax     = 
fDz.getValue();
 
  149   double cosPhi0  = std::cos(phi0);
 
  150   double sinPhi0  = std::sin(phi0);
 
  151   double cosPhi1  = std::cos(phi1);
 
  152   double sinPhi1  = std::sin(phi1);
 
  153   double cosDeltaPhi = std::cos(deltaPhi);
 
  154   double sinDeltaPhi = std::sin(deltaPhi);
 
  158   beginShape(action,TRIANGLE_STRIP);
 
  160   double sinPhi=sinPhi0;
 
  161   double cosPhi=cosPhi0;
 
  162   for (i = 0; i<=NPHI; i++) {
 
  163     GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,cosPhi,sinPhi,0);   
 
  164     GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,cosPhi,sinPhi,0);   
 
  165     inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  171   beginShape(action,TRIANGLE_STRIP);
 
  174   for (i = 0; i<=NPHI; i++) {
 
  175     GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,-cosPhi,-sinPhi,0);   
 
  176     GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,1.0,1.0,-cosPhi,-sinPhi,0);   
 
  177     inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  180   if (std::fabs(deltaPhi)<2.0*
M_PI) { 
 
  184     beginShape(action,TRIANGLE_STRIP);
 
  187     GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);   
 
  188     GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);   
 
  189     GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);   
 
  190     GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);   
 
  195     beginShape(action,TRIANGLE_STRIP);
 
  198     GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);  
 
  199     GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);  
 
  200     GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);  
 
  201     GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);  
 
  208   beginShape(action,TRIANGLE_STRIP);
 
  211   for (i = 0; i<=NPHI; i++) {
 
  212     GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,0,0,1);   
 
  213     GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,1.0,1.0,0,0,1);   
 
  214     inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  220   beginShape(action,TRIANGLE_STRIP);
 
  223   for (i = 0; i<=NPHI; i++) {
 
  224     GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,0.0,0,0,-1);   
 
  225     GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,0,0,-1);   
 
  226     inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);    
 
  240   float fRmax= 
fRmax1.getValue();  
 
  241   if (
fRmax2.getValue() > fRmax) fRmax = 
fRmax2.getValue(); 
 
  243   SbVec3f vmin(-fRmax,-fRmax,-
fDz.getValue()), 
 
  244           vmax( fRmax, fRmax, 
fDz.getValue());
 
  245   center.setValue(0,0,0);
 
  246   box.setBounds(vmin,vmax);
 
  253 void SoCons::updateChildren() {
 
  258   assert(children->getLength()==1);
 
  259   SoSeparator       *sep                = (SoSeparator *)  ( *children)[0];
 
  260   SoCoordinate3     *theCoordinates     = (SoCoordinate3 *)      ( sep->getChild(0));
 
  261   SoNormal          *theNormals         = (SoNormal *)           ( sep->getChild(1)); 
 
  262   SoNormalBinding   *theNormalBinding   = (SoNormalBinding *)    ( sep->getChild(2));
 
  263   SoIndexedFaceSet  *theFaceSet         = (SoIndexedFaceSet *)   ( sep->getChild(3));
 
  265   const int NPHI=24, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
 
  266   float points[NPOINTS][3], normals[NFACES][3];
 
  268   static long     indices[NINDICES];
 
  270   static int32_t  indices[NINDICES];
 
  273   double phi, 
pp, DeltaPhi;
 
  282     for (i = 0; i< NPHI; i++) {
 
  284       indices[5*i+0] =  2*i+0;
 
  285       indices[5*i+1] =  2*i+1;
 
  286       indices[5*i+2] =  2*i+3;
 
  287       indices[5*i+3] =  2*i+2;
 
  288       indices[5*i+4] = SO_END_FACE_INDEX;
 
  291     for (i=0;i<NPHI;i++) {
 
  292       indices[5*1*NPHI + 5*i+0] = 2*NPHI+2 + 2*i+0;  
 
  293       indices[5*1*NPHI + 5*i+1] = 2*NPHI+2 + 2*i+1;
 
  294       indices[5*1*NPHI + 5*i+2] = 2*NPHI+2 + 2*i+3;
 
  295       indices[5*1*NPHI + 5*i+3] = 2*NPHI+2 + 2*i+2;
 
  296       indices[5*1*NPHI + 5*i+4] = SO_END_FACE_INDEX;
 
  299     for (i=0;i<NPHI;i++) {
 
  300       indices[5*2*NPHI + 5*i+0] = 2*i+0;
 
  301       indices[5*2*NPHI + 5*i+1] = 2*i+2;
 
  302       indices[5*2*NPHI + 5*i+2] = NPOINTS - (2*i+4);
 
  303       indices[5*2*NPHI + 5*i+3] = NPOINTS - (2*i+2);
 
  304       indices[5*2*NPHI + 5*i+4] = SO_END_FACE_INDEX;
 
  307     for (i=0;i<NPHI;i++) {
 
  308       indices[5*3*NPHI + 5*i+0] = 2*i+1;
 
  309       indices[5*3*NPHI + 5*i+1] = NPOINTS - (2*i+1);
 
  310       indices[5*3*NPHI + 5*i+2] = NPOINTS - (2*i+3);
 
  311       indices[5*3*NPHI + 5*i+3] = 2*i+3;
 
  312       indices[5*3*NPHI + 5*i+4] = SO_END_FACE_INDEX;
 
  315     indices[5*4*NPHI +0] = 2*NPHI;
 
  316     indices[5*4*NPHI +1] = 2*NPHI+1;
 
  317     indices[5*4*NPHI +2] = 2*NPHI+3;
 
  318     indices[5*4*NPHI +3] = 2*NPHI+2;
 
  319     indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
 
  321     indices[5*4*NPHI +5 +0] = 0;
 
  322     indices[5*4*NPHI +5 +1] = NPOINTS-2;
 
  323     indices[5*4*NPHI +5 +2] = NPOINTS-1;
 
  324     indices[5*4*NPHI +5 +3] = 1;
 
  325     indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
 
  329   DeltaPhi = 
fDPhi.getValue()/NPHI, phi = 
fSPhi.getValue();
 
  334   for (i = 0; i<=NPHI; i++) {
 
  335     points[2*i+0][0] = 
fRmax2.getValue()*
FCOS(phi); 
 
  336     points[2*i+0][1] = 
fRmax2.getValue()*
FSIN(phi); 
 
  337     points[2*i+0][2] = +
fDz.getValue();
 
  338     points[2*i+1][0] = 
fRmax1.getValue()*
FCOS(phi); 
 
  339     points[2*i+1][1] = 
fRmax1.getValue()*
FSIN(phi); 
 
  340     points[2*i+1][2] = -
fDz.getValue();
 
  341     pp = phi+DeltaPhi/2.0;
 
  343       normals[i][0] = ct * 
FCOS(pp); 
 
  344       normals[i][1] = ct * 
FSIN(pp); 
 
  354   for (i = 0; i<=NPHI; i++) {
 
  355     points[2*NPHI+2+2*i+0][0] = 
fRmin2.getValue()*
FCOS(phi); 
 
  356     points[2*NPHI+2+2*i+0][1] = 
fRmin2.getValue()*
FSIN(phi); 
 
  357     points[2*NPHI+2+2*i+0][2] = +
fDz.getValue();
 
  358     points[2*NPHI+2+2*i+1][0] = 
fRmin1.getValue()*
FCOS(phi); 
 
  359     points[2*NPHI+2+2*i+1][1] = 
fRmin1.getValue()*
FSIN(phi); 
 
  360     points[2*NPHI+2+2*i+1][2] = -
fDz.getValue();
 
  361     pp = phi-DeltaPhi/2.0;
 
  363       normals[NPHI+i][0] = -ct*
FCOS(pp); 
 
  364       normals[NPHI+i][1] = -ct*
FSIN(pp); 
 
  365       normals[NPHI+i][2] = st;
 
  370   for (i=0;i<NPHI;i++) {
 
  371     normals[2*NPHI+i][0]=normals[2*NPHI+i][1]=0; 
 
  372     normals[2*NPHI+i][2]=  1.0;
 
  375   for (i=0;i<NPHI;i++) {
 
  376     normals[3*NPHI+i][0]=normals[3*NPHI+i][1]=0; 
 
  377     normals[3*NPHI+i][2]= -1.0;
 
  380   phi = 
fSPhi.getValue(); 
 
  381   normals[4*NPHI+0][0]=  
FSIN(phi); 
 
  382   normals[4*NPHI+0][1]= -
FCOS(phi); 
 
  383   normals[4*NPHI+0][2]= 0;
 
  387   normals[4*NPHI+1][0]= -
FSIN(phi); 
 
  388   normals[4*NPHI+1][1]= +
FCOS(phi); 
 
  389   normals[4*NPHI+1][2]=0;
 
  391   for (
int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
 
  392   theFaceSet->coordIndex.setValues(0,NINDICES,indices);
 
  396     for (
int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
 
  397     theNormalBinding->value=SoNormalBinding::PER_FACE;
 
  400     for (
int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
 
  401     theNormalBinding->value=SoNormalBinding::PER_FACE;
 
  406 void SoCons::generateChildren() {
 
  413   assert(children->getLength() ==0);
 
  414   SoSeparator      *sep              = 
new SoSeparator(); 
 
  415   SoCoordinate3    *theCoordinates   = 
new SoCoordinate3();
 
  416   SoNormal         *theNormals       = 
new SoNormal(); 
 
  417   SoNormalBinding  *theNormalBinding = 
new SoNormalBinding();
 
  418   SoIndexedFaceSet *theFaceSet       = 
new SoIndexedFaceSet();
 
  422   sep->addChild(theCoordinates);
 
  423   sep->addChild(theNormals);
 
  424   sep->addChild(theNormalBinding);
 
  425   sep->addChild(theFaceSet);
 
  426   children->append(sep);
 
  435   if (children->getLength() == 0) generateChildren();
 
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
 
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er)
compute bounding Box, required 
 
static void initClass()
Class Initializer, required. 
 
SoSFNode alternateRep
Alternate rep required - for use by users without HEPVis shared objects. 
 
virtual void generatePrimitives(SoAction *action)
Generate Primitives, required. 
 
SoSFFloat fRmin1
Inside radius at -fDz. 
 
SoSFFloat fRmax2
Outside radius at +fDz. 
 
virtual void clearAlternateRep()
We better be able to clear it, too! 
 
SoSFFloat fRmin2
Inside radius at +fDz. 
 
virtual SoChildList * getChildren() const 
GetChildList, required whenever the class has hidden children. 
 
SoSFBool smoothDraw
An Inventor option - slightly better render, worse performance. 
 
virtual ~SoCons()
Destructor, required. 
 
SoSFFloat fDPhi
Delta-angle, in radians. 
 
SoSFFloat fSPhi
Starting angle, in radians. 
 
SoSFFloat fDz
Half-length along Z. 
 
SoSFFloat fRmax1
Outside radius at -fDz. 
 
virtual void generateAlternateRep()