クラスタを取得する

 
 
 

このセクションでは、3D オブジェクトのクラスタとエレメントを作成、修正する方法と、それらにアクセスする方法について説明します。 このセクションのすべてのコードはある大きなスクリプトの一部ですが、説明する箇所に応じて分けられています。 内容は以下の通りです。

例: クラスタのエレメント、親、およびタイプへのアクセス

クラスタを使用する多くの作業に、クラスタのエレメントを使用する作業が含まれます。 エレメントには SubConmponent オブジェクト(Cluster.CreateSubComponent)からアクセスできます。 Cluster.CreateSubComponent からは、クラスタを子に持つ 3D オブジェクトにアクセスできます(SubComponent.Parent3DObject)。

ヒント:

エレメントには Cluster.Elements プロパティを介してアクセスすることもできます。このプロパティは、ジオメトリ インデックスのコレクションを ClusterElementCollection として返します。

これにより、クラスタの親の名前、クラスタに含まれるエレメント、およびエレメントのタイプが出力されます。 このセクションの他の例でもこの機能について触れます。

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