This section demonstrates how to create, access, and modify clusters and their elements on 3D objects. All of the code in this section belongs to one large script, but is presented in modules according to usage. The topics covered include:
A lot of the tasks when working with cluster involve using the cluster's elements. You can access the elements through the SubComponent object (Cluster.CreateSubComponent). From there, you can access the 3D object that is parenting the cluster (SubComponent.Parent3DObject).
This function prints the name of the cluster's parent, which elements it contains, and the type of elements it contains. The other examples in this section also refer to this function.
Function printClusterInfo( in_cluster ) ' Make sure the inbound object is a valid cluster If TypeName( in_cluster ) = "Cluster" Then ' Get the cluster's elements Set oMembers = in_cluster.CreateSubComponent aIndices = oMembers.ElementArray ' Format its values sElementData = "" For i = 0 To UBound( aIndices ) sElementData = sElementData & ", " & in_cluster.Type & "[" & aIndices(i) & "]" Next sElementData = vbTab & vbTab & Right( sElementData, Len(sElementData)-2 ) ' Print them out LogMessage "Current cluster contains these element(s) under the '" _ & oMembers.Parent3DObject.Name & "' object:" & vbLf _ & sElementData & vbLf LogMessage "==========================================================" printClusterInfo = True Else LogMessage "Object is not a valid cluster." printClusterInfo = False End If End Function
This example demonstrates how to create a cluster (using the object model) from a 3D object (in this case, a grid).
This code snippet uses the printClusterInfo() function described in Example: Accessing the cluster's elements, parent, and type.
After you create the grid, you can add a point (vertex) cluster on it using the Geometry.AddCluster method. Notice that you have to create the cluster on the Geometry object, not directly on the grid.
' Create the grid Set oGrid = ActiveSceneRoot.AddGeometry( "Grid", "MeshSurface", "wall" ) ' You can use an array variable to save the point indices aPointsForCluster = Array( 21,22,31,40,41 ) ' The indices used in this method correspond to the indexing order of the ' element for the 3D object Set oCluster = oGrid.ActivePrimitive.Geometry.AddCluster( _ siVertexCluster, _ "wallpaper", _ aPointsForCluster _ )
The printClusterInfo(oCluster) function displays the following message in the History Log of the Script Editor at this point:
'INFO : "Current cluster contains these element(s) under the 'wall' object: 'pnt[21], pnt[23], pnt[29], pnt[31], pnt[33], pnt[39], pnt[41] '" 'INFO : "=========================================================="
This step is not necessary if you have already created a cluster, but is provided simply as a demonstration of finding an existing cluster in the scene assuming you know only that you want the point cluster on a polymsh grid object.
This code snippet follows the one in Example: Create a cluster and uses the printClusterInfo() function described in Example: Accessing the cluster's elements, parent, and type.
Just to make it interesting, let's add a couple more clusters.
' Add an edge cluster to the grid aEdgesForCluster = Array( 28,31,47,50,66 ) Set oECls = oGrid.ActivePrimitive.Geometry.AddCluster( _ siEdgeCluster, _ "paint", _ aEdgesForCluster _ )
The printClusterInfo(oECls) function displays the following message in the History Log of the Script Editor at this point:
'INFO : "Current cluster contains these element(s) under the 'wall' object: 'edge[28], edge[31], edge[47], edge[50], edge[66] '" 'INFO : "=========================================================="
This piece of code adds a cube and makes another point cluster on it. Notice how you can use either an array variable or pass an array directly to the argument.
' Create a cube and add another point cluster to it Set oCube = ActiveSceneRoot.AddGeometry( "Cube", "MeshSurface", "chair" ) Set oPCls = oCube.ActivePrimitive.Geometry.AddCluster( _ siVertexCluster, _ "seat", _ Array( 1,3,5,7 ) _ )
The printClusterInfo(oPCls) function displays the following message in the History Log of the Script Editor at this point:
'INFO : "Current cluster contains these element(s) under the 'chair' object: 'pnt[1], pnt[3], pnt[5], pnt[7] '" 'INFO : "=========================================================="
Now the fun begins! This piece gets each object with mesh geometry in the scene and then gets the cluster collection from each using the Geometry.Clusters property. Make sure to trap as many potential errors as you can, since you may be working with empty or invalid objects at some point.
' Using the X3DObject.FindChildren method and specifying the mesh family ' (3rd argument) returns a collection of all polygon mesh objects that ' appear in the hierarchy under the scene root. From there we can find ' which one matches our criteria. Set oAllObjects = ActiveSceneRoot.FindChildren( , , siMeshFamily ) ' Loop through the collection to find any Point clusters For Each obj In oAllObjects ' Get all the clusters on the mesh geometry as a collection Set oAllClusters = obj.ActivePrimitive.Geometry.Clusters ' Loop through the collection to find any Point clusters For Each cls In oAllClusters ' Only deal with point clusters If cls.Type = "pnt" Then ' Get the one whose parent = grid Set oPoint = cls.CreateSubComponent Set oParent = oPoint.Parent3DObject ' If it matches, grab it & run If oParent.IsKindOf( "Grid" ) Then Set oCluster = cls Exit For End If End If Next Next
This example demonstrates how to add points to an existing point cluster. In this case, you have to use a mixture of the object model and scripting commands.
This code snippet follows the one in Example: Find the cluster in the scene and uses the printClusterInfo() function described in Example: Accessing the cluster's elements, parent, and type.
' Create a new SubComponent object so you can specify which elements to add. Set oSubComp = oCluster.CreateSubComponent ' Use the SubComponent.AddElement method to add each point separately ' to the subcomponent. oSubComp.AddElement 23 oSubComp.AddElement 29 oSubComp.AddElement 33 oSubComp.AddElement 39 ' Add the subcomponent to the cluster using the SIAddToCluster command. SIAddToCluster oCluster, oSubComp
The printClusterInfo(oCluster) function displays the following message in the History Log of the Script Editor at this point:
'INFO : "Current cluster contains these element(s) under the 'wall' object: 'pnt[21],pnt[22],pnt[23],pnt[29],pnt[31],pnt[33],pnt[39],pnt[40],pnt[41] '" 'INFO : "=========================================================="
When you want to remove points (or any element) from a cluster, you have to use the SubComponent.RemoveElement method to clear the elements you want to keep from the SubComponent object and then use the SIRemoveFromCluster command to remove the leftover elements from the actual cluster.
This code snippet follows the one in Example: Add points to the cluster and uses the printClusterInfo() function described in Example: Accessing the cluster's elements, parent, and type.
In this case, we want to remove points 22 and 40, so we have to remove "pnt[21,23,29,31,33,39,41]" from the subcomponent and then use it with SIRemoveFromCluster:
' Create a new SubComponent object to specify which elements to remove. Set oSubComp = oCluster.CreateSubComponent ' Remove the elements you want to keep from the subcomponent oSubComp.RemoveElement 21 oSubComp.RemoveElement 23 oSubComp.RemoveElement 29 oSubComp.RemoveElement 31 oSubComp.RemoveElement 33 oSubComp.RemoveElement 39 oSubComp.RemoveElement 41 ' Remove the specified subcomponent from the cluster SIRemoveFromCluster oCluster, oSubComp
The printClusterInfo(oCluster) function displays the following message in the History Log of the Script Editor at this point:
'INFO : "Current cluster contains these element(s) under the 'wall' object: 'pnt[21], pnt[23], pnt[29], pnt[31], pnt[33], pnt[39], pnt[41] '" 'INFO : "=========================================================="
When you want to copy an entire cluster from one object to another, you have to use the CopyCluster command
This code snippet follows the one in Example: Remove points from the cluster.
' ' Copying clusters can only be done via the CopyCluster command. This example ' demonstrates how to copy clusters between objects. Set oTarget = ActiveSceneRoot.AddGeometry( "Grid", "MeshSurface", "floor" ) CopyCluster oCluster, oTarget ' Now you have to find it in the scene again (since the CopyCluster command ' doesn't return the newly created cluster). It's probably the first one in ' the bunch. Set oNewCls = oTarget.ActivePrimitive.Geometry.Clusters(0)
The printClusterInfo(oCluster) function displays the following message in the History Log of the Script Editor at this point:
'INFO : "Current cluster contains these element(s) under the 'floor' object: 'pnt[21], pnt[23], pnt[29], pnt[31], pnt[33], pnt[39], pnt[41] '" 'INFO : "=========================================================="
Now that you've created a copy of the cluster on the new object, delete the old one. For this you need to use the RemoveCluster command:
This code snippet follows the one in Example: Copying clusters.
RemoveCluster oCluster
Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License