最近MotionBuilderのスクリプトを書くのですが、日本語の資料も少なく調べるのに手間取ったので、備忘録もかねてメモの一部公開します。
確認環境はMotionBuilder2013です。
MotionBuilderでPythonを書き始める際のとっかかりになれば幸いです。
名前からオブジェクトを取得
for i in FBSystem().Scene.Components: oObj = FBFindModelByName("Cube") print oObj.Name
選択をクリア
for i in FBSystem().Scene.Components: i.Selected = False
選択からオブジェクトを取得 その1
array = [] for i in FBSystem().Scene.Components: if i.Selected == True: array.append(i) print i.Name print array
選択からオブジェクトを取得 その2
models = FBModelList() FBGetSelectedModels(models) for i in models: print i.Name
シーン内のカメラを取得
CAM = FBSystem().Scene.Cameras for i in CAM: print i.Name
シーン内のコンストレインを取得
Cnst = FBSystem().Scene.Constraints for i in Cnst: print i.Name
他FBSystem().Scene.で取得できるもの
FBSystem().Scene.Folders FBSystem().Scene.Shaders FBSystem().Scene.Textures FBSystem().Scene.VideoClips FBSystem().Scene.Materials FBSystem().Scene.Characters
選択のTypeInfoを取得
models = FBModelList() FBGetSelectedModels(models) for i in models: print i.TypeInfo
Nullを作成
oNull = FBModelNull("null")
グループに関する操作
#とりあえずグループに格納するCubeを作成 cube1 = FBModelCube("Cube 1") cube1.Show = True #グループ作成 lGP = FBGroup("testGroup") #グループに格納 lGP.ConnectSrc(cube1) #グループの表示/非表示 lGP.Show = False lGP.Show = True #グループのピック可/不可 lGP.Pickable = False lGP.Pickable = True #グループのTransform可/不可 lGP.Transformable = False lGP.Transformable = True #グループから削除 lGP.DisconnectSrc(cube1)
削除
oNull = FBModelNull("testNull") oNull.FBDelete()
複製
oCube = FBModelCube("tempCube") oClone = oCube.Clone()
移動、回転、スケールのSET & GET
################ # SET ################ lCube = FBModelCube('aFBModelCube') lCube.Show =True #ワールド移動 lCube.SetVector( FBVector3d( 50, 50, 50 ), FBModelTransformationType.kModelTranslation, True) #ローカル移動 lCube.SetVector( FBVector3d( 50, 50, 50 ), FBModelTransformationType.kModelTranslation, False) #ワールド回転 lCube.SetVector( FBVector3d( 15, 25, 35 ), FBModelTransformationType.kModelRotation, True ) #ローカル回転 lCube.SetVector( FBVector3d( 15, 25, 35 ), FBModelTransformationType.kModelRotation, False ) #ワールドスケール lCube.SetVector( FBVector3d( 25, 25, 25 ), FBModelTransformationType.kModelScaling, True ) #ローカルスケール lCube.SetVector( FBVector3d( 25, 25, 25 ), FBModelTransformationType.kModelScaling, False ) ################ # GET ################ pos = FBVector3d() rot = FBVector3d() scl = FBVector3d() #ワールド座標取得 lCube.GetVector( pos, FBModelTransformationType.kModelTranslation, True) print "World Position = [%f, %f, %f]" %(pos[0] ,pos[1], pos[2]) #ローカル座標取得 lCube.GetVector( pos, FBModelTransformationType.kModelTranslation, False) print "Local Position = [%f, %f, %f]" %(pos[0] ,pos[1], pos[2]) #ワールド回転角取得 lCube.GetVector( rot, FBModelTransformationType.kModelRotation, True ) print "World Rotation = [%f, %f, %f]" %(rot[0] ,rot[1], rot[2]) #ローカル回転角取得 lCube.GetVector( rot, FBModelTransformationType.kModelRotation, False ) print "Local Rotation = [%f, %f, %f]" %(rot[0] ,rot[1], rot[2]) #ワールドスケール取得 lCube.GetVector( scl, FBModelTransformationType.kModelScaling, True ) print "World Scaling = [%f, %f, %f]" %(scl[0] ,scl[1], scl[2]) #ローカルスケール取得 lCube.GetVector( scl, FBModelTransformationType.kModelScaling, False ) print "Local Scaling = [%f, %f, %f]" %(scl[0] ,scl[1], scl[2])
コンストレイン
# Num : Type # # 0 : Aim # 1 : Expression # 2 : Multi Referential # 3 : Parent/Child # 4 : Path # 5 : Position # 6 : Range # 7 : Relation # 8 : Rigid Body # 9 : 3Points # 10: Rotation # 11: Scale # 12: Mapping # 13: Chain IK # ## ################ # Parent/Child ################ pSrcObj = FBModelNull("SourceNull") pSrcObj.Show = True pDstObj = FBModelCube("DistributionCube") pDstObj.Show = True CM = FBConstraintManager() c = CM.TypeCreateConstraint(3) c.Name = "%s->%s_Parent/Child" %(pSrcObj.Name.replace(':','_'), pDstObj.Name.replace(':','_')) c.ReferenceAdd(0,pDstObj) c.ReferenceAdd(1,pSrcObj) c.Snap = True c.Lock = True c.Active = True
Character Face
FaceBorn = FBModelList() CfName = "Test Character Face" CF = FBCharacterFace(CfName) print CF print dir(CF) #CharacterFaceを削除 CF.FBDelete() #CaharacterFaceをリセット CF.GotoRest() #CharacterFaceのアクティブ CF.Active = True CF.Active = False #新規ClusterGroupの追加(Windowを切り替えてあげると更新される?) IdCG = CF.ClusterGroupAdd(FaceBorn,"ClusterGP") #ClusterGroupの名前の変更 CF.ClusterGroupSetName(idCG, "testClusterGP") #名前からClusterGroupIDを取得 TempIdCG = CF.ClusterGroupFindByName("testClusterGP") #ClusterGroupの数を取得 print CF.ClusterGroupGetCount() #ClusterGroupの削除 CF.ClusterGroupRemove(idCG) #新規ClusterShpaeの追加 idCS_A = CF.ClusterShapeAdd(idCG,"ClusterShapesA") idCS_B = CF.ClusterShapeAdd(idCG,"ClusterShapesB") #ClusterShape名を変更 CF.ClusterShapeSetName(idCG, idCS_A, "renameClusterShapeA") print CF.ClusterGroupFindByName("renameClusterShapeA") #ClusterShapeの数を取得 print CF.ClusterShapeGetCount(IdCG) #現在のポーズをClusterShapeに登録 CF.ClusterShapeSnap(idCG, idCS_A) #ClusterShapeの削除 CF.ClusterShapeRemove(idCG, idCS_B) #Expressionの追加 idEX = CF.ExpressionAdd("ExpTest") idEX2 = CF.ExpressionAdd("ExpTest2") #Expression名からIDを取得 tmpID = CF.ExpressionFindByName("ExpTest2") print tmpID #Expression数を取得 print CF.ExpressionGetCount() #IDからExpression名を取得 print CF.ExpressionGetName(tmpID) #Expression名を変更 CF.ExpressionSetName(tmpID,"ExpTest3") CF.ExpressionSetShapeWeight(idEX, IdCG, idCS_A, 100) #Expressionの削除 CF.ExpressionRemove(tmpID)
親子付け
oCubeA = FBModelCube("CubeA") oCubeA.Show = True oCubeB = FBModelCube("CubeB") oCubeB.Show = True oCubeA.Parent = oCubeB</pre> <span style="text-decoration: underline;">●Markerの作成</span> <pre>oMk = FBModelMarker("MK") oMk.Show = True oMk.Size = 500 oMk.Look = FBMarkerLook.kFBMarkerLookStick
MessageBox
FBMessageBox( "Message", "Hellow World", "OK", None, None )
フォルダを作成
#カメラのフォルダを作成 cam1 = FBCamera("my cam") cam_folder = FBFolder("cam folder", cam1) #ライトのフォルダを作成 light = FBLight("my light") light_folder = FBFolder("light folder", light) #マテリアルのフォルダを作成 Mat = FBMaterial("testMat") Mat_folder = FBFolder("Mat folder", Mat[0])
選択したモデルのマテリアルを取得
models = FBModelList() FBGetSelectedModels(models) for i in models: print models[0].Materials[0].Name
リレーションコンストレイン、マクロ全種
lMacro = { 'Boolean' : ["AND", "Flip Flop", 'Memory (B1 when REC)','Memory (last trigger)','NAND','NOR','NOT','OR','XNOR', 'XOR'], 'Converters' : ['Deg To Rad', 'HSB To RGB', 'Number to RGBA', 'Number to Vector', 'Number to Vector2', 'Rad To Deg', 'RGB To HSB', 'RGB To RGBA', 'RGBA To Number', 'RGBA To RGB', 'Seconds to Time', 'Time to TimeCode', 'TimeCode to Time', 'Vector to Number', 'Vector2 to Number'], 'Macro Tools': ['Macro Input Bool', 'Macro Input ColorAndAlpha', 'Macro Input Number', 'Macro Input Time', 'Macro Input Vector', 'Macro Output Bool', 'Macro Output ColorAndAlpha', 'Macro Output Number', 'Macro Output Time', 'Macro Output Vector'], 'My Macros' : ['Scale ConstraintRelation'], 'Number' : ['Absolute (|a|)', 'Add (a + b)', 'arccos(a)', 'arcsin(a)', 'arctan(a)', 'arctan2(b/a)', 'Cosine cos(a)','Damp','Damp (Clock based)', 'Distance Numbers', 'Divide (a/b)', 'exp(a)', 'Exponent (a^b)','IF Cond Then A Else B', 'Integer', 'Invert (1/a)', 'Is Between A and B', 'Is Different (a != b)', 'Is Greater (a > b)', 'Is Greater or Equal (a >= b)', 'Is Identical (a == b)', 'Is Less (a < b)', 'Is Less or Equal (a <= b)', 'ln(a)', 'log(a)', 'Max Pass-thru', 'Memory (a when REC)', 'Min Pass-thru', 'Modulo mod(a, b)', 'Multiply (a x b)', 'Precision Numbers', 'Pull Number', 'Scale And Offset (Number)','Sine sin(a)', 'sqrt(a)', 'Subtract (a - b)', 'Sum 10 numbers', 'Tangeant tan(a)', 'Triggered Delay (Number)', 'Triggered Delay with Memory (Number)'], 'Other' : ['Bezier Curve','Damping (3D)','Damping (3D) (Clock based)', 'FCurve number (%)', 'FCurve number (Time)', 'TRIGGERED PLUS MINUS COUNTER', 'TRIGGERED RANDOM'], 'Rotation' : ['Add (R1 + R2)', 'Angle difference (Points)', 'Angle difference (Rotations)', 'ANGULAR ACCELERATION', 'ANGULAR SPEED','Damp (Rotation)', 'GLOBAL TO LOCAL', 'Interpolate', 'Local to global', 'Rotation scaling','Subtract (R1 - R2)', 'Three-point constraint'], 'Shapes' : ['Select exclusive', 'Select exclusive 24', 'Shape calibration'], 'Sources' : ['Counter with play pause' ,'Counter with start stop', 'HALF CIRCLE RAMP','Isoceles triangle ramp','Pulse', 'Ramp','Random','RIGHT TRIANGLE RAMP','SINE RAMP','SQUARE RAMP'], 'System' : ['Current Time','Local time','Play Mode','Reference Time', 'System Time', 'Transport Control'], 'Time' : ['If Cond Then T1 Else T2', 'Is Different (T1 != T2)', 'Is Greater (T1 > T2)','Is Greater or Equal (T1 >= T2)', 'Is Identical (T1 == T2)','Is Less (T1 < T2)', 'Is Less or Equal (T1 <= T2)'], 'Vector' : ['Acceleration','Add (V1 + V2)', 'Angle', 'Center of Mass', 'Damp position', 'Derive', 'Determinant', 'Displacement', 'Distance','Dot Product (V1.V2)', 'Gravity', 'IF Cond Then A Else B', 'Is different (V1 != V2)', 'Is identical (V1 == V2)', 'Length', 'Memory (V1 when REC)', 'MIDDLE POINT','Normalize','Orbit attraction', 'Precision vectors', 'PULL VECTOR', 'Scale (a x V)', 'Scale and offset (Vector)' , 'SCALE DAMPING', 'Speed', 'Subtract (V1 - V2)', 'Sum 10 vectors', 'Triggered delay (Vector)', 'Triggered delay with memory (Vector)', 'Vector product (V1 x V2)'] } csRelation = FBConstraintRelation( 'sample ConstraintRelation' ) y=0 for i in lMacro: x=0 for j in lMacro[i]: lBox = csRelation.CreateFunctionBox(i, j) csRelation.SetBoxPosition(lBox, x, y) x += 400 y += 300
NameSpaceの追加/入れ替え/削除
from pyfbsdk import FBSystem, FBNamespaceAction #ネームスペース用null作成 oNull = FBModelNull("null") #ネームスペースの追加/入れ替え/Remove lNamespace = "MyNameSpace" lNewNamespace = "MyNewNameSpace" for lComp in FBSystem().Scene.Components: #追加 lComp.ProcessNamespaceHierarchy(FBNamespaceAction.kFBConcatNamespace, lNamespace, None, False) #入れ替え #lComp.ProcessNamespaceHierarchy(FBNamespaceAction.kFBReplaceNamespace, lNamespace, lNewNamespace, False) #Remove #lComp.ProcessNamespaceHierarchy(FBNamespaceAction.kFBRemoveAllNamespace, lNamespace, None, False)
シーンを評価する
FBSystem().Scene.Evaluate()
ベクトル操作系
#ベクトルを用意 vecA = FBVector3d(1,1,1) vecB = FBVector3d(3,4,5) #長さ print vecA.Length() #長さの二乗 print vecA.SquareLength() #正規化 print vecA.Normalize() #外積 print vecA.CrossProduct(vecB) #内積 print vecA.DotProduct(vecB)
カスタムプロパティだけ取得したい
oObj = FBFindModelByName("Cube") for i in oObj.PropertyList: if i.IsUserProperty(): print "{0} is Custom Property".format(i.Name) else: print "{0} is not Custom Property".format(i.Name)
若干古いかもしれないけど、役に立つかな?
初めまして。
mayaと違ってログが出ないので苦労しており、とても勉強になります。
突然の質問で恐縮なのですが、takeの切り替えもpythonでできるものでしょうか?
take一覧を取得まではできたのですが、その後がわからず…
過去記事に失礼いたしました…。
takeList=[]
for aTake in FBSystem().Scene.Takes:
takeList.append(aTake.Name)
print takeList
せっかくコメントいただいたのですが、私の方が久しくmotionbuilderを使っていない上、現在手元にソフトすらないので、ご質問に対してお答えすることが出来ません。
お力になれずすみません。
takeの切り替えくらいなら関数なり用意されてるように思いますが、「マニュアルでそれらしいのを見つけて試しに使ってみる」くらいしか見つけるすべが無いかもしれませんね。
もう少し探してみます。
お忙しい中お返事ありがとうございました。
Namespaceは2015現在
obj.LongName = “newNamespace”+”:”+obj.Name
とかでできるようですね
教えていただきありがとうございます。
この記事の内容はMotionBuilder2013だから、最新との違いが結構ありそうですね。