Public Member Functions
Cluster Class Reference

## Detailed Description

A cluster represents a set of components on a Geometry.

For example, the polygons of the left arm of a human model might be grouped together by creating a cluster.

A cluster has a type (see SIObject::GetType) which corresponds to the component type that it contains, (`pnt`, `knot`, `poly`). A geometry can have multiple clusters, including clusters of different types. Any particular component might be included in multiple clusters. The ::ClusterTypes that are supported on a geometry depend on the type of object. For example only NurbsSurface or NurbsCurve can have a siKnotCluster.

Clusters can be created on the geometry of a ParticleCloud. These clusters are of type siVertexCluster but they contain Particles.

A cluster that includes all the components of a particular type is said to be always complete, which you can verify with Cluster::IsAlwaysComplete. An always-complete cluster always covers all components of the geometry, even when components are added by a modeling operation; however, notice that a cluster which covers all components of a geometry is not necessarily always-complete. Other clusters may contain a subset of components. In all cases the indices of the components in the cluster do not directly match the indices of the component on the geometry. The mapping between cluster indices and geometry indices is available through Cluster::GetElements and Cluster::FindIndices.

Clusters are useful for storing per-component data with a ClusterProperty or UserDataMap. Clusters can also have their own CustomProperty objects. All these properties can be created with SceneItem::AddProperty and enumerated with SceneItem::GetLocalProperties. Notice that some types of ClusterProperty require the cluster to be always complete.

Warning:
  Operations that change the geometry, for example adding an edge to a mesh, can result in the cluster growing or shrinking.

Note:
  As of v5.0, the base property SIObject::GetParent called on a Cluster object returns a Primitive instead of an X3DObject.

See also:
  Geometry, CClusterElementArray

Example:

            using namespace XSI;
            Application app;
            Model root = app.GetActiveSceneRoot();

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

            Cluster myCls;
            CLongArray indices(9);
            indices[0] = 8; indices[1] = 16; indices[2] = 24; indices[3] = 32;
            indices[4] = 40; indices[5] = 48; indices[6] = 56; indices[7] = 64;
            indices[8] = 72;

            myGrid.GetActivePrimitive().GetGeometry().AddCluster(siVertexCluster, L"",
                indices, myCls );

            app.LogMessage( L"Cluster type: " + myCls.GetClassIDName() );

`#include <xsi_cluster.h>`

Inheritance diagram for Cluster:
[legend]

List of all members.

## Public Member Functions
| Cluster ()
| ~Cluster ()
| Cluster (const CRef &in_ref)
| Cluster (const Cluster &in_obj)
bool | IsA (siClassID in_ClassID) const
siClassID | GetClassID () const
Cluster & | operator= (const Cluster &in_obj)
Cluster & | operator= (const CRef &in_ref)
CClusterElementArray | GetElements () const
X3DObject | GetCenterReference () const
CStatus | PutCenterReference (const X3DObject &in_centerObj)
bool | HasStaticKinematicState () const
CRefArray | GetStaticKinematicStates () const
SubComponent | CreateSubComponent ()
CStatus | FindIndex (LONG in_geometryIndex, LONG &out_clusterIndex) const
CStatus | FindIndices (const CLongArray &in_geometryIndices, CLongArray &out_clusterIndices) const
bool | IsAlwaysComplete () const
CStatus | GetGeometryElementFlags (CBitArray &out_flags) const

## Constructor & Destructor Documentation

Cluster | ( |  | ) |

Default constructor.

~Cluster | ( |  | ) |

Default destructor.

Cluster | ( | const CRef & | in_ref | ) |

Constructor.

Parameters:

  in_ref | constant reference object.

Cluster | ( | const Cluster & | in_obj | ) |

Copy constructor.

Parameters:

  in_obj | constant class 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 SceneItem.

siClassID GetClassID | ( |  | ) | const `[virtual]`

Returns the type of the API class.

Returns:
  The class type.

Reimplemented from SceneItem.

Cluster& operator= | ( | const Cluster & | 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 Cluster object.

Cluster& 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 Cluster object.

Reimplemented from SceneItem.

CClusterElementArray GetElements | ( |  | ) | const

Returns an array of geometry indices represented by the cluster.

Returns:
  The new CClusterElementArray object.

X3DObject GetCenterReference | ( |  | ) | const

Returns the cluster center reference.

Returns:
  The cluster reference object.

CStatus PutCenterReference | ( | const X3DObject & | in_centerObj | ) |

Sets the cluster center reference. If the reference is empty, the ClusterCenter operator is deleted.

Parameters:

  in_centerObj | Object to be used as the center reference.

Returns:
  CStatus::OK success
  CStatus::Fail failure

bool HasStaticKinematicState | ( |  | ) | const

Returns true if the cluster has a base pose. The base pose is represented by a StaticKinematicState property.

Returns:
  True if the cluster has a base pose, false otherwise.

CRefArray GetStaticKinematicStates | ( |  | ) | const

Returns an array containing all StaticKinematicState properties on the cluster.

Returns:
  Array of references to StaticKinematicState properties.

SubComponent CreateSubComponent | ( |  | ) |

Creates a SubComponent from the cluster type.

Returns:
  A SubComponent object.

CStatus FindIndex | ( | LONG | in_geometryIndex,
|  | LONG & | out_clusterIndex
| ) |  | const

Returns the cluster index corresponding to the specified geometry component index.

Parameters:

  in_geometryIndex | Geometry component index.

Return values:

  out_clusterIndex | Cluster index corresponding to the geometry index or -1 if the geometry index is not part of the cluster.

Returns:
  CStatus::OK success
  CStatus::Fail failure

CStatus FindIndices | ( | const CLongArray & | in_geometryIndices,
|  | CLongArray & | out_clusterIndices
| ) |  | const

Returns the cluster indices corresponding to the specified geometry component indices.

Parameters:

  in_geometryIndices | Array of geometry component indices.

Return values:

  out_clusterIndices | Array of cluster indices corresponding to the geometry indices or -1 if the geometry index is not part of the cluster.

Returns:
  CStatus::OK success
  CStatus::Fail failure

Example:

            using namespace XSI;
            Application app;
            Model root = app.GetActiveSceneRoot();

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

            CLongArray indices(3);
            indices[0] = 0; indices[1] = 3; indices[2] = 22;

            Geometry myMesh(myGrid.GetActivePrimitive().GetGeometry());
            Cluster myCls;
            myMesh.AddCluster(siVertexCluster, L"", indices, myCls );

            Facet myFacet(myMesh.GetFacets().GetItem(0));
            CLongArray aPointIndices = myFacet.GetPoints().GetIndexArray();

            CLongArray aClusterIndices;
            myCls.FindIndices(aPointIndices, aClusterIndices);

            for (LONG i=0; i<(LONG)aClusterIndices.GetCount(); ++i)
            {
                if ( aClusterIndices[i] == -1 )
                    app.LogMessage( L"The point index " +
                                    CValue(aPointIndices[i]).GetAsText() +
                                    L" is not part of the cluster.");
                else
                    app.LogMessage(L"Cluster index for point index " +
                        CValue(aPointIndices[i]).GetAsText() + L"= " +
                        CValue(aClusterIndices[i]).GetAsText());
            }

bool IsAlwaysComplete | ( |  | ) | const

Returns true if the cluster is maintained as always complete. If so, the cluster will always cover all geometry's components even under modeling operations.

Returns:
  True if the cluster is always complete, false otherwise.

Since:
  5.0

CStatus GetGeometryElementFlags | ( | CBitArray & | out_flags | ) | const

Returns an array of flags containing the geometry elements set on this cluster. The array size matches the number of elements on the geometry for this cluster type. A true flag indicates a cluster element, the position of the flag in the array corresponds to the cluster element.

If the cluster was generated by an instance of CGeometryAccessor initialized with a subdivision level > 0, the array matches the number of subdivided elements on the underlying geometry.

Note:
  This function will only work for clusters defined on a polygon mesh geometry.

Return values:

  out_flags | The element flags for this cluster

Returns:
  CStatus::OK success
  CStatus::False No elements defined on the cluster
  CStatus::Fail Error

See also:
  CGeometryAccessor, CClusterPropertyBuilder

Since:
  5.0

Example:

            using namespace XSI;
            Application app;
            Model root = app.GetActiveSceneRoot();

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

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

            CClusterPropertyBuilder cpBuilder = myMesh.GetClusterPropertyBuilder();

            // add a vertex color property on the geometry, this creates a complete node
            // cluster on the geometry
            ClusterProperty color = cpBuilder.AddVertexColor();

            // add a weight map property on the geometry, this creates an empty vertex
            // cluster
            ClusterProperty wmap = cpBuilder.AddWeightMap(false);

            // set the color vertex values
            LONG indices[] = {0, 3, 22};

            float colors[] =
            {
                1.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f,
                0.0f, 0.0f, 1.0f
            };

            color.SetValues( indices, colors, 3 );

            // set the weight map values
            float weights[] = { 1.0f, 0.5f, 0.75f };

            wmap.SetValues( indices, weights, 3 );

            // get a geometry accessor initialized with a subdivision level of 1
            CGeometryAccessor ga = myMesh.GetGeometryAccessor(siConstructionModeModeling, siCatmullClark, 1);

            // get the node and vertex clusters created with CClusterPropertyBuilder
            CRefArray clusters = ga.GetAllClusters();

            // log the clusters element ids
            for (LONG i=0; i<clusters.GetCount(); i++)
            {
                Cluster cls = clusters[i];

                CBitArray flags;
                CStatus st = cls.GetGeometryElementFlags( flags );
                st.AssertSucceeded();

                app.LogMessage( L"Cluster name: " + cls.GetName() );
                app.LogMessage( L"Nb geometry elements: " + CString(flags.GetCount()) );
                app.LogMessage( L"Nb cluster elements: " + CString(flags.GetTrueCount()) );

                LONG idx = flags.GetIterator();
                while( flags.GetNextTrueBit( idx ) )
                {
                    app.LogMessage( CString(idx) + L":" + CString( flags[idx] ) );
                }
            }

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

- xsi_cluster.h