The Geometry class gives access to a X3DObject's geometry. Geometry is the base class for specific geometry classes such as PolygonMesh and NurbsSurfaceMesh.
using namespace XSI; Application app; Model root = app.GetActiveSceneRoot(); X3DObject myGrid; root.AddGeometry( L"Grid", L"MeshSurface", L"", myGrid ); Geometry geom( myGrid.GetActivePrimitive().GetGeometry(0) ); CPointRefArray points( geom.GetPoints() ); app.LogMessage( L"Number of points: " + CValue(points.GetCount()).GetAsText() );
#include <xsi_geometry.h>
Public Member Functions |
|
Geometry () | |
~Geometry () | |
Geometry (const CRef &in_ref) | |
Geometry (const Geometry &in_obj) | |
bool | IsA (siClassID in_ClassID) const |
siClassID | GetClassID () const |
Geometry & | operator= (const Geometry &in_obj) |
Geometry & | operator= (const CRef &in_ref) |
CFacetRefArray | GetFacets () const |
CSegmentRefArray | GetSegments () const |
CPointRefArray | GetPoints () const |
CSampleRefArray | GetSamples () const |
CRefArray | GetClusters () const |
CTriangleRefArray | GetTriangles () const |
CStatus | AddCluster (const CString &in_type, const CString &in_name, const CLongArray &in_indices, Cluster &io_cluster) |
CStatus | AddEmptyCluster (const CString &in_type, const CString &in_name, Cluster &io_cluster) |
PointLocatorData | GetSurfacePointLocatorsFromPoints (LONG in_nbPoints=-1, const LONG *in_pPoints=NULL) const |
PointLocatorData | GetClosestLocations (LONG in_nbPositions, const double *in_pPositions) const |
PointLocatorData | GetRaycastIntersections (LONG in_nbPositions, const double *in_pPositions, const double *in_pRays, siLineIntersectionType in_eLineType=siSemiLineIntersection) const |
PointLocatorData | GetClosestLocationsWithinRadius (const MATH::CVector3 &in_position, double in_radius, LONG in_nbToSearch=-1) const |
CStatus | SetupPointLocatorQueries (siClosestLocationMethod in_method, MATH::CTransformation *in_pTransfo, LONG in_nbFacetsToRestrictSearch, const LONG *in_pFacetsToRestrictSearch, LONG in_nbLocatorsToBeQueried) |
CStatus | SetupClosestLocationQueries (siClosestLocationMethod in_method=siClosestSurface, MATH::CTransformation *in_pTransfo=NULL, LONG in_nbFacetsToRestrictSearch=-1, const LONG *in_pFacetsToRestrictSearch=NULL) |
CStatus | EvaluatePositions (const PointLocatorData &in_ptLocators, LONG in_nbPointLocatorsIndices, const LONG *in_pPointLocatorsIndices, double *out_pPositions) const |
CStatus | EvaluateNormals (const PointLocatorData &in_ptLocators, siNormalComputationMethod in_ComputationMethod, LONG in_nbPointLocatorsIndices, const LONG *in_pPointLocatorsIndices, double *out_pNormals) const |
CStatus | EvaluateClusterProperty (const PointLocatorData &in_ptLocators, LONG in_nbPointLocatorsIndices, const LONG *in_pPointLocatorsIndices, const Cluster &in_parentCluster, const ClusterProperty &in_clusterProperty, float *out_pData) const |
CStatus | PutCache (CValue &in_Cache) |
CValue | GetCache () |
CStatus | GetBoundingBox (double &out_centerx, double &out_centery, double &out_centerz, double &out_extentx, double &out_extenty, double &out_extentz, const MATH::CTransformation &in_XfoObjectToBBoxSpace) const |
CStatus | GetBoundingSphere (double &out_centerx, double &out_centery, double &out_centerz, double &out_radius, siVolumeCenterMethod in_centerMethod, const MATH::CTransformation &in_XfoObjectToBSphereSpace) |
CStatus | GetBoundingCapsule (double &out_centerx, double &out_centery, double &out_centerz, double &out_length, double &out_radius, siVolumeCenterMethod in_centerMethod, siBoundingCapsuleMethod in_axisMethod, const MATH::CTransformation &in_XfoObjectToBCapsuleSpace) |
CRefArray | GetICEAttributes () const |
ICEAttribute | GetICEAttributeFromName (const CString &in_name) const |
Geometry | ( | ) |
Default constructor.
~Geometry | ( | ) |
Default destructor.
bool IsA | ( | siClassID | in_ClassID | ) | const [virtual] |
Returns true if a given class type is compatible with this API class.
in_ClassID | class type. |
Reimplemented from SIObject.
Reimplemented in NurbsCurveList, NurbsSurfaceMesh, and PolygonMesh.
siClassID GetClassID | ( | ) | const [virtual] |
Returns the type of the API class.
Reimplemented from SIObject.
Reimplemented in NurbsCurveList, NurbsSurfaceMesh, and PolygonMesh.
Creates an object from another object. The newly created object is set to empty if the input object is not compatible.
in_obj | constant class object. |
Reimplemented in NurbsCurveList, NurbsSurfaceMesh, and PolygonMesh.
Creates an object from a reference object. The newly created object is set to empty if the input reference object is not compatible.
in_ref | constant class object. |
Reimplemented from SIObject.
Reimplemented in NurbsCurveList, NurbsSurfaceMesh, and PolygonMesh.
CFacetRefArray GetFacets | ( | ) | const |
Returns an array of Facet objects on this geometry.
CSegmentRefArray GetSegments | ( | ) | const |
Returns an array of Segment objects on this geometry.
CPointRefArray GetPoints | ( | ) | const |
CSampleRefArray GetSamples | ( | ) | const |
Returns an array of Sample objects on this geometry.
CRefArray GetClusters | ( | ) | const |
CTriangleRefArray GetTriangles | ( | ) | const |
Returns an array of Triangle objects on this geometry.
CStatus AddCluster | ( | const CString & | in_type, |
const CString & | in_name, | ||
const CLongArray & | in_indices, | ||
Cluster & | io_cluster | ||
) |
Creates and adds a partial or complete cluster to this geometry.
in_type | Type of cluster, such as siVertexCluster, siEdgeCluster, etc. See the ::ClusterTypes enum for a complete list. |
in_name | Name of the new cluster |
in_indices | Array of cluster indices. If an empty array is sent then a complete cluster is created. A complete cluster represents all the elements of the geometry and will remain complete even as new elements are added to the geometry. It is not possible to remove elements from such a cluster. |
io_cluster | Newly created Cluster |
Creates and adds an empty cluster to this geometry.
in_type | Type of cluster |
in_name | Name of the new cluster |
io_cluster | Newly created Cluster |
PointLocatorData GetSurfacePointLocatorsFromPoints | ( | LONG | in_nbPoints = -1 , |
const LONG * | in_pPoints =
NULL |
||
) | const |
Creates a PointLocatorData containing surface locations corresponding to the specified Points of the geometry (or all Points if not specified).
In the case of a NurbsSurfaceMesh, there is no direct relationship between the points (control vertices) and the surface. In that case, the returned point locators correspond to the surface locations most influenced by each input control vertex.
in_nbPoints | Number of points indices passed in in_pPoints. To specify all
points in geometry, use -1 . In that case, the
in_pPoints argument will be ignored. |
in_pPoints | Point indices (not used if in_pPoints is -1) |
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); } } void main() { Application app; Model root = app.GetActiveSceneRoot(); X3DObject meshSphereObj; root.AddGeometry( L"Sphere", L"MeshSurface", L"", meshSphereObj ); PolygonMesh meshSphereGeom( meshSphereObj.GetActivePrimitive().GetGeometry() ); PointLocatorData pointLocatorsFromSpherePoints = meshSphereGeom.GetSurfacePointLocatorsFromPoints(); CreateNullsAtPointLocations(meshSphereObj, pointLocatorsFromSpherePoints); }
PointLocatorData GetClosestLocations | ( | LONG | in_nbPositions, |
const double * | in_pPositions | ||
) | const |
Creates a PointLocatorData object containing the closest surface locations from the specified input positions. By default, input positions have to be defined in the object's local space reference.
Some aspects of the closest locations computation such as the reference pose or the method (closest surface, closest vertex or knot, ...) can be set up using Geometry::SetupPointLocatorQueries. This setup will affect all subsequent calls to Geometry::GetClosestLocations, Geometry::GetClosestLocationsWithinRadius or Geometry::GetRaycastIntersections.
When you call this function an acceleration cache is automatically created. See Geometry::SetupPointLocatorQueries for more information.
in_nbPositions | Number of positions (XYZ triplets) specified in in_pPositions |
in_pPositions | Positions (packed XYZ) from which the spatial search will be initiated. |
using namespace XSI; Application app; Model root = app.GetActiveSceneRoot(); Null nullObj; root.AddNull( L"myNull", nullObj ); CValueArray args(8); CValue outArg; args[0] = CValue(nullObj.GetRef()); args[1] = CValue(L"-2.0"); args[2] = CValue(L"8.0"); args[3] = CValue(L"5.0"); args[4] = CValue(L"siRelative"); args[5] = CValue(L"siView"); args[6] = CValue(L"siObj"); args[7] = CValue(L"siXYZ"); app.ExecuteCommand( L"Translate", args, outArg ); X3DObject meshSphereObj; root.AddGeometry( L"Sphere", L"MeshSurface", L"", meshSphereObj ); PolygonMesh meshSphereGeom( meshSphereObj.GetActivePrimitive().GetGeometry() ); PointLocatorData closestPointLocator = meshSphereGeom.GetClosestLocations(1, (double*)&(nullObj.GetKinematics().GetGlobal().GetTransform().GetTranslation())); double pos[3]; LONG triVtx[3]; float triWei[3]; meshSphereGeom.EvaluatePositions(closestPointLocator, -1, 0, pos); meshSphereGeom.GetTriangleVertexIndexArray(closestPointLocator, -1, 0, triVtx); meshSphereGeom.GetTriangleWeightArray(closestPointLocator, -1, 0, triWei); app.LogMessage(CString(L"The closest position on the mesh sphere from the Null is (") + CString(CValue(pos[0])) + L", " + CString(CValue(pos[1])) + L", " + CString(CValue(pos[2])) + L")"); app.LogMessage(CString(L"which corresponds to the triangle made of vertices (") + CString(CValue(triVtx[0])) + L", " + CString(CValue(triVtx[1])) + L", " + CString(CValue(triVtx[2])) + L")."); app.LogMessage(CString(L"The barycentric weight relatively to each triangle vertex is (") + CString(CValue(triWei[0])) + L", " + CString(CValue(triWei[1])) + L", " + CString(CValue(triWei[2])) + L")."); //INFO : The closest position on the mesh sphere from the Null is (-0.695969, 3.28837, 1.85179) //INFO : which corresponds to the triangle made of vertices (14, 21, 22). //INFO : The barycentric weight relatively to each triangle vertex is (0.347985, 0.121569, 0.530446).
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() ); meshSphereObj.PutParameterValue(L"subdivu", 24l); meshSphereObj.PutParameterValue(L"subdivv", 24l); // We must freeze it, otherwise setting its position array will be forbidden: CValueArray args(3); CValue outArg; args[0] = meshSphereObj.GetRef(); app.ExecuteCommand(L"FreezeObj",args, outArg); MATH::CVector3Array posArray = meshSphereGeom.GetPoints().GetPositionArray(); PointLocatorData sphereOnCubePointLocators = meshCubeGeom.GetClosestLocations(posArray.GetCount(), (double*)&posArray[0]); MATH::CVector3Array normArray; normArray.Resize(posArray.GetCount()); meshCubeGeom.EvaluatePositions(sphereOnCubePointLocators, -1, 0, (double*)&posArray[0]); meshCubeGeom.EvaluateNormals(sphereOnCubePointLocators, siInterpolatedVertexGeometricNormals, -1, 0, (double*)&normArray[0]); LONG i; for (i = 0; i < posArray.GetCount(); i++) { posArray[i].PutX(posArray[i].GetX()+normArray[i].GetX()*3); posArray[i].PutY(posArray[i].GetY()+normArray[i].GetY()*3); posArray[i].PutZ(posArray[i].GetZ()+normArray[i].GetZ()*3); } meshSphereGeom.GetPoints().PutPositionArray(posArray);
PointLocatorData GetRaycastIntersections | ( | LONG | in_nbPositions, |
const double * | in_pPositions, | ||
const double * | in_pRays, | ||
siLineIntersectionType | in_eLineType =
siSemiLineIntersection |
||
) | const |
Creates a PointLocatorData object containing the surface locations where the specified input rays intersect with the surface. By default, input positions and directions that define those rays have to be defined in the object's local space reference.
Although raycasting usually implies a semi line vs surface
intersection, one can request an infinite line vs surface or finite
line (segment) vs surface intersection by specifying
siLineIntersection
or
siSegmentIntersection
respectively for the argument
in_eLineType
(default =
siSemiLineIntersection
). In the case of
siSegmentIntersection
the length of each vector found
in in_pRays
will be used to determine where each
segment ends.
Some aspects of the raycast intersection computation such as the
reference pose for in_pPositions
and
in_pRays
or the method (closest surface, closest
vertex or knot, etc.) can be set up using Geometry::SetupPointLocatorQueries.
This setup affects all subsequent calls to Geometry::GetClosestLocations,
Geometry::GetClosestLocationsWithinRadius
or Geometry::GetRaycastIntersections.
The closest method is necessary in the case where you pass true for
in_bClosestSurfaceOtherwise
in_nbPositions | Number of rays (XYZ triplets) specified in
in_pPositions and in_pRays . |
in_pPositions | Rays' starting positions (packed XYZ). |
in_pRays | Rays' directions. The length of these vectors is important in
the case of in_eLineType ==
siSegmentIntersection |
in_eLineType | The type of line. Possible values include:
|
in_nbPositions
point locators (CRef::IsValid
==
false
if failed)using namespace XSI; Application app; Model root = app.GetActiveSceneRoot(); Null nullObj; root.AddNull( L"myNull", nullObj ); CValueArray args(8); CValue outArg; args[0] = CValue(nullObj.GetRef()); args[1] = CValue(L"-2.0"); args[2] = CValue(L"8.0"); args[3] = CValue(L"5.0"); args[4] = CValue(L"siRelative"); args[5] = CValue(L"siView"); args[6] = CValue(L"siObj"); args[7] = CValue(L"siXYZ"); app.ExecuteCommand( L"Translate", args, outArg ); X3DObject meshSphereObj; root.AddGeometry( L"Sphere", L"MeshSurface", L"", meshSphereObj ); PolygonMesh meshSphereGeom( meshSphereObj.GetActivePrimitive().GetGeometry() ); CVector3 nullPos = nullObj.GetKinematics().GetGlobal().GetTransform().GetTranslation(); CVector3 sphereCenter = meshSphereObj.GetKinematics().GetGlobal().GetTransform().GetTranslation(); CVector3 ray; ray.Sub( sphereCenter, nullPos ); PointLocatorData closestPointLocator = meshSphereGeom.GetRaycastIntersections( 1, (double*)&nullPos, (double*)&ray, siSegmentIntersection ); double pos[3]; LONG triVtx[3]; float triWei[3]; meshSphereGeom.EvaluatePositions(closestPointLocator, -1, 0, pos); meshSphereGeom.GetTriangleVertexIndexArray(closestPointLocator, -1, 0, triVtx); meshSphereGeom.GetTriangleWeightArray(closestPointLocator, -1, 0, triWei); app.LogMessage(CString(L"The mesh sphere intersects with the ray coming from the Null at (") + CString(CValue(pos[0])) + L", " + CString(CValue(pos[1])) + L", " + CString(CValue(pos[2])) + L")"); app.LogMessage(CString(L"which corresponds to the triangle made of vertices (") + CString(CValue(triVtx[0])) + L", " + CString(CValue(triVtx[1])) + L", " + CString(CValue(triVtx[2])) + L")."); app.LogMessage(CString(L"The barycentric weight relatively to each triangle vertex is (") + CString(CValue(triWei[0])) + L", " + CString(CValue(triWei[1])) + L", " + CString(CValue(triWei[2])) + L")."); //INFO : The mesh sphere intersects with the ray coming from the NULL at (-0.695969, 3.28837, 1.85179) //INFO : which corresponds to the triangle made of vertices (14, 21, 22). //INFO : The barycentric weight relatively to each triangle vertex is (0.347985, 0.121569, 0.530446).
PointLocatorData GetClosestLocationsWithinRadius | ( | const MATH::CVector3 & | in_position, |
double | in_radius, | ||
LONG | in_nbToSearch =
-1 |
||
) | const |
Constructs a PointLocatorData containing closest surface locations from the input position within a search sphere of a specific radius. By default, the input positions have to be defined in the object's local space reference. Optionally, the search can be restricted to return a maximum number of locations. In order to avoid volumetric restrictions, simply specify a very large radius.
Some aspects of the closest locations's computation such as the reference pose or the method (closest surface, closest vertex or knot, ...) can be set up using Geometry::SetupPointLocatorQueries. This setup will affect all subsequent calls to GetClosestLocationsWithinRadius, Geometry::GetClosestLocations and to Geometry::GetRaycastIntersections.
If the search was set up with Geometry::SetupPointLocatorQueries to be a closest surface or smoothed closest surface search, then it returns one point locator per connected island for PolygonMeshes. Such connected islands are defined so that you cannot walk between 2 returned point locators without leaving the search radius (this walking is through polygon adjacency, not vertex adjacency). For NurbsSurfaceMesh geometries, it returns at most one point locator.
When you call this function an acceleration cache is automatically created. See Geometry::SetupPointLocatorQueries for more information.
in_position | Position from which the spatial search will be initiated. |
in_radius | Maximum distance (cutoff) from in_PositionToSearchFrom |
in_nbToSearch | Maximum number of point locators to find (no maximum if -1) |
CStatus SetupPointLocatorQueries | ( | siClosestLocationMethod | in_method, |
MATH::CTransformation * | in_pTransfo, | ||
LONG | in_nbFacetsToRestrictSearch, | ||
const LONG * | in_pFacetsToRestrictSearch, | ||
LONG | in_nbLocatorsToBeQueried | ||
) |
Sets up how subsequent calls to Geometry::GetClosestLocations, Geometry::GetClosestLocationsWithinRadius and Geometry::GetRaycastIntersections will operate.
An acceleration cache is built either on the first call to this function or to Geometry::GetClosestLocations, Geometry::GetClosestLocationsWithinRadius or Geometry::GetRaycastIntersections. The cache assumes that the geometry will not be deformed before any subsequent call to those functions. If that is not the case, you should get the geometry again or force a rebuild of the acceleration cache by calling this function, otherwise you may get wrong results.
If you want to reuse the same cache in subsequent calls to SetupPointLocatorQueries on the same geometry but with a different instance of the Geometry object (in an operator's update function for instance) make sure to call PutCache before calling this function.
in_method | Method to use when searching the closest location (see siClosestLocationMethod for possible values). |
in_pTransfo | Reference transformation in which the input positions will be interpreted, and in which the search will be executed. Pass NULL if you dont have such a transformation. |
in_nbFacetsToRestrictSearch | Number of facets on which the search will be restricted (or -1 for no restriction) |
in_pFacetsToRestrictSearch |
Facet indices (size = in_nbFacetsToRestrictSearch). Not used if
in_nbFacetsToRestrictSearch is set to -1. |
in_nbLocatorsToBeQueried | Approximate number of point locators that will be queried next,
pass -1 if you dont know. This argument is useful to
achieve better performance in the queries that will follow the
setup. |
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() ); meshSphereObj.PutParameterValue(L"subdivu", 24l); meshSphereObj.PutParameterValue(L"subdivv", 24l); // We must freeze it, otherwise setting its position array will be forbidden: CValueArray args(3); CValue outArg; args[0] = meshSphereObj.GetRef(); app.ExecuteCommand(L"FreezeObj",args, outArg); LONG facets[2] = {2,3}; meshCubeGeom.SetupPointLocatorQueries(siClosestSurface,0,2,facets,-1); MATH::CVector3Array posArray = meshSphereGeom.GetPoints().GetPositionArray(); PointLocatorData sphereOnCubePointLocators = meshCubeGeom.GetClosestLocations(posArray.GetCount(), (double*)&posArray[0]); meshCubeGeom.EvaluatePositions(sphereOnCubePointLocators, -1, 0, (double*)&posArray[0]); meshSphereGeom.GetPoints().PutPositionArray(posArray);
CStatus SetupClosestLocationQueries | ( | siClosestLocationMethod | in_method =
siClosestSurface , |
MATH::CTransformation * | in_pTransfo =
NULL , |
||
LONG | in_nbFacetsToRestrictSearch =
-1 , |
||
const LONG * | in_pFacetsToRestrictSearch =
NULL |
||
) | [inline] |
This function has been deprecated because it does not allow you to specify the approximate number of locators that will be queried next after the call. This number is important to achieve better performance.
in_method | Method to use when searching the closest location (see siClosestLocationMethod for possible values). |
in_pTransfo | Reference transformation in which the input positions will be interpreted, and in which the search will be executed. Pass NULL if you dont have such a transformation. |
in_nbFacetsToRestrictSearch | Number of facets on which the search will be restricted (or -1 for no restriction) |
in_pFacetsToRestrictSearch |
Facet indices (size = in_nbFacetsToRestrictSearch). Not used if
in_nbFacetsToRestrictSearch is set to -1. |
in_nbLocatorsToBeQueried
is present.CStatus EvaluatePositions | ( | const PointLocatorData & | in_ptLocators, |
LONG | in_nbPointLocatorsIndices, | ||
const LONG * | in_pPointLocatorsIndices, | ||
double * | out_pPositions | ||
) | const |
Evaluates the positions at the surface locations defined by the input point locator data. The returned positions are in the geometry's local space reference.
in_ptLocators | Contains the point locations to be evaluated. |
in_nbPointLocatorsIndices | Number of point locators to be evaluated (-1 if all) |
in_pPointLocatorsIndices | Point locator indices to be evaluated (not used if in_nbPointLocatorsIndices is -1) |
out_pPositions | Returns evaluated positions' packed XYZ. Size must be
in_ptLocators::GetCount()*3 if
in_nbPointLocatorsIndices is set to -1; otherwise,
size must be in_nbPointLocatorsIndices*3 . |
CStatus EvaluateNormals | ( | const PointLocatorData & | in_ptLocators, |
siNormalComputationMethod | in_ComputationMethod, | ||
LONG | in_nbPointLocatorsIndices, | ||
const LONG * | in_pPointLocatorsIndices, | ||
double * | out_pNormals | ||
) | const |
Evaluates the surface normals at the surface locations defined by the input point locator data. The returned normals are in the geometry's local space reference. In the case of PolygonMesh, various computation methods are available.
in_ptLocators | Contains the point locations to be evaluated. |
in_ComputationMethod | Used method in order to compute the normals (only revelant to PolygonMesh geometries) |
in_nbPointLocatorsIndices | Number of point locators to be evaluated (-1 if all) |
in_pPointLocatorsIndices | Point locator indices to be evaluated (not used if in_nbPointLocatorsIndices is -1) |
out_pNormals | Returns evaluated normals' packed XYZ. Size must be
in_ptLocators::GetCount()*3 if
in_nbPointLocatorsIndices is set to -1; otherwise,
size must be in_nbPointLocatorsIndices*3 |
CStatus EvaluateClusterProperty | ( | const PointLocatorData & | in_ptLocators, |
LONG | in_nbPointLocatorsIndices, | ||
const LONG * | in_pPointLocatorsIndices, | ||
const Cluster & | in_parentCluster, | ||
const ClusterProperty & | in_clusterProperty, | ||
float * | out_pData | ||
) | const |
Evaluates the cluster property data at the surface locations defined by the point locator data.
The size of the returned array depends on the cluster property type, which can be queried using ClusterProperty::GetValueSize.
If a point locator doesn't correspond exactly to a component defining a value for the cluster property (for example, sampled point for UVs), then the value will be interpolated between adjacent components. In the case of NurbsSurfaceMesh, the returned values will be smoothed according to the NURBS surface mathematical equation since some properties are defined on control vertices (for example, weight maps) while point locators are defined on the surface.
If a point locator corresponds to a discontinuity in property space, the returned value will be an arbitrary one among the many values corresponding to that location.
in_ptLocators | Contains the point locations to be evaluated. |
in_nbPointLocatorsIndices | Number of point locators to be evaluated (-1 if all) |
in_pPointLocatorsIndices | Point locator indices to be evaluated (not used if in_nbPointLocatorsIndices is -1) |
in_parentCluster | The parent cluster of the cluster property to be evaluated. |
in_clusterProperty | The cluster property to be evaluated. |
out_pData | Returns evaluated cluster property's packed data. Size must be
in_ptLocators::GetCount() *
in_clusterProperty::GetValueSize() if
in_nbPointLocatorsIndices is -1; otherwise,
in_nbPointLocatorsIndices *
in_clusterProperty::GetValueSize() . |
Provides cache data for the geometry to use in various calls like SetupPointLocatorQueries, GetClosestLocations, and GetRaycastIntersections to speed up the execution time.
Usually this call is not necessary as the cache data is already stored in the Geometry instance and automatically reused in subsequent calls to functions like SetupPointLocatorQueries on the same Geometry.
But in some cases the instance of the Geometry object changes, like in subsequent calls to an operator's update function for instance, even though the geometry is the same. In those cases, a call to PutCache becomes necessary since the new instance of the Geometry object doesn't have the cache data that the old instance had. A call to GetCache should be made before the instance of the Geometry object is about to be released (for example, at the end of an operator's update function) so you can keep it around until you call PutCache again with a new instance of the Geometry object (for example, next time the operator's update function is called).
in_Cache | The cache data |
// MyCacheOpPlugin // Initial code generated by XSI SDK Wizard // Executed Tue Sep 12 11:12:34 EDT 2006 by ecabot // // // Tip: You need to compile the generated code before you can load the plug-in. // After you compile the plug-in, you can load it by clicking Update All in the Plugin Manager. #include <xsi_application.h> #include <xsi_context.h> #include <xsi_pluginregistrar.h> #include <xsi_status.h> #include <xsi_customoperator.h> #include <xsi_operatorcontext.h> #include <xsi_ppglayout.h> #include <xsi_ppgeventcontext.h> #include <xsi_selection.h> #include <xsi_point.h> #include <xsi_primitive.h> #include <xsi_command.h> #include <xsi_factory.h> #include <xsi_geometry.h> #include <xsi_model.h> #include <xsi_x3dobject.h> #include <xsi_kinematics.h> #include <xsi_outputport.h> #include <xsi_transformation.h> using namespace XSI; using namespace MATH; XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg ) { in_reg.PutAuthor(L"ecabot"); in_reg.PutName(L"MyCacheOpPlugin"); in_reg.PutEmail(L""); in_reg.PutURL(L""); in_reg.PutVersion(1,0); in_reg.RegisterOperator(L"MyCacheOp"); in_reg.RegisterCommand(L"ApplyMyCacheOp"); //RegistrationInsertionPoint - do not remove this line return CStatus::OK; } XSIPLUGINCALLBACK CStatus XSIUnloadPlugin( const PluginRegistrar& in_reg ) { CString strPluginName; strPluginName = in_reg.GetName(); Application().LogMessage(strPluginName + L" has been unloaded."); return CStatus::OK; } XSIPLUGINCALLBACK CStatus ApplyMyCacheOp_Init( CRef& in_ctxt ) { Context ctxt( in_ctxt ); Command oCmd; oCmd = ctxt.GetSource(); oCmd.PutDescription(L"Create an instance of MyCacheOp operator"); oCmd.SetFlag(siNoLogging,false); // TODO: You may want to add some arguments to this command so that the operator // can be applied to objects without depending on their specific names. // Tip: the Collection ArgumentHandler is very useful return CStatus::OK; } XSIPLUGINCALLBACK CStatus ApplyMyCacheOp_Execute( CRef& in_ctxt ) { Context ctxt( in_ctxt ); using namespace XSI; Application app; Model root = app.GetActiveSceneRoot(); // Let's create an arc curve that we will shrink wrap over a sphere X3DObject arcObj; root.AddGeometry( L"Arc", L"NurbsCurve", L"arc", arcObj ); // Let's create a hires sphere that we will use for the shrink wrap target X3DObject meshSphereObj; root.AddGeometry( L"Sphere", L"MeshSurface", L"sphere", meshSphereObj ); CValue outArg; // Let's make this sphere hires 200x200 CValueArray args(3); args[0] = CValue(meshSphereObj.GetFullName() + L".polymsh.geom.subdivu" ); args[1] = CValue(L"200"); args[2] = CValue(); app.ExecuteCommand( L"SetValue", args, outArg ); args[0] = CValue(meshSphereObj.GetFullName() + L".polymsh.geom.subdivv" ); app.ExecuteCommand( L"SetValue", args, outArg ); // // Note: The AddCustomOp command is an alternative way to build the operator CustomOperator newOp = Application().GetFactory().CreateObject(L"MyCacheOp"); CRef obj; obj.Set(L"arc.crvlist"); newOp.AddOutputPort(obj); obj.Set(L"arc.crvlist"); newOp.AddInputPort(obj); newOp.AddInputPort(arcObj.GetKinematics().GetGlobal()); obj.Set(L"sphere.polymsh"); newOp.AddInputPort(obj); newOp.AddInputPort(meshSphereObj.GetKinematics().GetGlobal()); newOp.Connect(); ctxt.PutAttribute( L"ReturnValue", newOp.GetRef() ); // Now animate the Z position of the curve // frame 1, XYZ = 4,0,0 args.Resize(8); args[0] = CValue(arcObj.GetFullName()); args[1] = CValue(L"4.0"); args[2] = CValue(L"0.0"); args[3] = CValue(L"0.0"); args[4] = CValue(L"siRelative"); args[5] = CValue(L"siLocal"); args[6] = CValue(L"siObj"); args[7] = CValue(L"siXYZ"); app.ExecuteCommand( L"Translate", args, outArg ); // Save a key at frame 1 args.Resize(4); args[0] = CValue(arcObj.GetFullName()+L".kine.local.posz"); args[1] = CValue((LONG)1); args[2] = CValue(); args[3] = CValue(); app.ExecuteCommand( L"SaveKey", args, outArg ); // frame 100, XYZ = 4,0,4 args.Resize(8); args[0] = CValue(arcObj.GetFullName()); args[1] = CValue(L"0.0"); args[2] = CValue(L"0.0"); args[3] = CValue(L"4.0"); args[4] = CValue(L"siRelative"); args[5] = CValue(L"siLocal"); args[6] = CValue(L"siObj"); args[7] = CValue(L"siXYZ"); app.ExecuteCommand( L"Translate", args, outArg ); // save a key at frame 100 args.Resize(4); args[0] = CValue(arcObj.GetFullName()+L".kine.local.posz"); args[1] = CValue((LONG)100); args[2] = CValue(); args[3] = CValue(); app.ExecuteCommand( L"SaveKey", args, outArg ); Application().LogMessage(L"ApplyMyCacheOp_Execute called"); return CStatus::OK; } XSIPLUGINCALLBACK CStatus MyCacheOp_Define( CRef& in_ctxt ) { Context ctxt( in_ctxt ); CustomOperator oCustomOperator; Parameter oParam; CRef oPDef; Factory oFactory = Application().GetFactory(); oCustomOperator = ctxt.GetSource(); oCustomOperator.PutAlwaysEvaluate(false); oCustomOperator.PutDebug(1); return CStatus::OK; } XSIPLUGINCALLBACK CStatus MyCacheOp_Init( CRef& in_ctxt ) { OperatorContext ctxt( in_ctxt ); Application().LogMessage(L"MyCacheOp_Init called",siVerboseMsg); return CStatus::OK; } XSIPLUGINCALLBACK CStatus MyCacheOp_Term( CRef& in_ctxt ) { OperatorContext ctxt( in_ctxt ); Application().LogMessage(L"MyCacheOp_Term called",siVerboseMsg); return CStatus::OK; } XSIPLUGINCALLBACK CStatus MyCacheOp_Update( CRef& in_ctxt ) { CStatus st; OperatorContext ctxt( in_ctxt ); Primitive io_Curve = ctxt.GetInputValue(0); KinematicState in_CurveG = ctxt.GetInputValue(1); CTransformation xCurveG = in_CurveG.GetTransform(); Primitive in_Target = ctxt.GetInputValue(2); KinematicState in_TargetG = ctxt.GetInputValue(3); CTransformation xTargetG = in_TargetG.GetTransform(); Application().LogMessage(L"MyCacheOp_Update called",siVerboseMsg); // // TODO: The Operator changes the Softimage scene by changing the state of this variable // Primitive output = ctxt.GetOutputTarget(); Geometry xTargetGeo = in_Target.GetGeometry(); CValue CacheVal = ctxt.GetUserData(); if( ! CacheVal.IsEmpty() ) { xTargetGeo.PutCache(CacheVal); } xTargetGeo.SetupPointLocatorQueries( siClosestSurface, &xTargetG, -1, NULL, -1 ); Geometry xCurveGeo = io_Curve.GetGeometry(); MATH::CVector3Array & xPoints = xCurveGeo.GetPoints().GetPositionArray(); CDoubleArray WorldPoints; WorldPoints.Resize( 3*xPoints.GetCount(), false ); LONG offset = 0; for( LONG i = 0; i < xPoints.GetCount(); ++i ) { CVector3 vPos = xPoints[i]; vPos.MulByTransformationInPlace(xCurveG); WorldPoints[offset+0] = vPos.GetX(); WorldPoints[offset+1] = vPos.GetY(); WorldPoints[offset+2] = vPos.GetZ(); offset += 3; } PointLocatorData ptLocators = xTargetGeo.GetClosestLocations( xPoints.GetCount(), WorldPoints.GetArray() ); double * PLoc = new double [ptLocators.GetCount()*3]; xTargetGeo.EvaluatePositions( ptLocators, -1, NULL, PLoc ); Geometry outGeo = output.GetGeometry(); MATH::CVector3Array & xOutPoints = outGeo.GetPoints().GetPositionArray(); CTransformation xCurveInvG; xCurveInvG.Invert(xCurveG); CTransformation xFromTargetToCurveG; xFromTargetToCurveG.Mul(xTargetG,xCurveInvG); for( i = 0; i < ptLocators.GetCount(); ++i ) { CVector3 vPos; vPos.Set( PLoc[3*i], PLoc[3*i+1], PLoc[3*i+2] ); vPos.MulByTransformationInPlace(xFromTargetToCurveG); xOutPoints[i] = vPos; } delete [] PLoc; outGeo.GetPoints().PutPositionArray(xOutPoints); // Let's keep the cache around for next time we are evaluated CacheVal = xTargetGeo.GetCache(); if( ! CacheVal.IsEmpty() ) { ctxt.PutUserData(CacheVal); } return CStatus::OK; }
CValue GetCache | ( | ) |
Returns the cache data currently used by the geometry.
The cache can be stored until a new instance of the same geometry is created at which time the new cache can be set using Geometry::PutCache. This saves the geometry from recreating all the internal data structures so that you don't lose any performance benefits.
CStatus GetBoundingBox | ( | double & | out_centerx, |
double & | out_centery, | ||
double & | out_centerz, | ||
double & | out_extentx, | ||
double & | out_extenty, | ||
double & | out_extentz, | ||
const MATH::CTransformation & | in_XfoObjectToBBoxSpace | ||
) | const |
Calculates and returns bounding box information
out_centerx | Returns the x coordinate of the center of the bounding box. |
out_centery | Returns the y coordinate of the center of the bounding box. |
out_centerz | Returns the z coordinate of the center of the bounding box. |
out_extentx | Returns the extent of the bounding box in the X axis. |
out_extenty | Returns the extent of the bounding box in the Y axis. |
out_extentz | Returns the extent of the bounding box in the Z axis. |
in_XfoObjectToBBoxSpace | Contains a transform (if desired) between the object and the global coordinate axes. This can be used to more tightly orient a bounding box around the object. |
CStatus GetBoundingSphere | ( | double & | out_centerx, |
double & | out_centery, | ||
double & | out_centerz, | ||
double & | out_radius, | ||
siVolumeCenterMethod | in_centerMethod, | ||
const MATH::CTransformation & | in_XfoObjectToBSphereSpace | ||
) |
Calculates and returns bounding sphere information
out_centerx | Returns the x coordinate of the center of the bounding sphere. |
out_centery | Returns the y coordinate of the center of the bounding sphere. |
out_centerz | Returns the z coordinate of the center of the bounding sphere. |
out_radius | Returns the radius of the bounding sphere. |
in_centerMethod | Specifies the technique used to calculate the center of the bounding sphere |
in_XfoObjectToBSphereSpace | Contains a transform (if desired) between the object and the global coordinate axes. This can be used to more tightly orient a bounding sphere around the object. |
CStatus GetBoundingCapsule | ( | double & | out_centerx, |
double & | out_centery, | ||
double & | out_centerz, | ||
double & | out_length, | ||
double & | out_radius, | ||
siVolumeCenterMethod | in_centerMethod, | ||
siBoundingCapsuleMethod | in_axisMethod, | ||
const MATH::CTransformation & | in_XfoObjectToBCapsuleSpace | ||
) |
Calculates and returns bounding capsule (swept sphere) information
out_centerx | Returns the x coordinate of the center of the bounding capsule. |
out_centery | Returns the y coordinate of the center of the bounding capsule. |
out_centerz | Returns the z coordinate of the center of the bounding capsule. |
out_length | Returns the length of the bounding capsule (not including the radii of the capping hemispheres). |
out_radius | Returns the cylindrical radius of the bounding capsule. |
in_centerMethod | Specifies the technique used to calculate the center of the bounding capsule |
in_axisMethod | Specifies the technique used to calculate the long axis of the bounding capsule |
in_XfoObjectToBCapsuleSpace | Contains a transform (if desired) between the object and the global coordinate axes. This can be used to more tightly orient a bounding capsule around the object |
CRefArray GetICEAttributes | ( | ) | const |
Returns all attributes defined for this geometry.
ICEAttribute GetICEAttributeFromName | ( | const CString & | in_name | ) | const |
Returns the attribute data matching a specific name as an ICEAttribute object.
in_name | Name of the attribute to find. |
CValue CreatePrim( const CString& in_presetobj, const CString& in_geometrytype, const CString& in_name, const CString& in_parent ); template < class T > class CICEAttributeDataLogger { public: static void Log( ICEAttribute& attr ) { CICEAttributeDataArray< T > data; attr.GetDataArray( data ); Application xsi; for( ULONG i=0; i<data.GetCount( ); i++ ) { xsi.LogMessage( CString( data[ i ] ) ); } } }; Application xsi; X3DObject grid = CreatePrim( L"Grid", L"MeshSurface", L"", L""); ICEAttribute attr = grid.GetActivePrimitive().GetGeometry().GetICEAttributeFromName( L"PointPosition" ); xsi.LogMessage( L"*******************************************************************" ); xsi.LogMessage( L"Name: " + attr.GetName() ); xsi.LogMessage( L"DataType: " + CString(attr.GetDataType()) ); xsi.LogMessage( L"StructType: " + CString(attr.GetStructureType()) ); xsi.LogMessage( L"ContextType: " + CString(attr.GetContextType()) ); xsi.LogMessage( L"IsConstant: " + CString(attr.IsConstant()) ); xsi.LogMessage( L"Readonly: " + CString(attr.IsReadonly()) ); xsi.LogMessage( L"Category: " + CString(attr.GetCategory()) ); xsi.LogMessage( L"Element count: " + CString(attr.GetElementCount()) ); CICEAttributeDataLogger<XSI::MATH::CVector3f>::Log( attr ); // Helper CValue CreatePrim( const CString& in_presetobj, const CString& in_geometrytype, const CString& in_name, const CString& in_parent ) { CValueArray args(4); CValue retval; args[0]= in_presetobj; args[1]= in_geometrytype; args[2]= in_name; args[3]= in_parent; Application app; app.ExecuteCommand( L"CreatePrim", args, retval ); return retval; }