Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

osg::ExtrusionSurface Class Reference

Encapsulates the data of an X3D extrusion surface Not intended to be directly used. Use construction functions makeExtrusion and makeExtrusionGeo instead.

#include <OSGExtrusionGeometry.h>

List of all members.

Public Member Functions

Constructors
ExtrusionSurface (const std::vector< Pnt2f > &crossSection, const std::vector< Quaternion > &orientation, const std::vector< Vec2f > &scale, const std::vector< Pnt3f > &spine, Real32 creaseAngle=0.f, bool beginCap=true, bool endCap=true, bool ccw=true, bool convex=true, bool buildNormal=true, bool buildTexCoord=true)
 Constructor initializing an extrusion surface.
Access
*GeometryPtr createGeometry (UInt32 nSubDivisions)
 Creates a multi-indexed Geometry representing the extrusion surface Invoked by the construction function makeExtrusionGeo and makeExtrusion.

Private Types

typedef std::vector< Pnt3f
>::const_iterator 
Pnt3fConstIt
typedef std::vector< Matrix
>::const_iterator 
MatrixConstIt
typedef std::pair< Pnt3fConstIt,
Pnt3fConstIt
Pnt3fConstItPair
typedef std::vector< std::vector<
Vertex > > 
VertexGrid
typedef std::map< Pnt3f, UInt32,
vecless< Pnt3f > > 
PositionMap
typedef std::map< Vec3f, UInt32,
vecless< Vec3f > > 
NormalMap
typedef std::map< Vec2f, UInt32,
vecless< Vec2f > > 
TexCoordMap

Private Member Functions

 ExtrusionSurface (const ExtrusionSurface &source)
 prohibit default function (move to 'public' if needed)
void operator= (const ExtrusionSurface &source)
 prohibit default function (move to 'public' if needed)
void calcXAxes (void)
void calcYAxes (void)
void calcZAxes (void)
void calcTransforms (void)
void calcSweepSurfacePositions (void)
void calcSweepSurfaceFaceNormals (void)
void calcSweepSurfaceTexCoords (void)
void determineTopology (void)
void initGrid (void)
bool verifyInput (void)
void refineCrossSection (UInt32 nTimes)
void refineOrientation (UInt32 nTimes)
void refineScale (UInt32 nTimes)
void refineSpine (UInt32 nTimes)
void storeConvexCap (UInt32 spineIndex, bool invertNormal, GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr)
void storeSweepSurfaceWithNormals (GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr)
void storeSweepSurfaceWithoutNormals (GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr)
void storeMaps (GeoPositions3fPtr positionsPtr, GeoNormals3fPtr normalsPtr, GeoTexCoords2fPtr texCoordsPtr)
void storeVertex (const Vertex &vertex, GeoIndicesUI32Ptr indicesPtr)
void storePrimitive (GLenum type, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr)
template<typename PType>
UInt32 store (PType property, std::map< PType, UInt32, vecless< PType > > &propertyIndexMap)
template<typename PType>
void store (const PType property, std::map< PType, UInt32, vecless< PType > > &propertyIndexMap, GeoIndicesUI32Ptr indicesPtr)
Pnt3fConstItPair getPrevAndNextIt (const Pnt3fConstIt &pIt)
Vec3f calcNonUnitYAxis (const Pnt3fConstIt &pIt)
Vec3f calcNonUnitZAxis (const Pnt3fConstIt &pIt)
Vec3f calcXAxis (const MatrixConstIt &pIt)
Vec3f calcTriangleFaceNormal (const Pnt3f &a, const Pnt3f &b, const Pnt3f &c)
Vec3f calcQuadFaceNormal (const Pnt3f &a, const Pnt3f &b, const Pnt3f &c, const Pnt3f &d)
void calcVertexNormal (Vertex *vertexPtr, UInt32 faceIndex)
bool isLeft (const Pnt2f &a, const Pnt2f &b)
Real32 computeMinYAbs (const std::vector< Pnt2f > &contour, Real32 alpha)
Real32 calcBetterRotationAngle (const std::vector< Pnt2f > &contour, UInt32 nAngles)
bool calcOptimizedContour (const std::vector< Pnt2f > &contour, const Pnt2f &point, std::vector< Pnt2f > *optimizedContour)
Int32 calcWindingNumber (const std::vector< Pnt2f > &contour, const Pnt2f &point)
void storeFaceNormalGeo (GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr)
void storeVertexNormalGeo (GeoIndicesUI32Ptr indicesPtr, GeoPLengthsUI32Ptr lensPtr, GeoPTypesUI8Ptr typesPtr)
Constructors
ExtrusionSurface (void)
 prohibit default function (move to 'public' if needed)

Private Attributes

std::vector< Pnt2f_crossSection
std::vector< Quaternion_orientation
std::vector< Vec2f_scale
std::vector< Pnt3f_spine
Real32 _creaseAngle
bool _beginCap
bool _endCap
bool _ccw
bool _convex
bool _crossSectionClosed
bool _spineClosed
bool _spineCollinear
bool _revolutionSurface
bool _createNormals
bool _createTexCoords
std::vector< Matrix_transform
VertexGrid _grid
PositionMap _posMap
NormalMap _normalMap
TexCoordMap _texCoordMap
UInt32 _vertexCount
UInt32 _totalVertexCount
UInt32 _primitiveCount

Classes

struct  vecless
struct  Vertex


Detailed Description

Definition at line 140 of file OSGExtrusionGeometry.h.


Member Typedef Documentation

typedef std::vector<Pnt3f>::const_iterator osg::ExtrusionSurface::Pnt3fConstIt [private]
 

Definition at line 249 of file OSGExtrusionGeometry.h.

typedef std::vector<Matrix>::const_iterator osg::ExtrusionSurface::MatrixConstIt [private]
 

Definition at line 250 of file OSGExtrusionGeometry.h.

typedef std::pair<Pnt3fConstIt, Pnt3fConstIt> osg::ExtrusionSurface::Pnt3fConstItPair [private]
 

Definition at line 251 of file OSGExtrusionGeometry.h.

typedef std::vector< std::vector< Vertex > > osg::ExtrusionSurface::VertexGrid [private]
 

Definition at line 253 of file OSGExtrusionGeometry.h.

typedef std::map<Pnt3f, UInt32, vecless<Pnt3f> > osg::ExtrusionSurface::PositionMap [private]
 

Definition at line 255 of file OSGExtrusionGeometry.h.

typedef std::map<Vec3f, UInt32, vecless<Vec3f> > osg::ExtrusionSurface::NormalMap [private]
 

Definition at line 256 of file OSGExtrusionGeometry.h.

typedef std::map<Vec2f, UInt32, vecless<Vec2f> > osg::ExtrusionSurface::TexCoordMap [private]
 

Definition at line 257 of file OSGExtrusionGeometry.h.


Constructor & Destructor Documentation

ExtrusionSurface::ExtrusionSurface const std::vector< Pnt2f > &  crossSection,
const std::vector< Quaternion > &  orientation,
const std::vector< Vec2f > &  scale,
const std::vector< Pnt3f > &  spine,
Real32  creaseAngle = 0.f,
bool  beginCap = true,
bool  endCap = true,
bool  ccw = true,
bool  convex = true,
bool  buildNormal = true,
bool  buildTexCoord = true
 

Parameters:
crossSection The cross-section of the sweep surface
orientation The orientation rotating the cross-section out of the XZ-plane
scale The scale values scaling the cross-section
spine The spine curve along which the cross-section is extruded
creaseAngle Determines when normals are smoothed between adjacent quads
beginCap Determines whether a begin cap is to created
endCap Determines whether an end cap is to be created
ccw Determines the ordering of the primitive vertices with respect to the generated normals
convex Determines whether the cross-section is convex
buildNormal Determines whether normals are calculated
buildTexCoord Determines whether texture coordinates are created

Definition at line 125 of file OSGExtrusionGeometry.cpp.

References _crossSection, _orientation, _scale, _spine, osg::DEF_CROSS_SECTION, osg::DEF_N_CROSS_SECTION_POINTS, osg::DEF_N_ORIENTATION_PARAMS, osg::DEF_N_SCALE_PARAMS, osg::DEF_N_SPINE_POINTS, osg::DEF_ORIENTATION, osg::DEF_SCALE, osg::DEF_SPINE, and FDEBUG.

00135                                                        :
00136 
00137     _creaseAngle(creaseAngle),
00138     _beginCap(beginCap),
00139     _endCap(endCap),
00140     _ccw(ccw),
00141     _convex(convex),
00142     _createNormals(buildNormal),
00143     _createTexCoords(buildTexCoord),
00144     _primitiveCount(0),
00145     _vertexCount(0),
00146     _totalVertexCount(0)
00147 {
00148     // initialize cross section
00149     if(!crossSection.empty()) 
00150     {
00151         // copy argument
00152         _crossSection.assign(crossSection.begin(), crossSection.end());
00153     }
00154     else
00155     {
00156         // copy default
00157         FDEBUG(("OSGExtrusion: Empty cross section. Using default.\n"));
00158         for(UInt32 i = 0; i < DEF_N_CROSS_SECTION_POINTS; i++)
00159             _crossSection.push_back(Pnt2f(DEF_CROSS_SECTION[i]));
00160     }
00161 
00162     // initialize orientations
00163     if(!orientation.empty())
00164     {
00165         // copy argument
00166         _orientation.assign(orientation.begin(), orientation.end());
00167     }
00168     else
00169     {
00170         // copy default
00171         FDEBUG(("OSGExtrusion: Empty orientation. Using default.\n"));
00172         for(UInt32 i = 0; i < DEF_N_ORIENTATION_PARAMS; i++)
00173             _orientation.push_back(Quaternion(Vec3f(DEF_ORIENTATION[i]),
00174                                               DEF_ORIENTATION[i][3]));
00175     }
00176     
00177     // initialize scale parameters
00178     if(!scale.empty())
00179     {
00180         // copy argument
00181         _scale.assign(scale.begin(), scale.end());
00182     }
00183     else
00184     {
00185         // copy default
00186         FDEBUG(("OSGExtrusion: Empty scale parameter. Using default.\n"));
00187         for(UInt32 i = 0; i < DEF_N_SCALE_PARAMS; i++)
00188             _scale.push_back(Vec2f(DEF_SCALE[i]));
00189     }
00190 
00191 
00192     // initialize spine
00193     if(!spine.empty())
00194     {
00195         // copy argument
00196         _spine.assign(spine.begin(), spine.end());
00197     }
00198     else
00199     {
00200         // copy default
00201         FDEBUG(("OSGExtrusion: Empty spine. Using default.\n"));
00202         for(UInt32 i = 0; i < DEF_N_SPINE_POINTS; i++)
00203             _spine.push_back(Pnt3f(DEF_SPINE[i]));
00204     }
00205 }

* osg::ExtrusionSurface::ExtrusionSurface void   )  [private]
 

osg::ExtrusionSurface::ExtrusionSurface const ExtrusionSurface source  )  [private]
 


Member Function Documentation

GeometryPtr ExtrusionSurface::createGeometry UInt32  nSubDivisions  ) 
 

Parameters:
nSubDivisions The number of subdivisions to apply
Returns:
A pointer to a newly created geometry containing the surface

Definition at line 1477 of file OSGExtrusionGeometry.cpp.

References _beginCap, _convex, _createNormals, _createTexCoords, _endCap, _normalMap, _orientation, _posMap, _primitiveCount, _spine, _texCoordMap, _totalVertexCount, osg::beginEditCP(), calcSweepSurfacePositions(), calcSweepSurfaceTexCoords(), osg::GeometryBase::create(), osg::GeoProperty< GeoPropertyDesc >::create(), determineTopology(), osg::endEditCP(), FDEBUG, FFATAL, FINFO, FWARNING, osg::GeoProperty< GeoPropertyDesc >::GeoPropDataFieldMask, osg::GeometryBase::IndexMappingFieldMask, osg::GeometryBase::IndicesFieldMask, initGrid(), osg::GeometryBase::LengthsFieldMask, osg::Geometry::MapNormal, osg::Geometry::MapPosition, osg::Geometry::MapTexCoords, osg::GeometryBase::NormalsFieldMask, osg::NullFC, osg::GeometryBase::PositionsFieldMask, refineCrossSection(), refineScale(), refineSpine(), SINFO, storeConvexCap(), storeFaceNormalGeo(), storeMaps(), storeSweepSurfaceWithNormals(), storeSweepSurfaceWithoutNormals(), storeVertexNormalGeo(), osg::GeometryBase::TexCoordsFieldMask, osg::GeometryBase::TypesFieldMask, and verifyInput().

Referenced by osg::makeExtrusionGeo().

01478 {
01479     // do some sanity checks on and determines the topology
01480     // of the _spine and _crossSection member fields
01481     if(!verifyInput())
01482     {
01483         FWARNING(("OSGExtrusion:createGeometry: Invalid input. Returning NullFC\n"));
01484         return NullFC;
01485     }
01486 
01487     // initialize topology flags (i.e spine/_crossSection closure)
01488     determineTopology();
01489     
01490     // optionally subdivide input data
01491     if(nSubdivs > 0)
01492     {
01493         refineCrossSection(nSubdivs);
01494 
01495         if(_orientation.size() == 1)
01496         {
01497             refineSpine(nSubdivs);
01498             refineScale(nSubdivs);
01499         }
01500         else // more than 1 orientation
01501         {
01502             // It'd be necessary to refine the orientations in order to get
01503             // a consistent result, but this is not implemented yet.
01504             FINFO(("OSGExtrusion:createGeometry: Too many orientations. Not refining along spine\n"));
01505         }
01506     }
01507 
01508     // allocate vertex grid structure
01509     initGrid();
01510     calcSweepSurfacePositions();
01511 
01512     if(_createTexCoords)
01513     {
01514         calcSweepSurfaceTexCoords();
01515     }
01516 
01517     // create opensg geometry field containers
01518     GeoPositions3fPtr  posPtr     = GeoPositions3f::create();
01519     GeoPLengthsUI32Ptr lensPtr    = GeoPLengthsUI32::create();
01520     GeoIndicesUI32Ptr  indicesPtr = GeoIndicesUI32::create();
01521     GeoPTypesUI8Ptr    typesPtr   = GeoPTypesUI8::create();
01522     GeoNormals3fPtr    normalsPtr = NullFC;
01523     GeoTexCoords2fPtr  texPtr     = NullFC;
01524 
01525     if(_createNormals)
01526         normalsPtr = GeoNormals3f::create();
01527 
01528     if(_createTexCoords)
01529         texPtr = GeoTexCoords2f::create();
01530 
01531     beginEditCP(indicesPtr, GeoIndicesUI32::GeoPropDataFieldMask);
01532     beginEditCP(lensPtr,    GeoPLengthsUI32::GeoPropDataFieldMask);
01533     beginEditCP(typesPtr,   GeoPTypesUI8::GeoPropDataFieldMask);
01534 
01535     if(_createNormals)
01536     {
01537         // store sweep surface as triangle strips with vertex normals
01538         storeSweepSurfaceWithNormals(indicesPtr, lensPtr, typesPtr);
01539     }
01540     else
01541     {
01542         // store sweep surface as triangle strips without vertex normals
01543         storeSweepSurfaceWithoutNormals(indicesPtr, lensPtr, typesPtr);
01544     }
01545 
01546     if(_convex)
01547     {
01548         // calculate and store caps as triangle fans
01549         if(_beginCap)
01550         {
01551             FDEBUG(("OSGExtrusion:createGeometry: Creating begin cap\n"));
01552             storeConvexCap(0,           // spine section 0 
01553                            true,        // flip normal
01554                            indicesPtr, 
01555                            lensPtr, 
01556                            typesPtr);
01557         }
01558         
01559         if(_endCap)
01560         {
01561             FDEBUG(("OSGExtrusion:createGeometry: Creating end cap\n"));
01562             storeConvexCap(_spine.size() - 1,  // last spine section
01563                            false,              // don't flip normal
01564                            indicesPtr,
01565                            lensPtr, 
01566                            typesPtr);
01567         }
01568     }
01569     else // non-convex case
01570     {
01571         FFATAL(("OSGExtrusion:createGeometry: Support for non-convex caps not implemented\n"));
01572     }
01573     
01574 #ifdef DEBUG_VERTEX_NORMALS
01575     // add surface normals for debugging purposes
01576     storeVertexNormalGeo(indicesPtr, lensPtr, typesPtr);
01577 #endif
01578 
01579 #ifdef DEBUG_FACE_NORMALS
01580     // add sweep surface face normals for debugging purposes
01581     storeFaceNormalGeo(indicesPtr, lensPtr, typesPtr);
01582 #endif    
01583 
01584     endEditCP(indicesPtr, GeoIndicesUI32::GeoPropDataFieldMask);
01585     endEditCP(lensPtr,    GeoPLengthsUI32::GeoPropDataFieldMask);
01586     endEditCP(typesPtr,   GeoPTypesUI8::GeoPropDataFieldMask);
01587 
01588     // store the shared vertex data into the vertex data field containers
01589     storeMaps(posPtr, normalsPtr, texPtr);
01590 
01591     // create a new OpenSG geometry
01592     GeometryPtr geoPtr = Geometry::create();
01593 
01594     beginEditCP(geoPtr, Geometry::TypesFieldMask  |
01595                 Geometry::LengthsFieldMask        |
01596                 Geometry::IndicesFieldMask        |
01597                 Geometry::IndexMappingFieldMask   |
01598                 Geometry::PositionsFieldMask      |
01599                 Geometry::NormalsFieldMask        |
01600                 Geometry::TexCoordsFieldMask      );
01601 
01602     // The interleaved multi-index blocks have one of the following 
01603     // layouts (depending on _createNormals and _createTexCoords):
01604     //
01605     // 1. (Position)                  
01606     // 2. (Position, Normal)
01607     // 3. (Position, TexCoord)        
01608     // 4. (Position, Normal, TexCoord)
01609     geoPtr->getIndexMapping().push_back(Geometry::MapPosition);
01610     if(_createNormals)
01611         geoPtr->getIndexMapping().push_back(Geometry::MapNormal);
01612     if(_createTexCoords)
01613         geoPtr->getIndexMapping().push_back(Geometry::MapTexCoords);
01614 
01615     // set primitive data field containers
01616     geoPtr->setLengths(lensPtr);
01617     geoPtr->setIndices(indicesPtr);
01618     geoPtr->setTypes(typesPtr);
01619    
01620     // set vertex data field containers
01621     geoPtr->setPositions(posPtr);
01622     geoPtr->setNormals(normalsPtr);
01623     geoPtr->setTexCoords(texPtr);
01624    
01625     endEditCP(geoPtr, Geometry::TypesFieldMask  |
01626               Geometry::LengthsFieldMask        |
01627               Geometry::IndicesFieldMask        |
01628               Geometry::IndexMappingFieldMask   |
01629               Geometry::PositionsFieldMask      |
01630               Geometry::NormalsFieldMask        |
01631               Geometry::TexCoordsFieldMask      );
01632 
01633 
01634     SINFO << "OSGExtrusion:createGeometry: Stats: ("
01635           << _primitiveCount     << '/'
01636           << _totalVertexCount   << '/'
01637           << _posMap.size() << '/'
01638           << _normalMap.size()   << '/'
01639           << _texCoordMap.size() << ')'
01640           << "(Prims/Verts/Pos/Norms/TexCoords)"
01641           << std::endl; 
01642         
01643     return geoPtr;
01644 }

void osg::ExtrusionSurface::operator= const ExtrusionSurface source  )  [private]
 

void ExtrusionSurface::calcXAxes void   )  [inline, private]
 

Calculates the X-Axes of the CP to SCP transforms

Definition at line 331 of file OSGExtrusionGeometry.cpp.

References _revolutionSurface, _spineCollinear, _transform, and calcXAxis().

Referenced by calcTransforms().

00332 {
00333     std::vector<Matrix>::iterator tIt = _transform.begin();
00334 
00335     // Either of the two cases below implies the cross product of
00336     // the y- and the z-axis vanish (and so do all x-axes)
00337     if(!_spineCollinear && !_revolutionSurface)
00338     {
00339         for(; tIt != _transform.end(); ++tIt)
00340         {
00341             Vec3f xAxis = calcXAxis(tIt);
00342             (*tIt)[0].setValue(xAxis);
00343         }
00344     }
00345     else
00346     {
00347         (*tIt)[0].setValue(Vec3f(0.f, 0.f, 0.f));
00348     }
00349 }

void ExtrusionSurface::calcYAxes void   )  [inline, private]
 

Calculates the Y-Axes of the CP to SCP transforms

Definition at line 361 of file OSGExtrusionGeometry.cpp.

References _revolutionSurface, _spine, _transform, calcNonUnitYAxis(), osg::Eps, FDEBUG, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::length(), and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize().

Referenced by calcTransforms().

00362 {
00363     bool yAxisDefined = false;
00364 
00365     std::vector<Pnt3f>::const_iterator  spineIt = _spine.begin();
00366     std::vector<Matrix>::iterator tIt = _transform.begin();
00367     for(; spineIt != _spine.end(); ++spineIt, ++tIt)
00368     {
00369         Vec3f yAxis = calcNonUnitYAxis(spineIt);
00370         if(yAxis.length() > Eps) // we have found a valid tangent
00371         {
00372             yAxis.normalize();
00373             if(!yAxisDefined)
00374             {
00375                 FDEBUG(("OSGExtrusion:calcYAxes: yAxis is defined\n"));
00376                 yAxisDefined = true;
00377 
00378                 // assign found y-axis to all transforms
00379                 // up to and including the current one
00380                 std::vector<Matrix>::iterator yIt;
00381                 for(yIt = _transform.begin(); yIt != (tIt + 1); ++yIt)
00382                     (*yIt)[1].setValue(yAxis);
00383             }
00384             else 
00385             {
00386                 // assign found y-axis to the current transform only
00387                 (*tIt)[1].setValue(yAxis);
00388             }
00389         }
00390         else if(yAxisDefined)
00391         {
00392             // reuse y-axis determined during last step
00393             (*tIt)[1] = (*(tIt - 1))[1];
00394         }
00395     }
00396 
00397     // all spine points coincided => surface of revolution
00398     _revolutionSurface = !yAxisDefined;
00399 }

void ExtrusionSurface::calcZAxes void   )  [inline, private]
 

Calculates the Z-Axes of the CP to SCP transforms

Definition at line 410 of file OSGExtrusionGeometry.cpp.

References _spine, _spineCollinear, _transform, calcNonUnitZAxis(), osg::VectorInterface< ValueTypeT, StorageInterfaceT >::dot(), osg::Eps, FDEBUG, osg::VectorInterface< ValueTypeT, StorageInterfaceT >::length(), osg::PointInterface< ValueTypeT, StorageInterfaceT >::negate(), and osg::VectorInterface< ValueTypeT, StorageInterfaceT >::normalize().

Referenced by calcTransforms().

00411 {
00412     bool zAxisDefined = false;
00413     
00414     std::vector<Pnt3f>::const_iterator  spineIt = _spine.begin();
00415     std::vector<Matrix>::iterator tIt = _transform.begin();
00416     for(; spineIt != _spine.end(); ++spineIt, ++tIt)
00417     {
00418         Vec3f zAxis = calcNonUnitZAxis(spineIt);
00419         if(zAxis.length() > Eps)
00420         {
00421             zAxis.normalize();
00422             if(!zAxisDefined)
00423             {
00424                 FDEBUG(("OSGExtrusion:calcZAxes: zAxis is defined\n"));
00425                 zAxisDefined = true;
00426                 
00427                 // set the current z-Axis for the current transform
00428                 (*tIt)[2].setValue(zAxis);
00429 
00430                 // assign found z-axis to all previous transforms
00431                 std::vector<Matrix>::iterator zIt;
00432                 for(zIt = _transform.begin(); zIt != tIt; ++zIt)
00433                 {
00434                     (*zIt)[2].setValue(zAxis);
00435                 }
00436             }
00437             else // assign found z-axis to this basis _only_
00438             {
00439                 (*tIt)[2].setValue(zAxis);
00440 
00441                 // as the zAxis is defined tIt - 1 contains a valid value 
00442                 Vec3f prevZAxis((*(tIt - 1))[2][0],
00443                                 (*(tIt - 1))[2][1],
00444                                 (*(tIt - 1))[2][2]);
00445 
00446                 // check whether the z-axis needs to be flipped
00447                 if(prevZAxis.dot(zAxis) + Eps < 0.f)
00448                 {
00449                     FDEBUG(("OSGExtrusion:calcZAxes: Flipping z-axis\n"));
00450                     zAxis.negate();
00451                 }
00452 
00453                 // assign zAxis to current transform
00454                 (*tIt)[2].setValue(zAxis);
00455             }
00456         }
00457         else if(zAxisDefined)
00458         {
00459             // reuse previous value
00460             (*tIt)[2] = (*(tIt - 1))[2];
00461         }
00462     } // end for
00463 
00464     // All cross products vanished => spine has no non-collinear part
00465     // and is thus composed of collinear parts and revolutions only
00466     _spineCollinear = !zAxisDefined;
00467 }

void ExtrusionSurface::calcTransforms void   )  [private]
 

Calculates the affine transformations from CP to SCP

Definition at line 480 of file OSGExtrusionGeometry.cpp.

References _orientation, _revolutionSurface, _scale, _spine, _spineCollinear, _transform, calcXAxes(), calcYAxes(), calcZAxes(), FDEBUG, osg::QuaternionBase< ValueTypeT >::getValue(), osg::TransformationMatrix< ValueTypeT >::multLeft(), and osg::QuaternionBase< ValueTypeT >::setValue().

Referenced by calcSweepSurfacePositions().

00481 {
00482     _transform.clear();
00483 
00484     // initialize the transformations with Id
00485     _transform.resize(_spine.size());
00486 
00487     /* X3D Spec:
00488      * The SCP is computed by first computing its Y-axis and Z-axis, then 
00489      * taking the cross product of these to determine the X-axis. These three 
00490      * axes are then used to determine the rotation value needed to rotate the
00491      * Y=0 plane to the SCP. This results in a plane that is the approximate 
00492      * tangent of the spine at each point, as shown in Figure 13.5.
00493      */
00494     calcZAxes(); // sets bool _spineCollinear
00495     calcYAxes(); // sets bool _revolutionSurface
00496 
00497     // We need to make a difference between surfaces having at least
00498     // one non-trivial collinear part in their spine and surfaces created
00499     // by pure revolution of the crossection.
00500     if(_revolutionSurface)
00501     {
00502         _spineCollinear = false;
00503     }
00504     calcXAxes(); // uses _spineCollinear and _revolutionSurface
00505 
00506     /* X3D Spec:
00507      *
00508      * If the entire spine is collinear, the SCP is computed by finding the 
00509      * rotation of a vector along the positive Y-axis (v1) to the vector formed
00510      * by the spine points (v2). The Y=0 plane is then rotated by this value.
00511      *
00512      * If two points are coincident, they both have the same SCP. If each point
00513      * has a different orientation value, then the surface is constructed by 
00514      * connecting edges of the cross-sections as normal. This is useful in 
00515      * creating revolved surfaces.
00516      */
00517     Matrix rotation; // m = Id and thus ok for revolution case
00518     if(_spineCollinear && !_revolutionSurface)
00519     {
00520         // calculate the rotation that rotates the y unit vector to the
00521         // direction of the spine.
00522         Vec3f v1(0.f, 1.f, 0.f);
00523         Vec3f v2(_transform[0][1]);
00524             
00525         Quaternion q;
00526         q.setValue(v1, v2);
00527         q.getValue(rotation);
00528     }
00529 
00530     std::vector<Matrix>::iterator tIt             = _transform.begin();
00531     std::vector<Pnt3f>::const_iterator spineIt    = _spine.begin();
00532     std::vector<Vec2f>::const_iterator scaleIt    = _scale.begin(); 
00533     std::vector<Quaternion>::const_iterator rotIt = _orientation.begin();
00534 
00535     // calculate an affine transformation for the cross-section at
00536     // each spine point
00537     for(; spineIt != _spine.end(); ++spineIt, ++tIt)
00538     {
00539         // special cases
00540         if(_spineCollinear || _revolutionSurface)
00541         {
00542             // defines the x,y and z-axes in this case
00543             *tIt = rotation;
00544         }        
00545 
00546         // setup transform of the CP
00547         Matrix cSPlaneTransform;
00548 
00549         // Scale the x- and z-axes
00550         cSPlaneTransform[0] *= (*scaleIt)[0];
00551         cSPlaneTransform[2] *= (*scaleIt)[1];
00552 
00553         // apply orientation
00554         Matrix orientationMatrix;
00555         rotIt->getValue(orientationMatrix);
00556         cSPlaneTransform.multLeft(orientationMatrix);
00557 
00558         tIt->mult(cSPlaneTransform);
00559 
00560         // affine translation to the spine point
00561         tIt->setTranslate(*spineIt);
00562         
00563         // The affine transformation *tIt should now
00564         //
00565         //   1. scale the CP
00566         //   2. apply the orientation to the CP        
00567         //   2. translate the origin to spine[i]
00568         //
00569         // in exactly this order.
00570 
00571         /* X3D Spec quotation:
00572          *
00573          * If the number of scale or orientation values is greater than the
00574          * number of spine points, the excess values are ignored. If they 
00575          * contain one value, it is applied at all spine points. The 
00576          * results are undefined if the number of scale or orientation 
00577          * values is greater than one but less than the number of spine 
00578          * points. The scale values shall be positive.
00579          */
00580         
00581         // always use last available value
00582         if(rotIt + 1   != _orientation.end()) { ++rotIt;   }
00583         if(scaleIt + 1 != _scale.end())       { ++scaleIt; }
00584     }
00585 
00586     FDEBUG(("OSGExtrusion:calcTransforms: spine collinear: %s\n", 
00587             (_spineCollinear ? "true" : "false")));
00588 
00589     FDEBUG(("OSGExtrusion:calcTransforms: revolution surface: %s\n",
00590             (_revolutionSurface ? "true" : "false")));
00591 }

void ExtrusionSurface::calcSweepSurfacePositions void   )  [private]
 

Calculates the positions of the sweep surface and stores them in the _grid

Definition at line 624 of file OSGExtrusionGeometry.cpp.

References _crossSection, _grid, _posMap, _spine, _transform, calcTransforms(), osg::Eps, FDEBUG, FFATAL, FWARNING, initGrid(), p, and SWARNING.

Referenced by createGeometry().

00625 {
00626     FDEBUG(("OSGExtrusion:calcSweepSurfacePositions: Calculation vertex positions\n"));
00627 
00628     if(_grid.size() < _spine.size())
00629     {
00630         FFATAL(("OSGExtrusion:calcSweepSurfacePositions: Grid not initialized\n"));
00631         return;
00632     }
00633 
00634     _posMap.clear();
00635 
00636     // compute transformation matrices
00637     calcTransforms();
00638 
00639     if(_grid.size() < _spine.size()) // grid not yet or incorrectly initialized
00640     {
00641         initGrid();
00642     }
00643 
00644     std::vector<Matrix>::iterator transIt = _transform.begin();
00645     VertexGrid::iterator gridRowIt = _grid.begin();
00646 
00647     // iterate over the spine points
00648     for(Int32 i = 0; i < _spine.size(); i++, ++gridRowIt)
00649     {
00650         if(transIt->det3() < Eps) // degenerate transform
00651         {
00652             FWARNING(("OSGExtrusion:calcSurfacePositions: Degenerate transformation matrix\n"));
00653             SWARNING << "Degenerate transform[" << i << "]:\n "
00654                      << *transIt << std::endl;
00655         }
00656 
00657         std::vector<Vertex>::iterator gridColIt = gridRowIt->begin();
00658         std::vector<Pnt2f>::iterator crossIt;
00659 
00660         // iterate over the cross-section curve
00661         for(crossIt = _crossSection.begin(); crossIt != _crossSection.end();
00662             ++crossIt, ++gridColIt)
00663         {
00664             Pnt3f p = Pnt3f((*crossIt)[0], 0.f, (*crossIt)[1]);
00665 
00666             // apply "CP to SCP"-transform
00667             transIt->multMatrixPnt(p, gridColIt->position);
00668         }
00669 
00670         // always use last defined transformation matrix
00671         if(transIt + 1 != _transform.end()) { ++transIt; }
00672     }
00673 }

void ExtrusionSurface::calcSweepSurfaceFaceNormals void   )  [private]
 

Calculates the face normals of the sweep surface and stores them in the _grid

Definition at line 748 of file OSGExtrusionGeometry.cpp.

References _crossSection, _crossSectionClosed, _grid, _spine, _spineClosed, calcQuadFaceNormal(), FDEBUG, and FFATAL.

Referenced by storeSweepSurfaceWithNormals().

00749 {
00750     FDEBUG(("OSGExtrusion:calcSweepSurfaceFaceNormals: Calculating sweep surface face normals\n"));
00751 
00752     if(_grid.size() < _spine.size())
00753     {
00754         FFATAL(("OSGExtrusion:calcSweepSurfaceFaceNormals: Grid not initialized\n"));
00755         return;
00756     }
00757     
00758     // calculate face normals
00759     for(UInt32 i = 0; i < _spine.size(); ++i)
00760     {
00761         UInt32 iPrev, iNext;
00762 
00763         // determine adjacent row indices
00764         if(_spineClosed)
00765         {
00766             // first point == last point
00767             iPrev = (i != 0) ? i - 1 : _spine.size() - 2;
00768             iNext = (i != _spine.size() - 1) ? i + 1 : 1;
00769         }
00770         else
00771         {
00772             iPrev = (i != 0) ? i - 1 : 0;
00773             iNext = (i != _spine.size() - 1) ? i + 1 : i;
00774         }
00775 
00776         for(UInt32 j = 0; j < _crossSection.size(); ++j)
00777         {
00778             Vec3f n;
00779             UInt32 jPrev, jNext;
00780 
00781             // determine adjacent column indices
00782             if(_crossSectionClosed)
00783             {
00784                 // first point == last point
00785                 jPrev = (j != 0) ? j - 1 : _crossSection.size() - 2;
00786                 jNext = (j != _crossSection.size() - 1) ? j + 1 : 1;
00787             }
00788             else
00789             {
00790                 jPrev = (j != 0) ? j - 1 : 0;
00791                 jNext = (j != _crossSection.size() - 1) ? j + 1 : j;
00792             }
00793 
00794             // upper right face normal (1st quadrant)
00795             _grid[i][j].adjFaceNormals[0] =
00796                 calcQuadFaceNormal(_grid[i][j].position,
00797                                    _grid[i][jNext].position,
00798                                    _grid[iNext][jNext].position,
00799                                    _grid[iNext][j].position);
00800 
00801 
00802             // upper left face normal (2nd quadrant)
00803             _grid[i][j].adjFaceNormals[1] = 
00804                 calcQuadFaceNormal(_grid[i][j].position,
00805                                    _grid[iNext][j].position,
00806                                    _grid[iNext][jPrev].position,
00807                                    _grid[i][jPrev].position);
00808 
00809 
00810             // lower left face normal (3nd quadrant)
00811             _grid[i][j].adjFaceNormals[2] = 
00812                 calcQuadFaceNormal(_grid[i][j].position,
00813                                    _grid[i][jPrev].position,
00814                                    _grid[iPrev][jPrev].position,
00815                                    _grid[iPrev][j].position);
00816 
00817 
00818             // lower right face normal (4th quadrant)
00819             _grid[i][j].adjFaceNormals[3] = 
00820                 calcQuadFaceNormal(_grid[i][j].position,
00821                                    _grid[iPrev][j].position,
00822                                    _grid[iPrev][jNext].position,
00823                                    _grid[i][jNext].position);
00824         }
00825     }
00826 }

void ExtrusionSurface::calcSweepSurfaceTexCoords void   )  [private]
 

Definition at line 686 of file OSGExtrusionGeometry.cpp.

References _crossSection, _grid, _spine, _texCoordMap, osg::Eps, FDEBUG, and FFATAL.