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.

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.Item. The data type of the value returned by ClusterElementCollection.Item 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 and symmetry map properties.

Methods

AddCustomOp

AddScriptedOp

AddScriptedOpFromFile

AnimatedParameters

AnimatedParameters2

BelongsTo

EvaluateAt

IsA

IsAnimated

IsAnimated2

IsClassOf

IsEqualTo

IsKindOf

IsLocked

IsSelected

LockOwners

SetAsSelected

SetCapabilityFlag

SetLock

TaggedParameters

UnSetLock

 

 

 

Properties

Application

Branch

BranchFlag

Capabilities

Categories

Elements

Families

FullName

Help

LockLevel

LockMasters

LockType

Model

Name

NestedObjects

Origin

OriginPath

Owners

Parameters

Parent

Parent3DObject

PPGLayout

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

' 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 )
   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 )

   '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" ).Value = g_ProjectionName

   '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



SOFTIMAGE|XSI v6.01     

Return to Softimage XSI Index