Object Hierarchy | Related C++ Class: ClusterProperty
ClusterProperty
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.
//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)" |
'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)" |
' 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 |
' 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 |
'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 |