CMS 3D CMS Logo

IgSoRotSolid.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "Iguana/Inventor/interface/IgSoRotSolid.h"
00004 #include <Inventor/nodes/SoIndexedFaceSet.h>
00005 #include <Inventor/nodes/SoIndexedLineSet.h>
00006 #include <Inventor/nodes/SoVertexProperty.h>
00007 #include <Inventor/nodes/SoShapeHints.h>
00008 #include <Inventor/SbLinear.h>
00009 
00010 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00011 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00012 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00013 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00014 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00015 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00016 
00017 SO_KIT_SOURCE (IgSoRotSolid);
00018 
00019 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00020 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00021 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00022 
00023 void
00024 IgSoRotSolid::initClass (void)
00025 { SO_KIT_INIT_CLASS (IgSoRotSolid, IgSoShapeKit, "IgSoShapeKit"); }
00026 
00027 IgSoRotSolid::IgSoRotSolid (void)
00028 {
00029     SO_KIT_CONSTRUCTOR (IgSoRotSolid);
00030     SO_KIT_ADD_FIELD (phiStart,         (0.0));
00031     SO_KIT_ADD_FIELD (phiDelta,         (2 * M_PI));
00032     SO_KIT_ADD_FIELD (polygon,          (0, 0));
00033     SO_KIT_ADD_FIELD (divisions,        (4));
00034     SO_KIT_ADD_FIELD (smooth,           (TRUE));
00035     SO_KIT_ADD_FIELD (showLines,        (FALSE));
00036     SO_KIT_ADD_CATALOG_ENTRY (hints, SoShapeHints, FALSE, separator,\x0, TRUE);
00037     SO_KIT_ADD_CATALOG_ENTRY (faces, SoIndexedFaceSet, FALSE, separator,\x0, TRUE);
00038     SO_KIT_ADD_CATALOG_ENTRY (lines, SoIndexedLineSet, FALSE, separator,\x0, TRUE);
00039     
00040     SO_KIT_INIT_INSTANCE ();
00041     setUpConnections (true, true);
00042 
00043     SbVec2f defaultShape [] =
00044         {
00045             SbVec2f (0, 0), 
00046             SbVec2f (1, 1), 
00047             SbVec2f (1, 0)
00048         }; 
00049 
00050     polygon.setValues (0, 3, defaultShape);
00051 }
00052 
00053 void 
00054 IgSoRotSolid::cleanParts (void)
00055 {
00056     setPart ("hints", NULL);
00057     setPart ("faces", NULL);
00058     setPart ("lines", NULL);
00059 }
00060 
00061 void
00062 IgSoRotSolid::refresh (void)
00063 {
00064     // If less than 3 points in the polygon being rotated, we have an
00065     // unclosed surface, therefore we just quit.
00066     if (polygon.getNum () < 3)
00067     {
00068         cleanParts ();
00069         return;
00070     }
00071 
00072     SoShapeHints        *hints = new SoShapeHints;
00073     SoIndexedFaceSet    *faces = new SoIndexedFaceSet;
00074     SoVertexProperty    *vtx = new SoVertexProperty;
00075 
00076     int                 divisions = this->divisions.getValue ();
00077     float               phiStart = this->phiStart.getValue ();
00078     float               phiDelta = this->phiDelta.getValue ();
00079     bool                smooth = this->smooth.getValue ();
00080     int                 numEdges = polygon.getNum ();
00081 
00082     bool                edgeVertical = false;
00083     bool                closedShape = true;
00084 
00085     // If the angle is less than 2PI, then the shape is not closed.
00086     if (fabs (phiDelta) < 2 * M_PI) closedShape = false;
00087 
00088     if (smooth) divisions = (int) (phiDelta / (M_PI / 36.0)) + 2;
00089     float delta = phiDelta / divisions;
00090 
00091     // Get the cross-section
00092     std::vector<SbVec3f> crossSection;
00093 
00094     for (int i = 0; i < numEdges; i++)
00095     {
00096         crossSection.push_back (SbVec3f (polygon [i][0], 0, polygon [i][1]));
00097     }
00098     crossSection.push_back (SbVec3f (polygon [0][0], 0, polygon [0][1]));
00099     
00100     int totalPoints = 0;
00101     
00102     std::vector<SbVec3f> vertexData;
00103     std::vector<int> indices;
00104     std::vector<int> lineIndices;
00105     std::vector<SbVec3f>::iterator it = crossSection.begin ();
00106     for (int i = 0; i < numEdges; i++, it++)
00107     {
00108         int nLeftPoints = 0;
00109         int nRightPoints = 0;
00110         
00111         SbVec3f leftPoint = *it;
00112         SbVec3f rightPoint = *(it + 1);
00113         
00114         (leftPoint [2] == rightPoint [2]) ? edgeVertical = true : edgeVertical = false;
00115 
00116         // Take one edge and rotate it.
00117         //
00118         if (leftPoint [0] != 0) // if left point is not on Z
00119         {
00120             // rotate it
00121             for (float phi = phiStart; phi < phiStart + phiDelta; phi += delta) // collect the rest
00122             {
00123                 SbMatrix transform;
00124                 transform.setRotate (SbRotation (SbVec3f (0, 0, 1), phi));
00125                 SbVec3f dst;
00126                 transform.multVecMatrix (leftPoint, dst);
00127                 vertexData.push_back (dst);
00128                 lineIndices.push_back (totalPoints);
00129                 totalPoints++;
00130                 nLeftPoints++;
00131             }
00132 
00133             // Repeate the last point to avoid rounding
00134             SbMatrix transform;
00135             transform.setRotate (SbRotation (SbVec3f (0, 0, 1), phiStart + phiDelta));
00136             SbVec3f dst;
00137             transform.multVecMatrix (leftPoint, dst);
00138             vertexData.push_back (dst);
00139             lineIndices.push_back (totalPoints);
00140             totalPoints++;
00141             nLeftPoints++;
00142             lineIndices.push_back (SO_END_LINE_INDEX);
00143         } else 
00144         {
00145             if (edgeVertical) 
00146             { 
00147                 if (!closedShape) 
00148                 {
00149                     vertexData.push_back (leftPoint);           
00150                     totalPoints++;
00151                     nLeftPoints++;
00152                 }
00153             } else 
00154             {
00155                 vertexData.push_back (leftPoint);
00156                 totalPoints++;
00157                 nLeftPoints++;          
00158             }
00159         }
00160 
00161         if (rightPoint [0] != 0) // if right point is not on Z
00162         {
00163             // rotate it
00164             for (float phi = phiStart; phi < phiStart + phiDelta; phi += delta) // collect the rest
00165             {
00166                 SbMatrix transform;
00167                 transform.setRotate (SbRotation (SbVec3f (0, 0, 1), phi));
00168                 SbVec3f dst;
00169                 transform.multVecMatrix (rightPoint, dst);
00170                 vertexData.push_back (dst);
00171                 lineIndices.push_back (totalPoints);
00172                 totalPoints++;
00173                 nRightPoints++;
00174             }
00175 
00176             // Repeate the last point to avoid rounding
00177             SbMatrix transform;
00178             transform.setRotate (SbRotation (SbVec3f (0, 0, 1), phiStart + phiDelta));
00179             SbVec3f dst;
00180             transform.multVecMatrix (rightPoint, dst);
00181             vertexData.push_back (dst);
00182             lineIndices.push_back (totalPoints);    
00183             totalPoints++;
00184             nRightPoints++;
00185             lineIndices.push_back (SO_END_LINE_INDEX);
00186         } else
00187         {
00188             if (edgeVertical)
00189             {
00190                 if (!closedShape)
00191                 {
00192                     vertexData.push_back (rightPoint);
00193                     totalPoints++;
00194                     nRightPoints++;
00195                 }
00196             } else 
00197             {       
00198                 vertexData.push_back (rightPoint);
00199                 totalPoints++;
00200                 nRightPoints++;
00201             }
00202         }
00203 
00204         int edgePoints = nRightPoints + nLeftPoints;
00205         int startPoint = totalPoints - edgePoints;
00206         int nEdgePoints = 0;
00207         (nLeftPoints >= nRightPoints) ? nEdgePoints = nLeftPoints : nEdgePoints = nRightPoints;
00208 
00209         for (int npe = 0; npe < nEdgePoints - 1; npe++)
00210         {
00211             switch (nLeftPoints)
00212             {
00213             case 0:
00214                 break;
00215             case 1:
00216                 indices.push_back (startPoint);
00217                 break;
00218             default:
00219                 if (nRightPoints != 0) 
00220                 {
00221                     indices.push_back (startPoint + npe);
00222                     indices.push_back (startPoint + npe + 1);
00223                 } else
00224                 {
00225                     indices.push_back (startPoint + npe);
00226                 }
00227                 break;
00228             }
00229             
00230             switch (nRightPoints)
00231             {
00232             case 0:
00233                 break;
00234             case 1:
00235                 indices.push_back (totalPoints);
00236                 indices.push_back (SO_END_FACE_INDEX);
00237                 break;
00238             default:
00239                 if (nLeftPoints != 0) 
00240                 {
00241                     indices.push_back (totalPoints - nRightPoints + npe + 1);
00242                     indices.push_back (totalPoints - nRightPoints + npe);
00243                     indices.push_back (SO_END_FACE_INDEX);
00244                     
00245                     if (!smooth) 
00246                     {
00247                         if (nLeftPoints == 1) 
00248                             lineIndices.push_back (startPoint);
00249                         else
00250                             lineIndices.push_back (startPoint + npe);
00251                         lineIndices.push_back (totalPoints - nRightPoints + npe);
00252                         lineIndices.push_back (SO_END_LINE_INDEX);
00253                     }
00254                 } else
00255                 {
00256                     indices.push_back (totalPoints - npe - 1);
00257                 }
00258                 break;
00259             }
00260         }
00261         if (!indices.empty () && (indices.back () != SO_END_FACE_INDEX))
00262             indices.push_back (SO_END_FACE_INDEX);          
00263     }
00264 
00265     if (!closedShape)
00266     {
00267         std::vector<SbVec3f> edgeVertexData;
00268         std::vector<int> edgeIndices;
00269         
00270         for (std::vector<SbVec3f>::iterator it = crossSection.begin (); it != crossSection.end (); it++)
00271         {
00272             SbMatrix transform;
00273             transform.setRotate (SbRotation (SbVec3f (0, 0, 1), phiStart));
00274             SbVec3f src = *it;
00275             SbVec3f dst;
00276             transform.multVecMatrix (src, dst);
00277             vertexData.push_back (dst);
00278             indices.push_back (totalPoints);
00279             totalPoints++;
00280         }
00281         indices.push_back (SO_END_FACE_INDEX); // end the shape
00282 
00283         float phi = phiDelta + phiStart;
00284         for (std::vector<SbVec3f>::reverse_iterator it = crossSection.rbegin (); it != crossSection.rend (); it++)
00285         {
00286             SbMatrix transform;
00287             transform.setRotate (SbRotation (SbVec3f (0, 0, 1), phi));
00288             SbVec3f src = *it;
00289             SbVec3f dst;
00290             transform.multVecMatrix (src, dst);
00291             vertexData.push_back (dst);
00292             indices.push_back (totalPoints);
00293             totalPoints++;
00294         }
00295         indices.push_back (SO_END_FACE_INDEX); // end the shape
00296     }
00297 
00298     vtx->vertex.setValues (0, vertexData.size (), &vertexData [0]);
00299     faces->vertexProperty = vtx;
00300     faces->coordIndex.setValues (0, indices.size (), &indices [0]);
00301 
00302     // Set the hints for the endcaps
00303     hints->vertexOrdering       = SoShapeHints::COUNTERCLOCKWISE;   
00304     hints->shapeType            = SoShapeHints::SOLID;
00305     if (smooth) 
00306         hints->creaseAngle      = 10.0;
00307 
00308     setPart ("hints", hints);
00309     setPart ("faces", faces);
00310 
00311     if (showLines.getValue () == true) 
00312     {
00313         SoIndexedLineSet        *lines = new SoIndexedLineSet;
00314         lines->coordIndex.setValues (0, lineIndices.size (), &lineIndices [0]);
00315         lines->vertexProperty = vtx;
00316         setPart ("lines", lines);
00317     }
00318     else
00319     {
00320         setPart ("lines", NULL);
00321     }
00322 }
00323 
00324 void
00325 IgSoRotSolid::makePgon (const std::vector<float> &zvals,
00326                         const std::vector<float> &rmin,
00327                         const std::vector<float> &rmax,
00328                         float phiStart,
00329                         float phiDelta,
00330                         int divisions)
00331 {
00332     this->divisions.setValue (divisions);
00333     this->phiStart.setValue (phiStart);
00334     this->phiDelta.setValue (phiDelta);
00335     if (divisions < 0)
00336         this->smooth = TRUE;
00337     else
00338         this->smooth = FALSE;
00339 
00340     std::vector<SbVec2f> contour (2 * zvals.size ());
00341     int k = 0;
00342 
00343     for (int i = 0; i < (int) zvals.size (); i++)
00344     {
00345         contour [k][0] = rmax [i];
00346         contour [k][1] = zvals [i];
00347         k++;
00348     }
00349 
00350     for (int i = (int) zvals.size () - 1; i >= 0 ; i--)
00351     {
00352         contour [k][0] = rmin [i];
00353         contour [k][1] = zvals [i];
00354         k++;
00355     }
00356     this->polygon.setValues (0, 2 * zvals.size (), &contour [0]);
00357 }
00358 
00359 void
00360 IgSoRotSolid::makePcon (const std::vector<float> &zvals,
00361                         const std::vector<float> &rmin,
00362                         const std::vector<float> &rmax,
00363                         float phiStart,
00364                         float phiDelta,
00365                         int divisions)
00366 {
00367     makePgon (zvals, rmin, rmax, phiStart, phiDelta, divisions);
00368 }
00369 
00370 void
00371 IgSoRotSolid::makeCons (float rmin1,
00372                         float rmax1,
00373                         float rmin2,
00374                         float rmax2,
00375                         float dz,
00376                         float phiStart,
00377                         float phiDelta,
00378                         int divisions)
00379 {
00380     std::vector<float> zvals (2);
00381     std::vector<float> rminTemp (2);
00382     std::vector<float> rmaxTemp (2);
00383     
00384     zvals [0] = -dz;
00385     zvals [1] = dz;
00386     rminTemp [0] = rmin1;
00387     rminTemp [1] = rmin2;
00388     rmaxTemp [0] = rmax1;
00389     rmaxTemp [1] = rmax2;
00390 
00391     makePcon (zvals, rminTemp, rmaxTemp, phiStart, phiDelta, divisions);
00392 }
00393 
00394 void
00395 IgSoRotSolid::makeTubs (float rmin,
00396                         float rmax,
00397                         float dz,
00398                         float phiStart,
00399                         float phiDelta,
00400                         int divisions)
00401 {
00402     std::vector<float> zvals (2);
00403     std::vector<float> rminTemp (2);
00404     std::vector<float> rmaxTemp (2);
00405     
00406     zvals [0] = -dz;
00407     zvals [1] = dz;
00408     rminTemp [0] = rmin;
00409     rminTemp [1] = rmin;
00410     rmaxTemp [0] = rmax;
00411     rmaxTemp [1] = rmax;
00412     
00413     makePcon (zvals, rminTemp, rmaxTemp, phiStart, phiDelta, divisions);    
00414 }

Generated on Tue Jun 9 17:38:47 2009 for CMSSW by  doxygen 1.5.4