メッシュから特定のポリゴン部分を切り出したい。
標準のツールでやるなら
ExtractFaces とか DuplicateFacesなんですが、
こうなっちゃうんですよね。
faceを抽出することで、新しい2つのメッシュに分離されます。
これがちょっとヤダなー
オリジナルのメッシュは維持しつつ、指定したface部分だけ別オブジェクトとして複製したいなぁと。
手っ取り早くやるのであれば
- メッシュを複製
- ExtractFaces で対象部分を複製メッシュから抽出
- 不要な方を削除
こんな感じでしょうか。
挙動を調べる
ExtractFaces というコマンドが無いので、挙動を調べてみます。
スクリプトエディタを眺めると、2つほどコマンドがみえました。
polyChipOff
これで、指定したfaceを複製 または 切り離し(ただし1オブジェクト内)
polySeparate
こっちで別オブジェクトに分離する
という流れですね。
ちょっと試してみます。
cmds.polyChipOff( 'pSphere1.f[236:237]', dup=True)
faceが増えてますね
cmds.polySeparate( 'pSphere1' )
# Result: ['polySurface1', 'polySurface2', 'polySeparate1'] #
別オブジェクト化されましたねー
うーん。返り値があまりよろしくない。
生成されたメッシュ名が返ってきますが、どっちが目的のメッシュなのかわかりませんね。
方法を変える
方法を変えてみます。
- メッシュを複製
- 抽出対象のface以外のfaceをすべて削除
力技ですが、その分シンプルですね。
対象以外のfaceを全て削除する為に、faceIDを全取得する必要があります。
これはapiを眺めていたらあったので
OpenMaya.MFnMesh.numPolygons()
を使ってみようと思います。
import maya.cmds as cmds
import maya.api.OpenMaya as om
def getDagNode(target):
try:
sellist = om.MGlobal.getSelectionListByName(target)
return sellist.getDagPath(0)
except:
return None
def getShapeFn(dagPath):
FnShape = None
if dagPath.hasFn(om.MFn.kMesh):
FnShape = om.MFnMesh(dagPath)
elif dagPath.hasFn(om.MFn.kNurbsSurface):
FnShape = om.MFnNurbsSurface(dagPath)
elif dagPath.hasFn(om.MFn.kNurbsCurve):
FnShape = om.MFnNurbsCurve(dagPath)
return FnShape
def extractFace(targetFaces,targetMesh):
dupTarget = cmds.duplicate(targetMesh, name = targetMesh + "_extracted")[0]
dagPath = getDagNode(dupTarget)
FnShape = getShapeFn(dagPath)
polyNum = FnShape.numPolygons
deleteFace = []
for i in range(0,polyNum):
if i not in targetFaces:
deleteFace.append(dupTarget + ".f["+str(i)+"]")
cmds.delete(deleteFace)
さて先ほどと同様のポリゴンを抽出してみます。
extractFace([236,237],"pSphere1")
理想的な結果になりました。
改修案
このままでは使いづらいので、
- 抽出後の名前を指定できるように
- 選択しているfaceから処理できるように
この辺ができれば実作業で使えるような気がします。