Public Types | Public Member Functions
CICEGeometry Class Reference

## Detailed Description

Provides a read-only API for accessing the data of a geometry object connected to a custom ICE node.

dirty states:checking for geometry changes The following geometry types are supported:

- CICEGeometry::siMeshSurfaceType: mesh surface.
- CICEGeometry::siNurbsSurfaceType: nurbs surface.
- CICEGeometry::siNurbsCurveType: nurbs curve.
- CICEGeometry::siPointCloudType: point cloud.
- CICEGeometry::siGroupType: grouped geometries.

This API can handle single geometries or a composite of multiple, or grouped, geometries. For grouped geometries, CICEGeometry virtually unifies the sub-geometries as one single geometry which allows data to be accessed as if it were actually a single geometry. For instance, calling CICEGeometry::GetPointPositionCount on a grouped geometry returns the total number of points for all sub-geometries.

Note:
  Geometries can be grouped together with the GroupGeometryNode or by adding them to a Group in the Softimage scene.

CICEGeometry is typically used in the cb_ICENode_BeginEvaluate BeginEvaluate callback but can also be used in all custom cb_icenodes ICENode evaluation callbacks . However, it cannot be used from an cb_ICENode_Evaluate Evaluate callback in multi-thread mode with a non-singleton context. Calls to CICEGeometry methods will just return default values in this context. Also, CICEGeometry can only be used with specific geometry ports defined with the following types:

- type: siICENodeDataGeometry
- structure: siICENodeStructureSingle
- context: siICENodeContextSingleton

The CICEGeometry class can also be used to interrogate connected geometries about their states. The states supported are:

- CICEGeometry::siTransformationDirtyState: This state is true when the transformation of the geometry has been changed (translation, rotation or scaling).
- CICEGeometry::siPointPositionDirtyState: This state is true when the point position of the geometry has been changed.
- CICEGeometry::siTopologyDirtyState: This state is true when the topology of the geometry has been changed. When `siTopologyDirtyState` is true, it implies that `siPointPositionDirtyState` is also true.
- CICEGeometry::siGeometryTypeDirtyState: This state is true when the type of geometry has been changed. When this state is true all other states are also true.

CICEGeometry only supports geometry-centric states. Use CICEPortState to query for the low-level port states of connected geometries.

Note:
  CICEGeometry::siAnyDirtyState can be used to test if at least one state is dirty.

Since:
  8.0 (2010)

Example:
  Simple example to demonstrate the CICEGeometry API. For a more detailed example see the CustomICENodes/netview_CustomICENodes PointGeneratorFromGeometry custom ICE node example

          XSIPLUGINCALLBACK CStatus Sample_RegisterNode( ICENodeContext& in_ctxt )
          {
              ICENodeDef nodeDef = Application().GetFactory().CreateICENodeDef(L"Sample",L"Sample");

              nodeDef.AddInputPort(   ID_IN_GeometryPortID, ID_G_100,
                                      siICENodeDataGeometry,siICENodeStructureSingle,siICENodeContextSingleton,
                                      L"geometry input", L"geometry input" );

              // Rest of the code omitted for brievity ...

              return CStatus::OK;
          }

          XSIPLUGINCALLBACK CStatus Sample_BeginEvaluate( ICENodeContext& in_ctxt )
          {
              CICEGeometry geom( in_ctxt, ID_IN_GeometryPortID  );

              // Geometry data are provided as a flat list of values
              CDoubleArray points;
              geom.GetPointPositions( points ) ;

              XSI::MATH::CMatrix4f transfo;
              geom.GetTransformation( transfo );

              std::vector< MATH::CVector3f >* pUserData = new std::vector< MATH::CVector3f >;

              ULONG nCount = geom.GetPolygonCount();

              CLongArray sizes;   // sizes holds the number of points per polygon
              CLongArray indices; // indices holds the polygon indices and are used for indexing the point values
              geom.GetPolygonIndices( sizes, indices );

              // Compute the center point of all polygons and save the result in a user data.
              ULONG nOffset = 0;
              for (ULONG i=0; i<nCount; i++)
              {
                  MATH::CVector3f vTotal;
                  for (ULONG j=0; j<(ULONG)sizes[i]; j++, nOffset++)
                  {
                      MATH::CVector3f v(  (float)points[ indices[nOffset]*3 ],
                                          (float)points[ indices[nOffset]*3+1 ],
                                          (float)points[ indices[nOffset]*3+2 ] );
                      vTotal += v;
                  }

                  vTotal *= 1.0f/sizes[i];

                  // The points are relative to the geometry and must be converted to global coordinates.
                  vTotal.MulByMatrix4InPlace( transfo );
                  pUserData->push_back( vTotal );
              }

              return CStatus::OK;
          }

          XSIPLUGINCALLBACK CStatus Sample_Evaluate( ICENodeContext& in_ctxt )
          {
              ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( );

              switch( out_portID )
              {
                  case ID_OUT_Sample_Points:
                  {
                      // Retrieve the points computed in Sample_BeginEvaluate
                      std::vector<MATH::CVector3f>* pUserData = (std::vector<MATH::CVector3f>*)(CValue::siPtrType)in_ctxt.GetUserData( );

                      CDataArrayVector3f outData( in_ctxt );

                      CIndexSet indexSet( in_ctxt );
                      for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
                      {
                          // Note: The output buffer is relative to the 'batch' data therefore the batch can be
                          // indexed with the iterator directly. As for the user data vector, pUSerData must be
                          // indexed with the 'batch' global index i.e. CIndexSet::Iterator::GetAbsoluteIndex()
                          outData[it] = (*pUserData)[ it.GetAbsoluteIndex() ];
                      }
                  }
                  break;
              };

              return CStatus::OK;
          }

          XSIPLUGINCALLBACK CStatus Sample_EndEvaluate( ICENodeContext& in_ctxt )
          {
              // Release the memory allocated for the user data

              CValue userData = in_ctxt.GetUserData( );
              if (userData.IsEmpty())
              {
                  return CStatus::OK;
              }

              std::vector<MATH::CVector3f>* pUserData = (std::vector<MATH::CVector3f>*)(CValue::siPtrType)userData;

              if (pUserData)
                  delete pUserData;

              in_ctxt.PutUserData( CValue() );

              return CStatus::OK;
          }

Example:
  Example to demonstrate querying the geometry states on geometries connected to a custom node. For a more detailed example see the CustomICENodes/netview_CustomICENodes PortStateObserver custom ICE node example.

          static void _LogGeometryStates( CICEGeometry& in_geom, const CString& in_portName, double in_dCurrentFrame, bool in_bClearState )
          {
              if ( in_geom.IsDirty( CICEGeometry::siAnyDirtyState ) )
              {
                  bool bTypeDirtyState = in_geom.IsDirty( CICEGeometry::siGeometryTypeDirtyState );
                  bool bTransfoDirtyState = in_geom.IsDirty( CICEGeometry::siTransformationDirtyState );
                  bool bPointsDirtyState = in_geom.IsDirty( CICEGeometry::siPointPositionDirtyState );
                  bool bTopologyDirtyState = in_geom.IsDirty( CICEGeometry::siTopologyDirtyState );

                  if ( in_bClearState )
                  {
                      in_geom.ClearState();
                  }

                  Application app;

                  // Don't log redundant information:
                  // bTypeDirtyState always implies bTransfoDirtyState + bPointsDirtyState + bTopologyDirtyState
                  // bTopologyDirtyState always implies bPointsDirtyState

                  if ( bTypeDirtyState)
                  {
                      app.LogMessage( ">>> Port " + in_portName + " siGeometryTypeDirtyState at frame " + CString(in_dCurrentFrame) + " is dirty" );
                  }
                  else
                  {
                      if ( bTransfoDirtyState)
                      {
                          app.LogMessage( ">>> Port " + in_portName + " siTransformationDirtyState at frame " + CString(in_dCurrentFrame) + " is dirty" );
                      }

                      if ( bTopologyDirtyState)
                      {
                          app.LogMessage( ">>> Port " + in_portName + " siTopologyDirtyState at frame " + CString(in_dCurrentFrame) + " is dirty" );
                      }
                      else if ( bPointsDirtyState)
                      {
                          app.LogMessage( ">>> Port " + in_portName + " siPointPositionDirtyState at frame " + CString(in_dCurrentFrame) + " is dirty" );
                      }
                  }
              }
          }

          static void LogGeometryStates( CICEGeometry& in_geom, const CString& in_portName, double in_dCurrentFrame )
          {
              CICEGeometry::Type geomtype = in_geom.GetGeometryType();
              switch( geomtype )
              {
                  case CICEGeometry::siGroupType:
                  {
                      // Note: ClearState on sub-geometries will clear the states for the entire group geometry. It's
                      // recommended to call ClearState only on the group geometry to avoid inconsistencies.
                      _LogGeometryStates( in_geom, in_portName, in_dCurrentFrame, false );

                      for (ULONG i=0; i<in_geom.GetSubGeometryCount(); i++)
                      {
                          CICEGeometry subgeom = in_geom.GetSubGeometry(i);
                          _LogGeometryStates( subgeom, in_portName + CString(i), in_dCurrentFrame, false );
                      }
                      in_geom.ClearState();
                  }
                  break;

                  default:
                  {
                      _LogGeometryStates( in_geom, in_portName, in_dCurrentFrame, true );
                  }
              }
          }

          XSIPLUGINCALLBACK CStatus Port_State_Observer_BeginEvaluate( ICENodeContext& in_ctxt )
          {
              CICEGeometry geomGroup( in_ctxt, ID_IN_GeometryGroup );
              CICEGeometry geomCurve( in_ctxt, ID_IN_NurbsCurve );
              CICEGeometry geomMesh( in_ctxt, ID_IN_MeshSurf );
              CICEGeometry geomNurbsSurf( in_ctxt, ID_IN_NurbsSurf );
              CICEGeometry geomCloud( in_ctxt, ID_IN_PointCloud );

              double dCurrentFrame = in_ctxt.GetTime();
              LogGeometryStates( geomGroup, L"GeometryGroup", dCurrentFrame );
              LogGeometryStates( geomCurve, L"NurbsCurve", dCurrentFrame );
              LogGeometryStates( geomMesh, L"MeshSurf", dCurrentFrame );
              LogGeometryStates( geomNurbsSurf, L"NurbsSurf", dCurrentFrame );
              LogGeometryStates( geomCloud, L"PointCloud", dCurrentFrame );

              return CStatus::OK;
          }

`#include <xsi_icegeometry.h>`

List of all members.

## Public Types
enum | Type { siNoneType = 0, siGroupType = 1, siMeshSurfaceType = 2, siNurbsSurfaceType = 3, siNurbsCurveType = 4, siPointCloudType = 5 }
enum | DirtyState { siGeometryTypeDirtyState = 1<<0, siTransformationDirtyState = 1<<1, siPointPositionDirtyState = 1<<2, siTopologyDirtyState = 1<<3, siAnyDirtyState }
## Public Member Functions
| CICEGeometry (ICENodeContext &in_ctxt, ULONG in_nInputPortID, ULONG in_nInstanceIndex=0)
| CICEGeometry (const CICEGeometry &in_geom)
| CICEGeometry ()
| ~CICEGeometry ()
bool | IsValid () const
Type | GetGeometryType () const
bool | operator== (const CICEGeometry &in_geom) const
bool | operator!= (const CICEGeometry &in_geom) const
CICEGeometry & | operator= (const CICEGeometry &in_geom)
ULONG | GetSubGeometryCount () const
CICEGeometry | GetSubGeometry (ULONG in_index) const
ULONG | GetPointPositionCount () const
CStatus | GetPointPositions (CDoubleArray &out_points) const
ULONG | GetTriangleCount () const
CStatus | GetTrianglePointIndices (CLongArray &out_indices) const
ULONG | GetPolygonCount () const
CStatus | GetPolygonIndices (CLongArray &out_sizes, CLongArray &out_indices) const
ULONG | GetSegmentCount () const
CStatus | GetSegmentIndices (CLongArray &out_indices) const
CStatus | GetTransformation (XSI::MATH::CMatrix4f &out_mat44) const
bool | IsDirty (unsigned short in_flag=siAnyDirtyState) const
void | ClearState ()

## Member Enumeration Documentation

enum Type

Defines the geometry types supported by CICEGeometry.

Enumerator:

  siNoneType | No geometry
  siGroupType | Group of geometries
  siMeshSurfaceType | Mesh surface geometry
  siNurbsSurfaceType | Nurbs surface geometry
  siNurbsCurveType | Nurbs curve geometry
  siPointCloudType | Point cloud geometry

enum DirtyState

Defines the supported dirty geometry state types.

Enumerator:

  siGeometryTypeDirtyState | This state is true when the type of geometry has been changed. When this state is true all other states are also true.
  siTransformationDirtyState | This state is true when the transformation of the geometry has been changed (translation, rotation or scaling).
  siPointPositionDirtyState | This state is true when the point position of the geometry has been changed.
  siTopologyDirtyState | This state is true when the topology of the geometry has been changed. When `siTopologyDirtyState` is true, it implies that `siPointPositionDirtyState` is also true.
  siAnyDirtyState | This state is true if any one of the states have changed.

## Constructor & Destructor Documentation

CICEGeometry | ( | ICENodeContext & | in_ctxt,
|  | ULONG | in_nInputPortID,
|  | ULONG | in_nInstanceIndex = `0`
| ) |  |

Constructor for creating and initializing an instance of CICEGeometry.

Parameters:

  in_ctxt | ICENode evaluation context.
  in_nInputPortID | Input port identifier.
  in_nInstanceIndex | The group instance of the port. Defaults to `0`.

CICEGeometry | ( | const CICEGeometry & | in_geom | ) |

Copy Constructor.

CICEGeometry | ( |  | ) |

Default Constructor. Creates an invalid CICEGeometry object of type Type::siNoneType.

~CICEGeometry | ( |  | ) |

Destructor.

## Member Function Documentation

bool IsValid | ( |  | ) | const

Returns true if the object is valid. Unless the object is not set properly, IsValid always return true. IsValid cannot be used to detect if a geometry is connected or not. The rational behind is that it's not guaranteed that all connected geometries have data, therefore having geometries always set as valid allows users to write generic code. For instance, unconnected geometries, empty polygon geometries and empty point clouds will all return 0 for CICEGeometry::GetPointPositionCount.

In general it's not recommended for a custom node to check for valid port connections. For instance, a custom node could be connected to a passthrough node which could be potentially not connected to any node. If you want to optimize things based on the port state then it is recommended to use the CICEPortState class and perform actions based on specific notifications.

Returns:
  True if valid, false otherwise.

Type GetGeometryType | ( |  | ) | const

Returns the geometry type. The type is set to Type::siNoneType when the object is not properly defined.

Returns:
  The geometry type.

bool operator== | ( | const CICEGeometry & | in_geom | ) | const

Equality operator. Tests if two geometries are the same; the function is just comparing the internal pointer objects.

Parameters:

  in_geom | CICEGeometry instance to compare to this instance.

Returns:
  true if both geometries are he same, false if different.

bool operator!= | ( | const CICEGeometry & | in_geom | ) | const

Inequality operator. Tests whether two geometries are different; the function is just comparing the internal pointer objects.

Parameters:

  in_geom | CICEGeometry instance to compare to this instance.

Returns:
  true if both geometries are different, false otherwise.

CICEGeometry& operator= | ( | const CICEGeometry & | in_geom | ) |

Assignment operator. Assign this geometry to another geometry. This operation is a simple object assignment. The content of the geometry is not duplicated.

Parameters:

  in_geom | CICEGeometry object to assign.

Returns:
  A reference to new CICEGeometry.

ULONG GetSubGeometryCount | ( |  | ) | const

Returns the number of sub-geometries contained by this geometry.

Returns:
  Number of sub-geometries.

CICEGeometry GetSubGeometry | ( | ULONG | in_index | ) | const

Returns the sub-geometry at the position identified by `in_index`. The CICEGeometry instance returned is invalid if `in_index` is out of bounds.

Returns:
  CICEGeometry instance.

ULONG GetPointPositionCount | ( |  | ) | const

Returns the number of point positions on the current geometry.

Returns:
  Number of point positions.

CStatus GetPointPositions | ( | CDoubleArray & | out_points | ) | const

Returns an array of double values containing the point positions (`xyz`) of the entire geometry. The positions are stored as a flat list and can be indexed using the indices returned by CICEGeometry::GetPolygonIndices, CICEGeometry::GetTrianglePointIndices or CICEGeometry::GetSegmentIndices.

The array is formatted as:

     {x0,y0,z0, ... xN,yN,zN}

Return values:

  out_points | Array of point positions.

Returns:
  CStatus::OK Success.
  CStatus::AccessDenied Object is invalid or method called from invalid context.

Example:
  Example to demonstrate how to access the points of a geometry.

          CICEGeometry geom( in_ctxt, ID_IN_geometry );

          CDoubleArray points;
          geom.GetPointPositions( points ) ;

          ULONG nCount = geom.GetPolygonCount();

          CLongArray sizes;
          CLongArray indices;
          geom.GetPolygonIndices( sizes, indices );

          ULONG nOffset = 0;
          std::vector< MATH::CVector3f > v3fArray;
          for (ULONG i=0; i<nCount; i++)
          {
              for (ULONG j=0; j<(ULONG)sizes[i]; j++, nOffset++)
              {
                  MATH::CVector3f v(  (float)points[ indices[nOffset]*3 ],
                                      (float)points[ indices[nOffset]*3+1 ],
                                      (float)points[ indices[nOffset]*3+2 ] );
                  v3fArray.push_back( v );
              }
          }

ULONG GetTriangleCount | ( |  | ) | const

Returns the number of triangles in the geometry.

Returns:
  Triangle count.

CStatus GetTrianglePointIndices | ( | CLongArray & | out_indices | ) | const

Returns an array containing the point indices for each triangulated polygon. The point indices are stored in the array as a flat list of values grouped in triplets, the first triplet being the points of triangle `0`, etc. The triangle indices are numbered based on the order of creation of the triangles.

The array is formatted as:

     {t0<p0,p1,p2>, t1<p0,p1,p2>... tN<p0,p1,p2>}

Note:
  This method performs a triangulation of the current geometry before returning the data.

Return values:

  out_indices | Array of triangle point indices.

Returns:
  CStatus::OK Success.
  CStatus::AccessDenied Object is invalid or method called from invalid context.

Example:
  Example to demonstrate how to access the triangle points of a geometry.

          CICEGeometry geom( in_ctxt, ID_IN_geometry );

          CDoubleArray points;
          geom.GetPointPositions( points ) ;

          ULONG nCount = geom.GetTriangleCount();

          CLongArray indices;
          geom.GetTrianglePointIndices( indices );

          ULONG nOffset = 0;
          std::vector< MATH::CVector3f > v3fArray;
          for (ULONG i=0; i<nCount; i++)
          {
              for (ULONG j=0; j<3; j++, nOffset++)
              {
                  MATH::CVector3f v(  (float)points[ indices[nOffset]*3 ],
                                      (float)points[ indices[nOffset]*3+1 ],
                                      (float)points[ indices[nOffset]*3+2 ] );
                  v3fArray.push_back( v );
              }
          }

ULONG GetPolygonCount | ( |  | ) | const

Returns the number of polygons of the geometry.

Returns:
  Polygon count.

CStatus GetPolygonIndices | ( | CLongArray & | out_sizes,
|  | CLongArray & | out_indices
| ) |  | const

Returns the size and point indices for all polygons on the geometry.

Return values:

  out_sizes | Array containing the point count for each polygon.
  out_indices | Array containing the point indices for each Polygon. The vertices are stored as a flat list and ordered by polygons, the first group being the points for polygon `0`, etc. The array is formatted as:
       {poly0<v0,v1..vN>, poly1<v0,v1..vN>... polyN<v0,v1..vN>}

Returns:
  CStatus::OK Success.
  CStatus::AccessDenied Object is invalid or method called from invalid context.

Example:
  Example to demonstrate how to access the polygon points of a geometry.

          CICEGeometry geom( in_ctxt, ID_IN_geometry );

          CDoubleArray points;
          geom.GetPointPositions( points ) ;

          ULONG nCount = geom.GetPolygonCount();

          CLongArray sizes;
          CLongArray indices;
          geom.GetPolygonIndices( sizes, indices );

          ULONG nOffset = 0;
          std::vector< MATH::CVector3f > v3fArray;
          for (ULONG i=0; i<nCount; i++)
          {
              for (ULONG j=0; j<(ULONG)sizes[i]; j++, nOffset++)
              {
                  MATH::CVector3f v(  (float)points[ indices[nOffset]*3 ],
                                      (float)points[ indices[nOffset]*3+1 ],
                                      (float)points[ indices[nOffset]*3+2 ] );
                  v3fArray.push_back( v );
              }
          }

ULONG GetSegmentCount | ( |  | ) | const

Returns the number of segments for the geometry. Segment is a generic term to describe 1D geometry components such as edges for mesh surfaces and control points for nurbs surfaces.

Returns:
  Segment count.

CStatus GetSegmentIndices | ( | CLongArray & | out_indices | ) | const

Returns an array of segment indices. Segment is a generic term to describe 1D geometry components such as edges for mesh surfaces and control points for nurbs surfaces. The array contains a sequence of pairs describing the segment indices:

     {s0<id0,id1>, ...sN<id0,id1>}

The indices can be used with CICEGeometry::GetPointPositions to get the segment points.

Return values:

  out_indices | Array of edge indices.

Returns:
  CStatus::OK Succeeded.
  CStatus::AccessDenied Object is invalid or method called from invalid context.

Example:
  Example to demonstrate how to access the segment points of a geometry.

          CICEGeometry geom( in_ctxt, ID_IN_geometry );

          CDoubleArray points;
          geom.GetPointPositions( points ) ;

          ULONG nCount = geom.GetSegmentCount();

          CLongArray indices;
          geom.GetSegmentIndices( sizes, indices );

          ULONG nOffset = 0;
          std::vector< MATH::CVector3f > v3fArray;
          for (ULONG i=0; i<nCount; i++)
          {
              for (ULONG j=0; j<2; j++, nOffset++)
              {
                  MATH::CVector3f v(  (float)points[ indices[nOffset]*3 ],
                                      (float)points[ indices[nOffset]*3+1 ],
                                      (float)points[ indices[nOffset]*3+2 ] );
                  v3fArray.push_back( v );
              }
          }

CStatus GetTransformation | ( | XSI::MATH::CMatrix4f & | out_mat44 | ) | const

Returns the global transformation matrix of this geometry.

Note:
  Geometry points are returned in local coordinates; use the geometry transformation matrix to convert the points to global coordinates.

Return values:

  out_mat44 | Transformation matrix.

Returns:
  CStatus::OK Succeeded.
  CStatus::AccessDenied Object is invalid or method called from invalid context.

bool IsDirty | ( | unsigned short | in_flag = `siAnyDirtyState` | ) | const

Returns the dirty state of this geometry for a given state type as defined in the CICEGeometry::DirtyState enumerator. By default, IsDirty returns true if at least one of the geometry states is dirty.

Note:
  Changing the transformation on a sub-geometry object will force a CICEGeometry::siPointPositionDirtyState change on the grouped geometry. However, no CICEGeometry::siTransformationDirtyState will be generated for the group geometry.

Parameters:

  in_flag | State type.

Returns:
  true if the object is dirty, false otherwise.

void ClearState | ( |  | ) |

Clears the geometry states.

Note:
  ClearState on sub-geometries will clear the states for the entire group geometry. It is recommended to call ClearState only on the group geometry to avoid inconsistencies.

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

- xsi_icegeometry.h