2009/09/19

ヘアースタイリング - Hair2Curve

ヘアースタイリングツールを作ってみました。
初めに断っておきますが、このツールは、スクリプテッドオペレータを使用しています。
で、そのスクリプテッドオペレータが存在している状態で、保存すると二度とデータは復帰出来ません
という超危険な仕様なので、使い方は気をつけてくださいw
保存するときは、ヘアについてる、Hair2Curveをすべて消してからにしましょう。

使い方は、下記画像さんしょ。



ヘアを選択して実行するやつ

Hair2Curve.pys
#---------------------------------------------------
app=Application;log=app.LogMessage;sel=app.Selection
import win32com.client
#---------------------------------------------------
if sel.Count==0 or sel(0).type!="hair":
 raise

sCode = """from win32com.client.dynamic import Dispatch as d
def Hair2Curve_Update(ctx,OutPrim,InPrim):
 oCrvCol = InPrim.Value.Geometry.Curves
 lHairPos = [[],[],[]]
 for oCrv in oCrvCol:
  for fHairPer in [f/13.000*99.999+0.001 for f in range(14)]:
   vPos = d(oCrv.EvaluatePositionFromPercentage(fHairPer)[0])
   lHairPos[0].append(vPos(0))
   lHairPos[1].append(vPos(1))
   lHairPos[2].append(vPos(2))
 OutPrim.Value.GetGeometry2(ctx.CurrentFrame).Points.PositionArray = lHairPos
"""

oCrvCol = win32com.client.Dispatch("XSI.Collection")
for oHair in sel:
 oHair.AllowStretch.Value = True
 lPos=[[f for f in l] for l in oHair.ActivePrimitive.Geometry.Points.PositionArray]
 iStrNmb=len(lPos[0])/14
 lPos.append(list([1])*len(lPos[0]))
 oCrv = oHair.Parent.AddNurbsCurveList()
 for i in range(iStrNmb):
  oCrv.ActivePrimitive.Geometry.AddCurve(
   [ lPos[0][i*14:i*14+14],
    lPos[1][i*14:i*14+14],
    lPos[2][i*14:i*14+14],
    lPos[3][i*14:i*14+14] ],
   range(14),
   False,
   1,
   1
  )
 oFitCrvOp = app.ApplyGenOp("CrvFit", "", oCrv, 3, "siPersistentOperation", "siKeepGenOpInputs", "")(0)
 oFitCrvOp.points.Value = 3
 log(oFitCrvOp.Parent3DObject)
 oFitCrv = oFitCrvOp.Parent3DObject
 oHair.Parent.AddChild(oFitCrv)

 oTransfo = oHair.Kinematics.Global.Transform
 oFitCrv.Kinematics.Global.Transform = oTransfo
 app.FreezeModeling(oFitCrv)
 app.DeleteObj(oCrv)
 #app.ToggleVisibility(oFitCrv)
 oCrvCol.Add(oFitCrv)
 app.Refresh()

 oOpr = oHair.ActivePrimitive.AddScriptedOp(sCode,oFitCrv.ActivePrimitive,"Hair2Curve","Python",1)

sel.SetAsText(oCrvCol.GetAsText())



そんでもって、Hair2CurveOpを消すスクリプトは、これです。

FreezeHair2Curve.pys
#---------------------------------------------------
app=Application;log=app.LogMessage;sel=app.Selection
import win32com.client
from win32com.client import constants as c
from win32com.client.dynamic import Dispatch as d
#---------------------------------------------------
app.ActivateObjectSelTool()
oHairPrimCol = app.FindObjects("","{D5C3CDBA-B361-4A11-9582-91DBA0ECBB49}")
for oPrim in oHairPrimCol:
 oOp = oPrim.NestedObjects("Hair2Curve")
 if oOp:
  log(oOp)
  oCrv = d(oOp).InputPorts(0).target2.Parent3DObject
  app.FreezeObj(oPrim.Parent3DObject)
  app.DeleteObj(oCrv)


いやいや、おっかねぇスクリプトですね。
会社でなんて使わせられません。

そもそも、Hairにスクリプテッドオペレータが適用出来ないXSI様が悪いんですけどね。
HairにICE適用出来ないのも悪いですね。

そいや、Softimage2010を使い始めましたわ。
2010になって、HairにICE適用出来るようになったのかしら。
後でやってみよーっと。

FaceRobotは、なかなか素晴らしいものがありますね。
顎とか、口まわりとか、目まわりとか。
顔は、モーションキャプチャの場合、Envelopeのほうが断然楽ですな。
ただし、後付け修正したいので、Shapeで加えるとかですかね。
もちろん、移動差分の骨のクリップを並べて、MixerのNormalizeをオフって加算でやるのもいいですね。
どっちも得手不得手があるので、それぞれ選ぶべきですなー。

データは軽く作れよっ。

Perforce: 複数のワークスペースを更新するバッチ

batを叩けば全部更新。 @echo off set P4PORT=x.x.x.x:xxxx set P4USER=user set P4PASSWD=password echo %P4PORT% echo %P4USER% echo %P4PASSWD% echo %P4PAS...