PolygonMesh Class Reference
 
 
 
PolygonMesh Class Reference

This reference page is linked to from the following overview topics: Softimage 2014, Creating a Custom Primitive.


#include <xsi_polygonmesh.h>


Class Description

A PolygonMesh is a kind of Geometry.

We can navigate the PolygonMesh using the generic terms such as Facet, Segment or Point or we can choose to navigate using terms that are specific to the PolygonMesh such as PolygonFace, Edge and Vertex. There are some functions that do not fit with the generic terms such as PolygonNode, which are specific to PolygonMesh, this is why there are specific terms as well as generic terms.

See also:
Primitive::GetGeometry, X3DObject::AddPolygonMesh
Example:
                using namespace XSI;

                Application app;
                Model root = app.GetActiveSceneRoot();

                X3DObject myGrid;
                root.AddGeometry( L"Grid", L"MeshSurface", L"", myGrid );

                PolygonMesh mesh( myGrid.GetActivePrimitive().GetGeometry(0) );

                CPolygonFaceRefArray polygonArray( mesh.GetPolygons() );

                CValue val( polygonArray.GetCount() );
                app.LogMessage( CString(L"Number of polygons: ") + val.GetAsText() );
Inheritance diagram for PolygonMesh:
Geometry SIObject CBase

List of all members.

Public Member Functions

  PolygonMesh ()
  ~PolygonMesh ()
  PolygonMesh (const CRef &in_ref)
  PolygonMesh (const PolygonMesh &in_obj)
  PolygonMesh (const Geometry &in_obj)
bool  IsA (siClassID in_ClassID) const
siClassID  GetClassID () const
PolygonMesh operator= (const PolygonMesh &in_obj)
PolygonMesh operator= (const Geometry &in_geom)
PolygonMesh operator= (const CRef &in_ref)
CVertexRefArray  GetVertices () const
CEdgeRefArray  GetEdges () const
CPolygonFaceRefArray  GetPolygons () const
CPolygonNodeRefArray  GetNodes () const
CStatus  Set (const MATH::CVector3Array &in_vertices, const CLongArray &in_polygonDescr)
CStatus  Get (MATH::CVector3Array &io_vertices, CLongArray &io_polygonDescr) const
CStatus  PutCurrentVertexColor (const ClusterProperty &=ClusterProperty())
ClusterProperty  GetCurrentVertexColor (void) const
ClusterProperty  AddVertexColor (const CString &name=CString())
CRefArray  GetVertexColors (void) const
CGeometryAccessor  GetGeometryAccessor (siConstructionMode in_mode=siConstructionModeModeling, siSubdivisionRuleType in_type=siCatmullClark, LONG in_subdLevel=0, bool in_bUseLoopForTriangles=false, bool in_bUseDiscontinuity=true, double in_discontinuityAngle=60.0) const
CMeshBuilder  GetMeshBuilder () const
CClusterPropertyBuilder  GetClusterPropertyBuilder () const
CStatus  GetPolygonIndexArray (const PointLocatorData &in_ptLocators, LONG in_nbPointLocatorsIndices, const LONG *in_pPointLocatorsIndices, LONG *out_pIndices) const
CStatus  GetTriangleVertexIndexArray (const PointLocatorData &in_ptLocators, LONG in_nbPointLocatorsIndices, const LONG *in_pPointLocatorsIndices, LONG *out_pIndices) const
CStatus  GetTriangleNodeIndexArray (const PointLocatorData &in_ptLocators, LONG in_nbPointLocatorsIndices, const LONG *in_pPointLocatorsIndices, LONG *out_pIndices) const
CStatus  GetTriangleWeightArray (const PointLocatorData &in_ptLocators, LONG in_nbPointLocatorsIndices, const LONG *in_pPointLocatorsIndices, float *out_pWeights) const
PointLocatorData  ConstructPointLocators (LONG in_nbPointLocators, const LONG *in_pPolygonIndices, const LONG *in_pSubTriangleVertexIndices, const float *in_pSubTriangleWeights) const

Constructor & Destructor Documentation

Default constructor.

Default destructor.

PolygonMesh ( const CRef in_ref )

Constructor.

Parameters:
in_ref constant reference object.
PolygonMesh ( const PolygonMesh in_obj )

Copy constructor.

Parameters:
in_obj constant class object.
PolygonMesh ( const Geometry in_obj )

Copy constructor.

Parameters:
in_obj Geometry object.

Member Function Documentation

bool IsA ( siClassID  in_ClassID ) const [virtual]

Returns true if a given class type is compatible with this API class.

Parameters:
in_ClassID class type.
Returns:
true if the class is compatible, false otherwise.

Reimplemented from Geometry.

siClassID GetClassID ( ) const [virtual]

Returns the type of the API class.

Returns:
The class type.

Reimplemented from Geometry.

PolygonMesh& operator= ( const PolygonMesh in_obj )

Creates an object from another object. The newly created object is set to empty if the input object is not compatible.

Parameters:
in_obj constant class object.
Returns:
The new PolygonMesh object.
PolygonMesh& operator= ( const Geometry in_geom )

Creates a Polygon object from a Geometry object. The newly created object is set to empty if the input Geometry object is not compatible.

Parameters:
in_geom constant class object.
Returns:
The new PolygonMesh object.

Reimplemented from Geometry.

PolygonMesh& operator= ( const CRef in_ref )

Creates an object from a reference object. The newly created object is set to empty if the input reference object is not compatible.

Parameters:
in_ref constant class object.
Returns:
The new PolygonMesh object.

Reimplemented from Geometry.

CVertexRefArray GetVertices ( ) const

Returns an array of of all Vertex objects on this PolygonMesh object.

Returns:
Array of Vertex objects.
CEdgeRefArray GetEdges ( ) const

Returns an array of all Edge objects on this PolygonMesh object.

Returns:
Array of Edge objects.
CPolygonFaceRefArray GetPolygons ( ) const

Returns an array of all PolygonFace objects on this PolygonMesh object.

Returns:
Array of PolygonFace objects.
CPolygonNodeRefArray GetNodes ( ) const

Returns an array of all PolygonNode objects on this PolygonMesh object.

Returns:
Array of PolygonNode objects.
CStatus Set ( const MATH::CVector3Array in_vertices,
const CLongArray in_polygonDescr 
)

Sets the PolygonMesh from a raw data set. If this function is used on a polygon mesh with some clusters and a topology change is performed, the caller is responsible for updating the clusters.

Parameters:
in_vertices Array representing the polygon vertices. Each vertex is expressed with a CVector3 structure.
in_polygonDescr An ordered array of polygon definitions, each polygon is defined by a list of elements, the first element of a polygon definition must be set with the number of indices for that polygon. The ordering of vertices must respect a ccw ordering to get out going normals (right-hand rule). For instance, an array of polygons with 4 indices each is formatted as {4,0,1,4,3,4,1,2,5,4...}
Returns:
CStatus::OK success
CStatus::AccessDenied function used outside of a plug-in operator context.
Example:
                using namespace XSI;
                using namespace MATH;

                Application app;
                Model root = app.GetActiveSceneRoot();

                X3DObject myCube;
                root.AddGeometry( L"Cube", L"MeshSurface", L"", myCube );

                X3DObject myCone;
                root.AddGeometry( L"Cone", L"MeshSurface", L"", myCone );

                PolygonMesh meshCube( myCube.GetActivePrimitive().GetGeometry() );

                //Getting the polygon mesh description
                CVector3Array   vertices;
                CLongArray              polygonData;
                meshCube.Get(vertices,polygonData);

                //Freezing the geometry
                CValueArray args(3);
                CValue outArg;
                args[0] = myCone.GetRef();
                app.ExecuteCommand(L"FreezeObj",args, outArg);

                PolygonMesh meshCone( myCone.GetActivePrimitive().GetGeometry() );

                //converting the cone to a cube.
                meshCone.Set(vertices,polygonData);
CStatus Get ( MATH::CVector3Array io_vertices,
CLongArray io_polygonDescr 
) const

Returns a complete data set description of a polygon mesh.

Parameters:
io_vertices Array representing the polygon vertices. Each vertex is expressed with a CVector3 structure.
io_polygonDescr An ordered array of polygon definitions, each polygon is defined by a list of elements, the first element of a polygon definition must be set with the number of indices for that polygon. The ordering of vertices must respect a ccw ordering to get out going normals (right-hand rule). For instance, an array of polygons with 4 indices each is formatted as {4,0,1,4,3,4,1,2,5,4...}
Returns:
CStatus::OK success
CStatus::Fail failure
CStatus PutCurrentVertexColor ( const ClusterProperty = ClusterProperty() )

Sets the current color at vertices property used by the polygon mesh's material. Using the default argument clears the current vertex color property.

Returns:
CStatus::OK success
CStatus::Fail failure
ClusterProperty GetCurrentVertexColor ( void  ) const

Returns the current vertex color property used by the polygon mesh's material. When you first create a polygon mesh it inherits a material but doesn't automatically have a vertex color. You need to explicitly set the vertex color to be used by the material (this then becomes the current vertex color). The current color at vertices property may not be set, in which case the first vertex color property found will be returned. If the polygon mesh has no vertex color properties then an empty ClusterProperty API class will be returned. Use the IsValid() method to check if the cluster property is valid.

Returns:
ClusterProperty
ClusterProperty AddVertexColor ( const CString name = CString() )

Adds a new vertex color property to this polygon mesh object.

Parameters:
name name of new vertex color.
Returns:
The vertex color property as a ClusterProperty.
CRefArray GetVertexColors ( void  ) const

Returns an array of the vertex color properties installed on this polygon mesh object.

Returns:
Array of vertex color properties.
CGeometryAccessor GetGeometryAccessor ( siConstructionMode  in_mode = siConstructionModeModeling,
siSubdivisionRuleType  in_type = siCatmullClark,
LONG  in_subdLevel = 0,
bool  in_bUseLoopForTriangles = false,
bool  in_bUseDiscontinuity = true,
double  in_discontinuityAngle = 60.0 
) const

Returns a geometry accessor object which gives access to the mesh and subdivided geometry data.

Note: The CGeometryAccessor object can be accessed in a custom operator. However, the in_mode argument is ignored if GetGeometryAccessor is called on a primitive connected on the operator.

Parameters:
in_mode The construction mode is used to access a version of the geometry with specific deforms. The geometry positions you get depends on the mode you pass in, for instance, when in_mode is set to siConstructionModeModeling, you get the original geometry positions. This mode is typically used in export applications where geometry, shape and envelope positions are exported separately. Other modes of interest (see siConstructionMode) include:
  • siConstructionModePrimaryShape: Combines the geometry positions with the shape deformation.
  • siConstructionModeAnimation: Combines the geometry positions with the shape and envelope deformation altogether.
  • siConstructionModeSecondaryShape: Combines the geometry positions with the shape and envelope deformation and the deforms installed above the envelope such as the move point operators. This mode is typically used for plotting the final results of shape and envelope deformation.
  • siConstructionModeDefault: Uses the current construction mode set in Softimage.
Parameters:
in_type The algorithm used for subdividing the geometry.
in_subdLevel The level of subdivision of the geometry. Defaults to 0.
in_bUseLoopForTriangles This argument is specific to the subdivision and provides a more precise subdivision when set to true. The argument is ignored when in_subdLevel is 0. Defaults to false.
in_bUseDiscontinuity Allows computing the discontinuity of normals when accessing the normal values of the geometry. If this flag is false the resulting normals are smoothed. Defaults to true.
in_discontinuityAngle Specifies the angle of discontinuity when accessing the normal values on the geometry. This argument is ignored if in_bUseDiscontinuity is false. Defaults to 60.0.
Returns:
CGeometryAccessor object.
Since:
5.0
CMeshBuilder GetMeshBuilder ( ) const

Returns a mesh builder object.

Returns:
CMeshBuilder object.
Since:
5.0
CClusterPropertyBuilder GetClusterPropertyBuilder ( ) const

Returns a cluster property builder object.

Returns:
CClusterPropertyBuilder object.
Since:
5.0
CStatus GetPolygonIndexArray ( const PointLocatorData in_ptLocators,
LONG  in_nbPointLocatorsIndices,
const LONG *  in_pPointLocatorsIndices,
LONG *  out_pIndices 
) const

Returns the polygon indices on which point locators are defined.

The position within the polygon can be queried with PolygonMesh::GetTriangleVertexIndexArray, PolygonMesh::GetTriangleNodeIndexArray and PolygonMesh::GetTriangleWeightArray.

Notice that this information is part of polygon mesh point locator's definition, and depends on the topology only (won't change if the geometry is deformed).

Parameters:
in_ptLocators Contains the point locations to be queried.
in_nbPointLocatorsIndices Number of point locators to be queried (-1 if all)
in_pPointLocatorsIndices Point locator indices to be queried (not used if in_nbPointLocatorIndices is -1)
Return values:
out_pIndices Returned polygon indices. Size must be in_ptLocators.GetCount() if in_nbPointLocatorIndices is -1, in_nbPointLocatorIndices otherwise.
Returns:
CStatus::OK success
CStatus::Fail failure
See also:
PolygonMesh::GetTriangleVertexIndexArray, PolygonMesh::GetTriangleNodeIndexArray, PolygonMesh::GetTriangleWeightArray, PolygonMesh::ConstructPointLocators
Since:
5.0
Example:
This example topologically describes the point locators resulting from the shrink-wrapping of a cube onto a mesh sphere.
                using namespace XSI;
                Application app;
                Model root = app.GetActiveSceneRoot();

                X3DObject meshCubeObj;
                root.AddGeometry( L"Cube", L"MeshSurface", L"", meshCubeObj );
                PolygonMesh meshCubeGeom( meshCubeObj.GetActivePrimitive().GetGeometry() );

                X3DObject meshSphereObj;
                root.AddGeometry( L"Sphere", L"MeshSurface", L"", meshSphereObj );
                PolygonMesh meshSphereGeom( meshSphereObj.GetActivePrimitive().GetGeometry() );

                MATH::CVector3Array posArray = meshCubeGeom.GetPoints().GetPositionArray();
                PointLocatorData cubeOnSpherePointLocators = meshSphereGeom.GetClosestLocations(posArray.GetCount(), (double*)&posArray[0]);

                LONG i;
                for(i = 0; i < cubeOnSpherePointLocators.GetCount(); i++)
                {
                        LONG polygon;
                        meshSphereGeom.GetPolygonIndexArray(
                                                        cubeOnSpherePointLocators,
                                                        1, &i, &polygon);
                        LONG nodes[3];
                        meshSphereGeom.GetTriangleNodeIndexArray(
                                                        cubeOnSpherePointLocators,
                                                        1, &i, nodes);
                        LONG vertices[3];
                        meshSphereGeom.GetTriangleVertexIndexArray(
                                                        cubeOnSpherePointLocators,
                                                        1, &i, vertices);
                        float weights[3];
                        meshSphereGeom.GetTriangleWeightArray(
                                                        cubeOnSpherePointLocators,
                                                        1, &i, weights);

                        app.LogMessage(L"Point locator " + CString(CValue(i)) + L" is on polygon " + CString(CValue(polygon)) + L",");
                        app.LogMessage(L"on a subtriangle described by nodes ("
                                                + CString(CValue(nodes[0])) + L", " + CString(CValue(nodes[1])) + L", " + CString(CValue(nodes[2])) + L")" +
                                                L" or by vertices ("
                                                + CString(CValue(vertices[0])) + L", " + CString(CValue(vertices[1])) + L", " + CString(CValue(vertices[2])) + L")");
                        app.LogMessage(L"and having barycentric coordinates ("
                                                + CString(CValue(weights[0])) + L", " + CString(CValue(weights[1])) + L", " + CString(CValue(weights[2])) + L")");
                        app.LogMessage(L"");
                }
                // Expected results:
                //INFO : Point locator 0 is on polygon 58,
                //INFO : on a subtriangle described by nodes (217, 219, 220) or by vertices (52, 4, 53)
                //INFO : and having barycentric coordinates (0.617317, 0, 0.382683)
                //INFO :
                //INFO : Point locator 1 is on polygon 42,
                //INFO : on a subtriangle described by nodes (157, 159, 160) or by vertices (38, 46, 39)
                //INFO : and having barycentric coordinates (0.617317, 0, 0.382683)
                //INFO :
                //INFO : Point locator 2 is on polygon 61,
                //INFO : on a subtriangle described by nodes (229, 231, 232) or by vertices (55, 7, 56)
                //INFO : and having barycentric coordinates (0.382683, 0, 0.617317)
                //etc.
CStatus GetTriangleVertexIndexArray ( const PointLocatorData in_ptLocators,
LONG  in_nbPointLocatorsIndices,
const LONG *  in_pPointLocatorsIndices,
LONG *  out_pIndices 
) const

Returns the vertex indices of the polygon subtriangle on which the point locators are defined.

Each vertex index triplet is guaranteed to correspond to one polygon (the one returned by PolygonMesh::GetPolygonIndexArray). The barycentric position within the triangle can be queried with PolygonMesh::GetTriangleWeightArray.

Warning:
This information may in some cases vary between geometry instances having the same topology but different deformations. Since the point locators are defining a precise position on the surface, and since deformations can dynamically change the triangulation within a polygon, it can happen that a point locator is remapped to a different subtriangle (both barycentric weights and subtriangle indices can vary).
Parameters:
in_ptLocators Contains the point locations to be queried.
in_nbPointLocatorsIndices Number of point locators to be queried (-1 if all)
in_pPointLocatorsIndices Point locator indices to be queried (not used if in_nbPointLocatorIndices is -1)
Return values:
out_pIndices Returned triangle vertex triplets. Size must be 3*in_ptLocators.GetCount() if in_nbPointLocatorIndices is -1, 3*in_nbPointLocatorIndices otherwise.
Returns:
CStatus::OK success
CStatus::Fail failure
See also:
PolygonMesh::GetPolygonIndexArray, PolygonMesh::GetTriangleNodeIndexArray, PolygonMesh::GetTriangleWeightArray, PolygonMesh::ConstructPointLocators
Since:
5.0
Example:
An example using this method can be found in PolygonMesh::GetPolygonIndexArray and Geometry::GetClosestLocations methods' description.
CStatus GetTriangleNodeIndexArray ( const PointLocatorData in_ptLocators,
LONG  in_nbPointLocatorsIndices,
const LONG *  in_pPointLocatorsIndices,
LONG *  out_pIndices 
) const

Returns the node indices of the polygon subtriangle on which the point locators are defined.

Each node index triplet is guaranteed to correspond to one polygon (the one returned by PolygonMesh::GetPolygonIndexArray). The barycentric position within the triangle can be queried with PolygonMesh::GetTriangleWeightArray.

Warning:
This information may in some cases vary between geometry instances having the same topology but different deformations. Since the point locators are defining a precise position on the surface, and since deformations can dynamically change the triangulation within a polygon, it can happen that a point locator is remapped to a different subtriangle (both barycentric weights and subtriangle indices can vary).
Parameters:
in_ptLocators Contains the point locations to be queried.
in_nbPointLocatorsIndices Number of point locators to be queried (-1 if all)
in_pPointLocatorsIndices Point locator indices to be queried (not used if in_nbPointLocatorIndices is -1)
Return values:
out_pIndices Returned triangle node triplets. Size must be 3*in_ptLocators.GetCount() if in_nbPointLocatorIndices is -1, 3*in_nbPointLocatorIndices otherwise.
Returns:
CStatus::OK success
CStatus::Fail failure
See also:
PolygonMesh::GetPolygonIndexArray, PolygonMesh::GetTriangleNodeIndexArray, PolygonMesh::GetTriangleWeightArray, PolygonMesh::ConstructPointLocators
Since:
5.0
Example:
An example using this method can be found in PolygonMesh::GetPolygonIndexArray and Geometry::GetClosestLocations methods' description.
CStatus GetTriangleWeightArray ( const PointLocatorData in_ptLocators,
LONG  in_nbPointLocatorsIndices,
const LONG *  in_pPointLocatorsIndices,
float *  out_pWeights 
) const

Returns the barycentric weight triplets describing the position within the polygon subtriangle on which the point locators are defined.

The components defining the subtriangle queried with methods PolygonMesh::GetTriangleVertexIndexArray and PolygonMesh::GetTriangleNodeIndexArray.

Notice that this information may exceptionally vary between geometry instances having the same topology but different deformations. Since the point locators are defining a precise position on the surface, and since deformations can dynamically change the triangulation within a polygon, it can happen that a point locator is remapped to a different subtriangle (both barycentric weights and subtriangle indices can vary).

Parameters:
in_ptLocators Contains the point locations to be queried.
in_nbPointLocatorsIndices Number of point locators to be queried (-1 if all)
in_pPointLocatorsIndices Point locator indices to be queried (not used if in_nbPointLocatorIndices is -1)
Return values:
out_pWeights Returned barycentric weight triplets. Size must be 3*in_ptLocators.GetCount() if in_nbPointLocatorIndices is -1, 3*in_nbPointLocatorIndices otherwise.
Returns:
CStatus::OK success
CStatus::Fail failure
See also:
PolygonMesh::GetPolygonIndexArray, PolygonMesh::GetTriangleNodeIndexArray, PolygonMesh::GetTriangleWeightArray, PolygonMesh::ConstructPointLocators
Since:
5.0
Example:
An example using this method can be found in PolygonMesh::GetPolygonIndexArray and Geometry::GetClosestLocations methods' description.
PointLocatorData ConstructPointLocators ( LONG  in_nbPointLocators,
const LONG *  in_pPolygonIndices,
const LONG *  in_pSubTriangleVertexIndices,
const float *  in_pSubTriangleWeights 
) const

Creates a PointLocatorData from PolygonMesh specific topological information. Polygon indices, vertex indices and subtriangle barycentric weights (normalized and positive) are required in order to define each point locator. The vertex indices of a subtriangle must all be part of the corresponding input polygon.

In order to have more predictable results, it is recommended to specify the subtriangles of vertices corresponding to the actual triangulation of the polygons. Actual polygon triangulation can be retrieved with PolygonFace::TriangleSubIndexArray.

Notice that the returned point locators can be evaluated on any PolygonMesh instance having the same topology.

Parameters:
in_nbPointLocators Number of points locators to be constructed
in_pPolygonIndices Polygon indices (size must be in_nbPoints)
in_pSubTriangleVertexIndices Vertex indices on the polygon (size must be in_nbPoints*3)
in_pSubTriangleWeights Triangle barycentric weights (size must be in_nbPoints*3)
Returns:
A new PointLocatorData object
IsValid() == false if failed
See also:
PolygonMesh::GetPolygonIndexArray, PolygonMesh::GetTriangleVertexIndexArray, PolygonMesh::GetTriangleNodeIndexArray, PolygonMesh::GetTriangleWeightArray, Geometry::GetSurfacePointLocatorsFromPoints, NurbsSurfaceMesh::ConstructPointLocators
Since:
5.0
Example:
This example creates point locators at random surface locations, and positions a Null at each of these point locators.
                using namespace XSI;

                void CreateNullsAtPointLocations( X3DObject& inObj, const PointLocatorData& inPointLocators )
                {
                        Geometry geom( inObj.GetActivePrimitive().GetGeometry() );

                        std::vector<double> posData, normData;
                        posData.resize(inPointLocators.GetCount()*3);
                        normData.resize(inPointLocators.GetCount()*3);

                        geom.EvaluatePositions(inPointLocators, -1, 0, &posData.front());
                        geom.EvaluateNormals(inPointLocators, siInterpolatedVertexGeometricNormals, -1, 0, &normData.front());

                        MATH::CVector3 trans;
                        MATH::CRotation rot;

                        LONG i;
                        for (i = 0; i < (LONG)posData.size(); i+=3)
                        {
                                Null nullObj;
                                inObj.AddNull(L"",nullObj);

                                trans.Set(posData[i], posData[i+1], posData[i+2]);
                                nullObj.PutLocalTranslation(trans);

                                trans.Set(normData[i], normData[i+1], normData[i+2]);
                                rot.SetFromXYZAxes( trans, trans, trans );
                                nullObj.PutLocalRotation(rot);
                        }
                }

                float GetNormalizedRandom(){return float(rand())/RAND_MAX;}

                LONG RandInRange(LONG in_bound)
                {
                        float fRand = GetNormalizedRandom()*0.99999f;
                        return (LONG)(in_bound*fRand);
                }

                void main()
                {
                        //      Even if these point locators are simply randomly constructed,
                        //      this example shows how to do it in the most accurate way,
                        //      which is to specify subtriangles which correspond to the actual
                        //      polygon triangulation.
                        Application app;
                        Model root = app.GetActiveSceneRoot();

                        X3DObject meshSphereObj;
                        root.AddGeometry( L"Sphere", L"MeshSurface", L"", meshSphereObj );
                        PolygonMesh meshSphereGeom( meshSphereObj.GetActivePrimitive().GetGeometry() );

                        LONG nbPtLocators = 50;

                        std::vector<LONG> polygonIndexArray;
                        std::vector<LONG> subTriangleVertexArray;
                        std::vector<float> subTriangleWeightArray;

                        polygonIndexArray.resize(nbPtLocators);
                        subTriangleVertexArray.resize(nbPtLocators*3);
                        subTriangleWeightArray.resize(nbPtLocators*3);

                        CPolygonFaceRefArray polygons = meshSphereGeom.GetPolygons();

                        LONG i;
                        for(i = 0; i < nbPtLocators; i++)
                        {
                                polygonIndexArray[i] = RandInRange(polygons.GetCount());

                                PolygonFace polygon = polygons[polygonIndexArray[i]];

                                LONG subTri = RandInRange(polygon.GetNbPoints()-2);
                                CLongArray polygonNeiVtxIndices = polygon.GetVertices().GetIndexArray();

                                CLongArray triangleSubIndices = polygon.GetTriangleSubIndexArray();
                                subTriangleVertexArray[i*3] = polygonNeiVtxIndices[triangleSubIndices[subTri*3]];
                                subTriangleVertexArray[i*3+1] = polygonNeiVtxIndices[triangleSubIndices[subTri*3+1]];
                                subTriangleVertexArray[i*3+2] = polygonNeiVtxIndices[triangleSubIndices[subTri*3+2]];

                                float weights[3] = {GetNormalizedRandom(), GetNormalizedRandom(), GetNormalizedRandom()};
                                float wsum = weights[0]+weights[1]+weights[2];
                                subTriangleWeightArray[i*3] = weights[0]/wsum;
                                subTriangleWeightArray[i*3+1] = weights[0]/wsum;
                                subTriangleWeightArray[i*3+2] = weights[0]/wsum;
                        }
                        PointLocatorData randomPointLocators = meshSphereGeom.ConstructPointLocators(nbPtLocators, &polygonIndexArray.front(), &subTriangleVertexArray.front(), &subTriangleWeightArray.front());

                        CreateNullsAtPointLocations(meshSphereObj, randomPointLocators);
                }

The documentation for this class was generated from the following file: