## 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