myara CG blog

CG Design Blog. Thoughts, experiments and experiences.

SI | Memo : GetICEAttributeFromName("PolygonPosition")

仕事関係で古いSIのプロジェクトもあったりするから、自分のツール開発ではICEを避けていました。

最近は古くてもXSI7になるにもかかわらずICEを避けつづけていました。
7ではICEのモデリングはあんまり出来ないしね。でもこのコマンドは7からでもOKだったことは知りませんでした。

これからはこのGetICEAttributeFromNameを使ってみます。

未完成の mSymm2 プラグインはまだいじってる為このコマンドを試してみました。
GetICEAttributeFromNameってのは、ICEアトリビュートを名前で取得するという意味です。
そのAttributeは色々ありますが、今回はPolygonPositionを使ってみました。

この「PolygonPosition」でポリゴンの位置情報を簡単に取得ができます。

今まで

obj.Geometry1D.CenterPosition

を使っていました。遅くて非常にややこしいやり方ですが、これしか知りませんでした。
AFAIK、ICEなしだとこれしかないですね。


例えば、X<0 のポリゴンを選択するファンクションはこんな感じに作っていました:

 
var oObj = selection(0)

// ポリゴンコレクションを取得
var CompCol = oObj.ActivePrimitive.Geometry.Facets;
var CompColCount = CompCol.Count;

// ターゲットのポリゴンコレクションを作っておく
var oTargetPoly = oObj.ActivePrimitive.Geometry.CreateSubComponent(siPolygonCluster);

// Geometry2D でポリゴンを取得
var oGeometry = oObj.obj;
var o2DComponent = oGeometry.Geometry2D;
var oPos = XSIMath.CreateVector3();

for ( var i=0; i < CompColCount; i++ ) {
var idx = CompCol(i).index;

// Geometry2DのCenterPositionでポリゴンの位置を取得
o2DComponent.CenterPosition(idx, oPos);

if (oPos.x < 0){oTargetPoly.Addelement(idx)};
}
SelectObj (oTargetPoly);



面倒だし、前回メモった「GetGeometry2」も使えなくて、元のポリゴンの位置取得が出来ません。

ICEなしでどうやってやるのかは分からないけど、ICEのPolygonPositionを使うと楽に出来ます:


 
var oObj = selection(0)

// ジオメトリ取得
var geo = oObj.ActivePrimitive.GetGeometry2(null, 0)

// ポリゴンの位置情報を取得
// JScriptだと .toArray() を使わないといけない。面倒くさい。
var polys = geo.GetICEAttributeFromName("PolygonPosition").DataArray.toArray();
// lenghtを取得しておく。(CollectionじゃなくてArrayだから)
var polyslength = polys.length

// ターゲットのポリゴンコレクションを作っておく
var oTargetPoly = oObj.ActivePrimitive.Geometry.CreateSubComponent(siPolygonCluster)

// ポリゴンの位置情報のアレイをループ
for ( var i=0; i < polyslength; i++ ) {
if (polys[i].X < 0){oTargetPoly.Addelement(i)}
}
SelectObj (oTargetPoly)


GetGeometry2 を使える上に、速度も倍ぐらい速くなっています。

追記:因みに、Pythonだとこんな感じです:

 
x = Application
from win32com.client import constants as c
oObj = x.selection(0)
geo = oObj.ActivePrimitive.GetGeometry2(0, 0)
polys = geo.GetICEAttributeFromName("PolygonPosition").DataArray
oTargetPoly = oObj.ActivePrimitive.Geometry.CreateSubComponent(c.siPolygonCluster)
for i, pos in enumerate(polys):
if (pos.X < 0):
oTargetPoly.AddElement(i)
x.SelectObj(oTargetPoly)

やっぱりPythonって見やすいね。このコードだとJSより 40~50% 遅いけど。