このセクションでは、3D オブジェクトのクラスタとエレメントを作成、修正する方法と、それらにアクセスする方法について説明します。 このセクションのすべてのコードはある大きなスクリプトの一部ですが、説明する箇所に応じて分けられています。 内容は以下の通りです。
クラスタを使用する多くの作業に、クラスタのエレメントを使用する作業が含まれます。 エレメントには SubConmponent オブジェクト(Cluster.CreateSubComponent)からアクセスできます。 Cluster.CreateSubComponent からは、クラスタを子に持つ 3D オブジェクトにアクセスできます(SubComponent.Parent3DObject)。
これにより、クラスタの親の名前、クラスタに含まれるエレメント、およびエレメントのタイプが出力されます。 このセクションの他の例でもこの機能について触れます。
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
この例では、3D オブジェクト(グリッド)から(オブジェクト モデルを使用する)クラスタを作成する方法を示します。
このコード断片では、「例: クラスタのエレメント、親、およびタイプにアクセスする」で説明されている printClusterInfo()関数を使用します。
グリッドを作成した後、Geometry.AddCluster メソッドを使ってグリッド上にポイント(頂点)クラスタを追加できます。 クラスタはグリッド上に作成するのではなく、Geometry オブジェクト上に作成する必要があります。
' 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 _ )
printClusterInfo(oCluster)関数により、このポイントに対応する Script Editor の履歴ログに次のメッセージが表示されます。
'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 : "=========================================================="
既にクラスタを作成している場合この手順は不要です。ここでは、polymsh グリッド オブジェクト上のポイント クラスタを取得する場合を想定し、シーン内の既存クラスタを検索する方法を示します。
このコード断片は、「例: クラスタの作成」の例に従い、「例: クラスタのエレメント、親、およびタイプにアクセスする」で説明されている printClusterInfo()関数を使用します。
' Add an edge cluster to the grid aEdgesForCluster = Array( 28,31,47,50,66 ) Set oECls = oGrid.ActivePrimitive.Geometry.AddCluster( _ siEdgeCluster, _ "paint", _ aEdgesForCluster _ )
printClusterInfo(oECls)関数により、このポイントに対応する Script Editor の履歴ログに次のメッセージが表示されます。
'INFO : "Current cluster contains these element(s) under the 'wall' object: 'edge[28], edge[31], edge[47], edge[50], edge[66] '" 'INFO : "=========================================================="
このコードは、立方体を追加し、その立方体にもう 1 つのポイント クラスタを配置します。 配列の変数を使用することも、配列を引数に直接渡すこともできます。
' 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 ) _ )
printClusterInfo(oPCls)関数により、このポイントに対応する Script Editor の履歴ログに次のメッセージが表示されます。
'INFO : "Current cluster contains these element(s) under the 'chair' object: 'pnt[1], pnt[3], pnt[5], pnt[7] '" 'INFO : "=========================================================="
ここから面白くなります。 以下のコードでは、シーン内のメッシュ ジオメトリを使って各オブジェクトを取得し、次に Geometry.Clusters プロパティを使ってそれぞれのオブジェクトからクラスタ コレクションを取得します。 そのポイントにおける空のオブジェクトや無効なオブジェクトを使って作業しないで済むように、潜在的なエラーをできるだけ多く検出してください。
' 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
この例では、既存のポイント クラスタへのポイントの追加方法を示します。 オブジェクト モデルとスクリプト コマンドを併用します。
このコード断片は、「例: シーン内のクラスタの検索」の例に従い、「例: クラスタのエレメント、親、およびタイプにアクセスする」で説明されている printClusterInfo()関数を使用します。
' 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
printClusterInfo(oCluster)関数により、このポイントに対応する Script Editor の履歴ログに次のメッセージが表示されます。
'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 : "=========================================================="
クラスタからポイント(またはエレメント)を削除する場合は、SubComponent.RemoveElement メソッドを使用して SubComponent オブジェクトから独立させたいエレメントを消去してから、SIRemoveFromCluster コマンドを使用して実際のクラスタから残りのエレメントを削除します。
このコード断片は、「例: クラスタへのポイントの追加」の例に従い、「例: クラスタのエレメント、親、およびタイプにアクセスする」で説明されている printClusterInfo()関数を使用します。
ここでは、ポイント 22 および 40 を削除するため、サブコンポーネントから "pnt[21,23,29,31,33,39,41]" を削除し、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
printClusterInfo(oCluster)関数により、このポイントに対応する Script Editor の履歴ログに次のメッセージが表示されます。
'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 : "=========================================================="
1 つのオブジェクトからクラスタ全体をコピーする場合は、CopyCluster コマンドを使用します。
このコード断片は、「例: クラスタからの削除」の例に従っています。
' ' 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)
printClusterInfo(oCluster)関数により、このポイントに対応する Script Editor の履歴ログに次のメッセージが表示されます。
'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 : "=========================================================="
新しいオブジェクトにクラスタのコピーを作成したので、古いクラスタを削除します。 この場合、RemoveCluster コマンドを使って削除する必要があります。
このコード断片は、「例: クラスタをコピーする」の例に従っています。
RemoveCluster oCluster