## ClusterProperty

Object Hierarchy | Related C++ Class: ClusterProperty

### Inheritance

SIObject

ProjectItem

Property

ClusterProperty

### Description

A property of a Cluster that stores separate data for each component of the cluster.
The data type of the value stored for each component is an Array of Doubles. The size depends on the type of the cluster property. Size of a weight map is 1. Size of a UV property is 3 (UVW). Size of a Shape Animation property is 3 (XYZ). Size of a vertex color property is 4 (RGBA). Size of an envelope weight property is equal to the number of deformers Size of a User Motion property is 3 (XYZ).
The values contained by the cluster property can be accessed via the ClusterProperty.Elements. You can access the entire 2-dimensional value array using ClusterElementCollection.Array or individual values via ClusterElementCollection.ItemsByIndex. The data type of the value returned by ClusterElementCollection.ItemsByIndex is always an Array.
Use the SceneItem.LocalProperties property to find ClusterProperties on a Cluster.
Notice that some cluster property types can only be added to Cluster objects that are always-complete (see Cluster.IsAlwaysComplete). These types are vertex color, uv, symmetry map and user motion properties.

### Methods

AddCustomOp | AddICEAttribute | AddScriptedOp | AddScriptedOpFromFile
AnimatedParameters2 | BelongsTo | EvaluateAt | GetICEAttributeFromName
IsA | IsAnimated2 | IsClassOf | IsEqualTo
IsKindOf | IsLocked | IsSelected | LockOwners
RemoveICEAttribute | SetAsSelected | SetCapabilityFlag | SetLock
TaggedParameters | UnSetLock |  |

### Properties

Application | Branch | BranchFlag | Capabilities
Categories | Elements | EvaluationID | Families
FullName | Help | HierarchicalEvaluationID | ICEAttributes
LockLevel | LockMasters | LockType | Model
Name | NestedObjects | ObjectID | Origin
OriginPath | Owners | PPGLayout | Parameters
Parent | Parent3DObject | Selected | Singleton
Type |  |  |

### Examples

#### 1. JScript Example

    //JScript example showing how to read UV values in a
    //UV Cluster Property
    var oRoot = Application.ActiveProject.ActiveScene.Root;
    var oObject = oRoot.AddGeometry( "Cube", "MeshSurface" );
    BlendInPresets( "Image", oObject, 1, false );
    CreateTextureSupport( oObject, siTxtUV, siTxtDefaultSpherical, "Texture_Support" );
    SetInstanceDataValue(null, "cube.Scene_Material.UV", "Texture_Support");
    var oUVWProp = oObject.Material.CurrentUV;
    // Output the first 5 UV text coords
    var vbaUVW = new VBArray(oUVWProp.Elements.Array);
    // Use this to map from index in the Cluster back to index in the Geometry
    // If the cluster is not complete or if topology changes are done then
    // the geometry index is not necessarily the same as the cluster index
    var vbaClusterElement = new VBArray(oUVWProp.Parent.Elements.Array);
    for ( iIndex = 0; iIndex < 4; iIndex++ )
    {
                    logmessage ( "Sample(" + vbaClusterElement.getItem(iIndex) + ") = UV(" +
                               vbaUVW.getItem(0,iIndex) + "," + vbaUVW.getItem(1,iIndex) + ")"  ) ;
    }
    //INFO : "Sample(0) = UV(0.125,0.30408671498298645)"
    //INFO : "Sample(1) = UV(0.125,0.6959132552146912)"
    //INFO : "Sample(2) = UV(-0.125,0.6959132552146912)"
    //INFO : "Sample(3) = UV(-0.125,0.30408671498298645)"

#### 2. VBScript Example

    'VBScript example showing how to read UV values in a
    'UV Cluster Property
    set oRoot = application.activeproject.activescene.root
    set oObject = oRoot.addgeometry( "Cube", "MeshSurface" )
    BlendInPresets "Image", oObject, 1, False
    CreateTextureSupport oObject, siTxtUV, siTxtDefaultSpherical, "Texture_Support"
    SetInstanceDataValue , oObject & ".Scene_Material.UV", "Texture_Support"
    set oUVWProp = oObject.Material.CurrentUV
    ' output uv text coords
    aUVW=oUVWProp.elements.array
    'Use this to map from index in the Cluster back to index in the Geometry
    'If the cluster is not complete or if topology changes are done then
    'the geometry index is not necessarily the same as the cluster index
    aClusterIndices = oUVWProp.Parent.elements.array
    ' Print out just the first few elements
    for iIndex=0 to 3
            logmessage "Sample(" & aClusterIndices(iIndex) & ") = UV(" & _
                       aUVW(0,iIndex) & "," & aUVW(1,iIndex) & ")"
    next
    'Result of running this script:
    'INFO : "Sample(0) = UV(0.125,0.304086714982986)"
    'INFO : "Sample(1) = UV(0.125,0.695913255214691)"
    'INFO : "Sample(2) = UV(-0.125,0.695913255214691)"
    'INFO : "Sample(3) = UV(-0.125,0.304086714982986)"

#### 3. VBScript Example

    ' VBScript example showing how to find the
    ' texture projection UV values associated
    ' with each vertex of a polygon
    set oRoot = application.activeproject.activescene.root
    set oObject = oRoot.addgeometry("Grid", "MeshSurface")
    setValue oObject & ".polymsh.geom.subdivu", 2
    setValue oObject & ".polymsh.geom.subdivv", 1
    BlendInPresets "Image", oObject, 1, False
    CreateTextureSupport oObject, siTxtPlanarXZ, siTxtDefaultPlanarXZ, "Texture_Support"
    set oUVWProp = oObject.Material.CurrentUV
    set oGeom = oObject.activeprimitive.geometry
    ' get UVW array
    aUVW = oUVWProp.elements.Array
    ' The cluster knows the relationship between
    ' indices of the Samples and indices of the Sample cluster
    set oCluster = oUVWProp.Parent
    for Each oPolygon In oGeom.Polygons
            ' get polygon index
            oPolygonId = oPolygon.Index
            ' get points index array under polygon
            aPntsIndex = oPolygon.Points.IndexArray
            logMessage "Polygon" & oPolygonId
            ' get sample indices
            set oSamples = oPolygon.Samples
            for i = 0 To oSamples.Count - 1
                    'Map from the geometry index to the cluster index
                    indexInCluster = oCluster.FindIndex( oSamples(i).Index )
                    if ( indexInCluster <> -1 ) then
                            logMessage "Point" & aPntsIndex(i) & ":" & "UV("_
                                    & aUVW(0, oSamples(i).Index) & _
                                    "," & aUVW(1, oSamples(i).Index) & ")"
                    end if
            next
    next

#### 4. VBScript Example

    ' This example demonstrates applying a file as a texture to an object, and explicitly setting
    ' the UV values to specify how the texture maps onto the geometry
    option explicit
    'This Texture should be a unique name to avoid conflicts with any other possible textures
    'The projection and the uv cluster property will use this name
    const g_ProjectionName = "MyTexture"
    'Set up a sample scene
    dim oObj1, oObj2, ImageFile
    ImageFile = Application.InstallationPath(siFactoryPath) & "\Data\XSI_SAMPLES\Pictures\jaiqua_face.jpg"
    NewScene ,false
    SetDisplayMode "Camera", "texturedecal"
    set oObj1 = ActiveSceneRoot.AddGeometry( "Sphere", "MeshSurface" )
    ApplyFileAsTexture oObj1,ImageFile
    set oObj2 = ActiveSceneRoot.AddGeometry( "Torus", "MeshSurface" )
    Translate oObj2, 0, 5, 0, siRelative, siView, siObj, siY
    ApplyFileAsTexture oObj2,ImageFile
    sub ApplyFileAsTexture( in_obj, in_FileName )
            AttachImageFileToObj in_obj, in_FileName
            dim oUVProp
            set oUVProp = FindClusterProperty( in_obj, g_ProjectionName)
            SetUVsOnProperty in_obj, oUVProp
    end sub
    'Subroutine: Attach Image File to Object
    '
    'This method creates a texture project, and image clip
    'and a small render tree that uses the image as the object's texture
    sub AttachImageFileToObj( in_obj, in_FileName )
            Dim oTextureProj
            set oTextureProj = CreateProjection( in_obj, , siTxtUV, , g_ProjectionName )
            'Create a local copy of the material and attach the default (phong shader)
            in_obj.AddMaterial "Phong"
            dim oPhongShader, oAmbientParam, oDiffuseParam
            set oPhongShader = in_obj.Material.Shaders(0)
            set oAmbientParam = oPhongShader.Parameters( "ambient" )
            set oDiffuseParam = oPhongShader.Parameters( "diffuse" )
            dim oImageClip
            SICreateImageClip in_FileName, ,oImageClip
            dim oImageNode
            set oImageNode = oAmbientParam.connectfrompreset("Image", siTextureShaderFamily)
            'Diffuse will be driven by the same image node
            oDiffuseParam.Connect( oImageNode )
            oImageNode.parameters( "tex" ).Connect(oImageClip)
            'Tell the image node that the uv values we are going to write into
            'the cluster property are the ones to use for this image
            oImageNode.parameters( "tspace_id" ).SetInstanceValue in_obj, oTextureProj, true
            'Connect the image to the image node
            oImageNode.Parameters( "tex" ).Connect( oImageClip )
    end sub
    'Subroutine: SetUVOnProperty
    '
    'Given an object and a Cluster Property of UV's
    'this routine will fill in values.
    'Currently it just show the entire texture on
    'each polygon.  However it could also be adjusted
    'to take the UV values as arguments
    sub SetUVsOnProperty( in_oObj, in_oUVProp )
            dim oUVElements, oCluster, cnt
            'get the ClusterElementCollection
            set oUVElements = in_oUVProp.Elements
            set oCluster = in_oUVProp.Parent
            cnt = oUVElements.Count
            'Get an array of all the UV Values
            dim ElArray, i
            ElArray = oUVElements.Array
            'Zero out the u,v,w values in the array
            for i = 0 to cnt - 1
                    ElArray( 0, i ) = 0
                    ElArray( 1, i ) = 0
                    ElArray( 2, i ) = 0
            next
            'Traverse the facets (eg polygons on a polymesh)
            'setting the UV values for each sample
            dim oFacets, oFacet, oSamples, oSample, cntSamples
            dim sample1ClusterIdx, sample2ClusterIdx, sample3ClusterIdx
            set oFacets = in_oObj.ActivePrimitive.Geometry.Facets
            for each oFacet in oFacets
                    set oSamples = oFacet.Samples
                    cntSamples = oSamples.Count
                    'In this example we will map each polygon to cover
                    'the entire u/v space - eg the entire texture shows up on
                    'each
                    'Because values are already zeroed we only set
                    'the values     we want as non-zero
                    sample1ClusterIdx = oCluster.FindIndex( oSamples(1).Index )
                    sample2ClusterIdx = oCluster.FindIndex( oSamples(2).Index )
                    ElArray( 0, sample1ClusterIdx ) = 1
                    ElArray( 0, sample2ClusterIdx ) = 1
                    ElArray( 1, sample2ClusterIdx ) = 1
                    if ( cntSamples >= 4 ) then
                            sample3ClusterIdx = oCluster.FindIndex( oSamples(2).Index )
                            ElArray( 1, oSamples(3).Index ) = 1
                    end if
            next
            'Assign these values to the cluster property
            oUVElements.Array = ElArray
            'Freezing the property provides the most efficient memory representation
            FreezeObj in_oUVProp
    end sub
    'Subroutine: FindClusterProperty
    'Give an object and a property name string,
    'this will find the UV cluster property
    function FindClusterProperty( in_obj, in_Name )
            dim oClusters, oCluster, oProps, oProp
            'Get the sample clusters
            set oClusters = in_obj.ActivePrimitive.Geometry.Clusters.Filter( "Sample" )
            for each oCluster in oClusters
                    set oProps = oCluster.Properties.Filter( "uvspace" )
                    for each oProp in oProps
                            if ( oProp.Name = in_Name ) then
                                    set FindClusterProperty = oProp
                                    exit function
                            end if
                    next
            next
            set FindClusterProperty = Nothing
    end function

#### 5. VBScript Example

    'VBScript example showing how to find ClusterProperty objects
    'on an Mesh
    'Create a sample scene with many different cluster properties
    newscene ,false
    dim sphere
    set sphere = CreatePrim ( "Sphere", "MeshSurface" )
    'Create a vertex color cluster property
    CreateVertexColorSupport , "MyVertexColorProperty", sphere
    'Save a Shape
    SaveShapeKey "sphere", , , 1, , , , , siShapeLocalReferenceMode
    'Create a symmetry map
    CreateSymmetryMap
    'Save two weight maps (they will re-use the same
    'cluster)
    CreateWeightMap , sphere, "Weight_Map1"
    CreateWeightMap , sphere, "Weight_Map2"
    'Create an skeleton and envelop weight map
    Create2DSkeleton -5, 1, 0, 6, 1, 0, -6, 0, 0, 4
    AppendBone "eff", 5, 4, 0
    ApplyFlexEnv "sphere;bone,bone1", False
    'Demonstrate how it is possible to find all the
    'clusters and cluster properties
    logmessage "List of Clusters and Cluster Properties on " & sphere.Name
    logmessage "--------------------------------"
    for each oCluster in sphere.ActivePrimitive.Geometry.Clusters
            logmessage "Cluster: " & oCluster.Name
            for each oLocalProp in oCluster.LocalProperties
                    if typename( oLocalProp ) = "ClusterProperty" then
                            logmessage "   " & oLocalProp.Name & " (Type: " & oLocalProp.Type & ")"
                    end if
            next
            logmessage "--------------------------------"
    next
    'Demonstrate how we can be more direct if we are looking for a specific type
    'of cluster property
    'We know that weight maps are always on point clusters
    set oPntClusters = sphere.ActivePrimitive.Geometry.Clusters.Filter( "pnt" )
    for each oPntCluster in oPntClusters
            set oWeightMaps = oPntCluster.LocalProperties.Filter( "wtmap" )
            for each oWeightMap in oWeightMaps
                    logmessage "Found weight map " & oWeightMap.FullName
            next
    next

### See Also

Material.CurrentUV Geometry.SaveShapeKey PolygonMesh.AddVertexColor CreateVertexColorSupport CreateUserMotion