CMS 3D CMS Logo

IgSoPcon Class Reference

IgSoPcon produces an OIV version of the GEANT3 PCON shape. More...

#include <Iguana/Inventor/interface/IgSoPcon.h>

Inheritance diagram for IgSoPcon:

IgSoShapeKit

List of all members.

Public Member Functions

 IgSoPcon (void)
void initialise (const int nzee, const float phi, const float delPhi, const float *zvals, const float *rmin, const float *rmax)
 this initialisation method matches the old definition
void makePcon (const std::vector< float > &zvals, const std::vector< float > &rmin, const std::vector< float > &rmax, float phiStart=0, float phiDelta=2 *M_PI, int divisions=-1)
 this initialisation method matches the equivalent one in IgSoRotSolid

Static Public Member Functions

static void initClass (void)

Public Attributes

SoSFVec3f center
SoSFFloat phiDelta
SoSFFloat phiStart
SoMFVec3f vertices

Protected Member Functions

virtual void refresh (void)

Private Member Functions

 SO_KIT_CATALOG_ENTRY_HEADER (side2Face)
 SO_KIT_CATALOG_ENTRY_HEADER (side2Hints)
 SO_KIT_CATALOG_ENTRY_HEADER (side2Rot)
 SO_KIT_CATALOG_ENTRY_HEADER (side1Face)
 SO_KIT_CATALOG_ENTRY_HEADER (side1Hints)
 SO_KIT_CATALOG_ENTRY_HEADER (side1Rot)
 SO_KIT_CATALOG_ENTRY_HEADER (bottomSurface)
 SO_KIT_CATALOG_ENTRY_HEADER (bottomCoords)
 SO_KIT_CATALOG_ENTRY_HEADER (topSurface)
 SO_KIT_CATALOG_ENTRY_HEADER (topCoords)
 SO_KIT_CATALOG_ENTRY_HEADER (innerSurface)
 SO_KIT_CATALOG_ENTRY_HEADER (innerCoords)
 SO_KIT_CATALOG_ENTRY_HEADER (outerSurface)
 SO_KIT_CATALOG_ENTRY_HEADER (outerCoords)
 SO_KIT_CATALOG_ENTRY_HEADER (translation)
 SO_KIT_HEADER (IgSoPcon)


Detailed Description

IgSoPcon produces an OIV version of the GEANT3 PCON shape.

This particular version has five fields which control the shape which can be supplied or a set of arguments (following the GEANT3 version) can be given via the setPconPts method.

The representation is based on two NURB sufaces, one each for the inner and outer surfaces of revolution, plus two NURB surfaces for the end faces and two face sets for the side surfaces in case the full 2 PI of revolution is not covered.

Since TGS-based NURB surfaces average surface normals, the junctures between regions of different r/z slope seem blurry. This was deemed less troublesome than either including a separate surface for each region or replacing a NURB surface by some less adaptive surface function.

The MF field arguments are cached: to change the shape the field must be replaced.

Textures are not currently supported.

Author:
George Alverson, CMS/Northeastern University Software Group
Date:
April 2002 Original HEPVis version, June 1998

Definition at line 47 of file IgSoPcon.h.


Constructor & Destructor Documentation

IgSoPcon::IgSoPcon ( void   ) 

Definition at line 33 of file IgSoPcon.cc.

References center, FALSE, phiDelta, phiStart, IgSoShapeKit::setUpConnections(), TRUE, and vertices.

00034 {
00035     SO_KIT_CONSTRUCTOR (IgSoPcon);
00036     SO_KIT_ADD_FIELD (vertices, (SbVec3f (0,0,0)));
00037     SO_KIT_ADD_FIELD (center, (SbVec3f (0,0,0)));
00038     SO_KIT_ADD_FIELD (phiStart, (0));
00039     SO_KIT_ADD_FIELD (phiDelta, ( (2*M_PI)));
00040 
00041     SbVec3f defPcon [] = {
00042         SbVec3f (0.2F, 0.F, -1.F),
00043         SbVec3f (1.F,  0.F, -0.8F),
00044         SbVec3f (1.F,  0.F,  0.8F),
00045         SbVec3f (0.2F, 0.F,  1.F)
00046     };
00047     vertices.setValues (0, 4, defPcon);
00048 
00049     SO_KIT_ADD_CATALOG_ENTRY (translation,  SoTranslation,  FALSE, separator,\x0, TRUE);
00050     SO_KIT_ADD_CATALOG_ENTRY (outerCoords,  SoCoordinate4,  FALSE, separator,\x0, TRUE);
00051     SO_KIT_ADD_CATALOG_ENTRY (outerSurface, SoNurbsSurface, FALSE, separator,\x0, TRUE);
00052     SO_KIT_ADD_CATALOG_ENTRY (innerCoords,  SoCoordinate4,  FALSE, separator,\x0, TRUE);
00053     SO_KIT_ADD_CATALOG_ENTRY (innerSurface, SoNurbsSurface, FALSE, separator,\x0, TRUE);
00054     SO_KIT_ADD_CATALOG_ENTRY (topCoords,    SoCoordinate4,  FALSE, separator,\x0, TRUE);
00055     SO_KIT_ADD_CATALOG_ENTRY (topSurface,   SoNurbsSurface, FALSE, separator,\x0, TRUE);
00056     SO_KIT_ADD_CATALOG_ENTRY (bottomCoords, SoCoordinate4,  FALSE, separator,\x0, TRUE);
00057     SO_KIT_ADD_CATALOG_ENTRY (bottomSurface,SoNurbsSurface, FALSE, separator,\x0, TRUE);
00058     SO_KIT_ADD_CATALOG_ENTRY (side1Rot,     SoTransform,    TRUE, separator,\x0, TRUE);
00059     SO_KIT_ADD_CATALOG_ENTRY (side1Hints,   SoShapeHints,   TRUE, separator,\x0, TRUE);
00060     SO_KIT_ADD_CATALOG_ENTRY (side1Face,    SoFaceSet,      TRUE, separator,\x0, TRUE);
00061     SO_KIT_ADD_CATALOG_ENTRY (side2Rot,     SoTransform,    TRUE, separator,\x0, TRUE);
00062     SO_KIT_ADD_CATALOG_ENTRY (side2Hints,   SoShapeHints,   TRUE, separator,\x0, TRUE);
00063     SO_KIT_ADD_CATALOG_ENTRY (side2Face,    SoFaceSet,      TRUE, separator,\x0, TRUE);
00064     SO_KIT_INIT_INSTANCE ();
00065     setUpConnections (true, true);
00066 }


Member Function Documentation

void IgSoPcon::initClass ( void   )  [static]

Reimplemented from IgSoShapeKit.

Definition at line 30 of file IgSoPcon.cc.

Referenced by initNodes(), and initShapes().

00031 { SO_KIT_INIT_CLASS (IgSoPcon, IgSoShapeKit, "IgSoShapeKit"); }

void IgSoPcon::initialise ( const int  nzee,
const float  phi,
const float  delPhi,
const float *  zvals,
const float *  rmin,
const float *  rmax 
)

this initialisation method matches the old definition

GEANT3 style arguments nzee: number of z breaks phi: starting angle for the surfaces of revolution (same as startAngle field) delPhi: range of revolution (same as deltaAngle) zvals: array of the z locations of the breaks rmin: r value for the inner surface of revolution at the z points given in zvals rmax: same as rmin but for the outer surface.

Definition at line 325 of file IgSoPcon.cc.

References i, phiDelta, phiStart, python::multivaluedict::sort(), vec3fCompare(), vec3fCompareReverse(), and vertices.

Referenced by makePcon().

00327 {
00328     // Set up some typedefs so if we change the object we don't have
00329     // to change the code.
00330     typedef std::vector<SbVec3f> OrderedPair;
00331     typedef OrderedPair::iterator OrderedPairIt;
00332     using std::sort;
00333 
00334     assert (nzee > 1);
00335 
00336     phiStart = phi;
00337     if (fabs(delPhi) > 2*M_PI)
00338     {
00339         phiDelta = static_cast<float>(copysign(2*M_PI,delPhi));
00340     }
00341     else
00342     {
00343         phiDelta = delPhi;
00344     }
00345 
00346     // Sort the incoming points so that the path is counterclockwise
00347     // viewed along the y axis; start with upmost inner z and work
00348     // down, then up.
00349     OrderedPair pts (2*nzee+1);
00350     for (int i = 0; i < nzee; i++)
00351     {
00352         pts [i] = SbVec3f (rmin[i], 0, zvals[i]);
00353         pts [i+nzee] = SbVec3f (rmax[nzee-i-1], 0, zvals[nzee-i-1]);
00354     }
00355 
00356     // Order the points: first rmin, then rmax; then invert the rmax
00357     // set to get a loop.  This ordering doesn't seem to do what it is
00358     // supposed to, but everything has been jiggered to use the result
00359     // so we're not touching it for now.
00360 
00361     OrderedPairIt startDown = pts.begin ();
00362     OrderedPairIt endDown = startDown+nzee;
00363     OrderedPairIt startUp = endDown;
00364     OrderedPairIt endUp = startUp+nzee;
00365 
00366     sort (startDown, endDown, vec3fCompare);
00367     sort (startUp, endUp, vec3fCompareReverse);
00368 
00369     pts [2*nzee] = pts [0];
00370 
00371     // Stuff the points into the vertex list
00372     vertices.deleteValues (0);
00373     vertices.setValues (0, 2*nzee+1, &pts[0]);
00374 }

void IgSoPcon::makePcon ( const std::vector< float > &  zvals,
const std::vector< float > &  rmin,
const std::vector< float > &  rmax,
float  phiStart = 0,
float  phiDelta = 2*M_PI,
int  divisions = -1 
) [inline]

this initialisation method matches the equivalent one in IgSoRotSolid

Definition at line 92 of file IgSoPcon.h.

References initialise().

00095 { initialise (static_cast<int>( zvals.size() ), phiStart, phiDelta, &zvals[0], &rmin[0], &rmax[0]); }

void IgSoPcon::refresh ( void   )  [protected, virtual]

Reimplemented from IgSoShapeKit.

Definition at line 69 of file IgSoPcon.cc.

References center, funct::cos(), i, j, maxNurbAngle, NULL, phiDelta, phiStart, u_knot_vals, v_knot_vals, vertices, x, y, and z.

00070 {
00071     if (vertices.getNum () <= 1)
00072     {   
00073         // set parts
00074         setPart ("translation", NULL);
00075         setPart ("outerCoords", NULL);
00076         setPart ("outerSurface", NULL);
00077         setPart ("innerCoords", NULL);
00078         setPart ("innerSurface", NULL);
00079         setPart ("topCoords", NULL);
00080         setPart ("topSurface", NULL);
00081         setPart ("bottomCoords", NULL);
00082         setPart ("bottomSurface", NULL);
00083         return;
00084     }
00085     
00086     //  We generate a NURB surface to represent a surface of rotation
00087     //  The v dimension represents the rotation. The u represents the cross section.
00088     //
00089     //  Number of control points = DIM.
00090     //  DIM = 7, ORDER = 3 (quadratic) (minimum required: COIN needs more)
00091     //  Number of knots = DIM+ORDER=10.
00092     //  It requires 2*nz + 1 to describe a closed polygon:
00093     //  DIM = 2*nz+1, ORDER = 2 (linear)
00094     //  Number of knots = DIM+ORDER = 2*nz+1+2
00095 
00096     //  Outer & inner surfaces are completely equivalent in structure
00097 
00098     SoTranslation       *translation = new SoTranslation;
00099     SoCoordinate4       *outerCoords = new SoCoordinate4;
00100     SoNurbsSurface      *outerSurface = new SoNurbsSurface;
00101     SoCoordinate4       *innerCoords = new SoCoordinate4;
00102     SoNurbsSurface      *innerSurface = new SoNurbsSurface;
00103     SoCoordinate4       *topCoords = new SoCoordinate4;
00104     SoNurbsSurface      *topSurface = new SoNurbsSurface;
00105     SoCoordinate4       *bottomCoords = new SoCoordinate4;
00106     SoNurbsSurface      *bottomSurface = new SoNurbsSurface;
00107     SoTransform         *side1Rot = new SoTransform;
00108     SoShapeHints        *side1Hints = new SoShapeHints;
00109     SoFaceSet           *side1Face = new SoFaceSet;
00110     SoTransform         *side2Rot = new SoTransform;
00111     SoShapeHints        *side2Hints = new SoShapeHints;
00112     SoFaceSet           *side2Face = new SoFaceSet;
00113 
00114     float               phiStart = this->phiStart.getValue ();
00115     float               phiDelta = this->phiDelta.getValue ();
00116     int                 uDim = vertices.getNum () / 2;
00117 #ifdef TGS_VERSION
00118     static const float maxNurbAngle =  M_PI / 2.; // max angle to cover with 3 control points
00119 #else
00120     static const float maxNurbAngle =  M_PI / 8.; 
00121 #endif
00122     const int nurbSegs = std::max<int>(1,static_cast<int>(phiDelta/maxNurbAngle));
00123     const int   V_DIM = 2*nurbSegs+1; // the dimension of the surfaces around the direction of revolution
00124     static const int    V_ORDER = 3; // the order of the surface (quadratic)
00125     static const int    U_ORDER = 2; // the order of the surface along the z axis (linear)
00126 
00127     outerSurface->numUControlPoints = uDim;
00128     outerSurface->numVControlPoints = V_DIM;
00129     innerSurface->numUControlPoints = uDim;
00130     innerSurface->numVControlPoints = V_DIM;
00131 
00132     //  Generate the knot vectors
00133     //  For v, this should be {0,0,0,1,1,2,2,3,3,3}
00134     int iu, iv, ik, ik_count;
00135     std::vector<float> u_knot_vals(U_ORDER+uDim);
00136     std::vector<float> v_knot_vals(V_ORDER+V_DIM);
00137 
00138     //  Do the first point ORDER times  
00139     for (iv = 0, ik = 0, ik_count = 0; iv < V_ORDER; iv++, ik++)
00140         v_knot_vals[ik] = static_cast<float>(ik_count);
00141     ik_count++;
00142 
00143     //  All but the end point get ORDER-1
00144     for (iv = 0; iv < (V_DIM+V_ORDER-2*V_ORDER)/(V_ORDER-1); iv++, ik_count++)
00145         for (int j = 0; j < (V_ORDER-1); j++, ik++)
00146             v_knot_vals[ik] = static_cast<float>(ik_count);
00147 
00148     //  Now the last point, ORDER times
00149     for (iv = 0; iv < V_ORDER; iv++, ik++)
00150         v_knot_vals[ik] = static_cast<float>(ik_count);
00151 
00152     //  Now for u
00153     for (iu = 0, ik = 0, ik_count = 0; iu < U_ORDER; iu++, ik++) 
00154         u_knot_vals[ik] = static_cast<float>(ik_count);
00155     ik_count++;
00156 
00157     for (iu = 0; iu < (uDim+U_ORDER-2*U_ORDER)/(U_ORDER-1); iu++, ik_count++)
00158         for (int j = 0; j < (U_ORDER-1); j++, ik++)
00159             u_knot_vals[ik] = static_cast<float>(ik_count);
00160 
00161     for (iu = 0; iu < U_ORDER; iu++, ik++)
00162         u_knot_vals[ik] = static_cast<float>(ik_count);
00163 
00164     //  Should look like {0,0,1,2,3,...,n-1,n,n}
00165     outerSurface->uKnotVector.setValues (0,uDim+U_ORDER,&u_knot_vals[0]);
00166     outerSurface->vKnotVector.setValues (0,V_DIM+V_ORDER,&v_knot_vals[0]);
00167     innerSurface->uKnotVector.setValues (0,uDim+U_ORDER,&u_knot_vals[0]);
00168     innerSurface->vKnotVector.setValues (0,V_DIM+V_ORDER,&v_knot_vals[0]);
00169         
00170     /*  Set the number of co-ordinates... */
00171     outerCoords->point.setNum (uDim*V_DIM);
00172     innerCoords->point.setNum (uDim*V_DIM);
00173 
00174     /*  Generate the co-ordinates (Control Points) */
00175 
00176     /*  Set up the basic grid of control points */
00177     for (iv = 0; iv < V_DIM; iv++)
00178     {
00179         float           angleV = phiStart + phiDelta - iv * phiDelta/(2*nurbSegs);
00180         SbRotation      rotator (SbVec3f (0,0,1.F), angleV);
00181         float           weightV = iv % 2 == 1 ? fabs (cos (phiDelta/(2*nurbSegs))) : 1.0F;
00182 
00183         for (iu = 0; iu < uDim; iu++)
00184         {
00185             int         i = iu + iv*uDim;
00186             float       x;
00187             float       y;
00188             float       z;
00189             SbVec3f     cpt;
00190 
00191             // get the order this way to set exterior of surf
00192             vertices [iu].getValue (x, y, z);
00193             cpt = SbVec3f ((x / weightV), y, z);
00194             rotator.multVec (cpt, cpt);
00195             cpt *= (weightV);
00196             innerCoords->point.set1Value (i, cpt[0], cpt[1], cpt[2], (weightV));
00197 
00198             vertices [iu+uDim].getValue (x, y, z);
00199             cpt = SbVec3f ((x / weightV), y, z);
00200             rotator.multVec (cpt, cpt);
00201             cpt *= (weightV);
00202             outerCoords->point.set1Value (i, cpt[0], cpt[1], cpt[2], (weightV));
00203         }
00204     }
00205 
00206     //  We instituted an additional surface at the top and bottom to try and
00207     //  minimize the blurring at the intersections when the faces are at large
00208     //  angles wrt one another when using the G5G (TGS OIV) NURB libraries.
00209     //  Coin apparently doesn't have this problem.
00210 
00211     //  now for end plates; again u is linear (this time in r) and v
00212     //  is quadratic (the rotation angle)
00213     //  vend should look like vend [10] = { 0, 0, 0, 1, 1, 2, 2, 3, 3, 3 };
00214 
00215     float       uend [4] = { 0, 0, 1, 1 };
00216 
00217     bottomCoords->point.setNum (12);
00218     topCoords->point.setNum (12);
00219     bottomSurface->numUControlPoints = 2;
00220     bottomSurface->numVControlPoints = V_DIM;
00221     bottomSurface->uKnotVector.setValues (0, 4, &uend[0]);
00222     bottomSurface->vKnotVector.setValues (0, V_DIM+V_ORDER,&v_knot_vals[0]);
00223     topSurface->numUControlPoints = 2;
00224     topSurface->numVControlPoints = V_DIM;
00225     topSurface->uKnotVector.setValues (0, 4, &uend[0]);
00226     topSurface->vKnotVector.setValues (0, V_DIM+V_ORDER, &v_knot_vals[0]);
00227 
00228     int iu_indices [4] = { uDim-1, uDim, 2*uDim-1, 0}; // flip top end to get orientation
00229     for (iv = 0; iv < V_DIM; iv++)
00230     {
00231         float           angleV = phiStart + phiDelta - iv * phiDelta/(2*nurbSegs);
00232         SbRotation      rotator (SbVec3f (0,0,1.F), (angleV));
00233         float           weightV = iv % 2 == 1 ? fabs (cos (phiDelta/(2*nurbSegs))) : 1.0F;
00234 
00235         for (iu = 0; iu < 2; iu++)
00236         {  
00237             int         i = iu + iv*2;
00238             float       x;
00239             float       y;
00240             float       z;
00241             SbVec3f     cpt;
00242 
00243             vertices [iu_indices [iu]].getValue (x, y, z);
00244             cpt = SbVec3f ((x / weightV), (y / weightV), z);
00245             rotator.multVec (cpt, cpt);
00246             cpt *= (weightV);
00247             bottomCoords->point.set1Value (i, cpt[0], cpt[1], cpt[2], (weightV));
00248 
00249             vertices [iu_indices [iu+2]].getValue (x, y, z);
00250             cpt = SbVec3f ((x / weightV), (y / weightV), z);
00251             rotator.multVec (cpt, cpt);
00252             cpt *= (weightV);
00253             topCoords->point.set1Value (i, cpt[0], cpt[1], cpt[2], (weightV));
00254         }
00255     }
00256 
00257     translation->translation = center;
00258 
00259     // set parts
00260     setPart ("translation",     translation);
00261     setPart ("outerCoords",     outerCoords);
00262     setPart ("outerSurface",    outerSurface);
00263     setPart ("innerCoords",     innerCoords);
00264     setPart ("innerSurface",    innerSurface);
00265     setPart ("topCoords",       topCoords);
00266     setPart ("topSurface",      topSurface);
00267     setPart ("bottomCoords",    bottomCoords);
00268     setPart ("bottomSurface",   bottomSurface);
00269 
00270     //  Now check to see if we need cut faces
00271     if (! (fabs (phiDelta - 2*M_PI) < 0.0001 || phiDelta < 0.0001))
00272     {
00273         SoVertexProperty *sideVtx = new SoVertexProperty;
00274         sideVtx->vertex = vertices;
00275         side1Face->numVertices = 2*uDim;
00276         side2Face->numVertices = 2*uDim;
00277         side1Face->vertexProperty = sideVtx;
00278         side2Face->vertexProperty = sideVtx;
00279         side1Rot->rotation.setValue (SbVec3f (0.,0.,1.), phiStart);
00280         side2Rot->rotation.setValue (SbVec3f (0.,0.,1.), phiDelta);
00281         side1Hints->vertexOrdering = SoShapeHints::CLOCKWISE;
00282         side1Hints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
00283         side1Hints->faceType = SoShapeHints::UNKNOWN_FACE_TYPE;
00284         side2Hints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
00285         side2Hints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
00286         side2Hints->faceType = SoShapeHints::UNKNOWN_FACE_TYPE;
00287         setPart ("side1Rot",    side1Rot);
00288         setPart ("side1Hints",  side1Hints);
00289         setPart ("side1Face",   side1Face);
00290         setPart ("side2Rot",    side2Rot);
00291         setPart ("side2Hints",  side2Hints);
00292         setPart ("side2Face",   side2Face);
00293     }
00294 
00295 }

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( side2Face   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( side2Hints   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( side2Rot   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( side1Face   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( side1Hints   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( side1Rot   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( bottomSurface   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( bottomCoords   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( topSurface   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( topCoords   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( innerSurface   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( innerCoords   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( outerSurface   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( outerCoords   )  [private]

IgSoPcon::SO_KIT_CATALOG_ENTRY_HEADER ( translation   )  [private]

IgSoPcon::SO_KIT_HEADER ( IgSoPcon   )  [private]


Member Data Documentation

SoSFVec3f IgSoPcon::center

Definition at line 71 of file IgSoPcon.h.

Referenced by IgSoPcon(), and refresh().

SoSFFloat IgSoPcon::phiDelta

Definition at line 73 of file IgSoPcon.h.

Referenced by IgSoPcon(), initialise(), and refresh().

SoSFFloat IgSoPcon::phiStart

Definition at line 72 of file IgSoPcon.h.

Referenced by IgSoPcon(), initialise(), and refresh().

SoMFVec3f IgSoPcon::vertices

Definition at line 70 of file IgSoPcon.h.

Referenced by IgSoPcon(), initialise(), and refresh().


The documentation for this class was generated from the following files:
Generated on Tue Jun 9 18:25:43 2009 for CMSSW by  doxygen 1.5.4