#include <Iguana/Inventor/interface/IgSoPcon.h>
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) |
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.
Definition at line 47 of file IgSoPcon.h.
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 }
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]); }
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] |
SoSFVec3f IgSoPcon::center |
SoSFFloat IgSoPcon::phiDelta |
SoSFFloat IgSoPcon::phiStart |
SoMFVec3f IgSoPcon::vertices |