Python Reference Guide
 
Loading...
Searching...
No Matches
ComplexTools\BlendShape_Editor.py
1# Copyright 2009 Autodesk, Inc. All rights reserved.
2# Use of this software is subject to the terms of the Autodesk license agreement
3# provided at the time of installation or download, or which otherwise accompanies
4# this software in either electronic or hard copy form.
5#
6# Script description:
7# Blend shaped editor.
8# Press Attach and it will grab all BlendShape Model in the scene and create an editor for them.
9# Press Detach and it will release all BlendShape and clears all UI
10#
11# Topic: FBEventName, FBSlider
12#
13
14from pyfbsdk import *
15from pyfbsdk_additions import *
16
17class SliderControl(FBVBoxLayout):
18 def _sliderCallback(self,control,event):
19 if event.Type == FBEventName.kFBEventChange:
20 self.value.Text = "%3.2f" % self.slider.Value
21 self._linkedproperty.Data=self.slider.Value
22 if self.key.State==1:
23 self._isCandidate=True
24 elif event.Type ==FBEventName.kFBEventOnClick:
25 self._onChange=True
26 elif event.Type ==FBEventName.kFBEventExit:
27 self._onChange=False
28
29 def _valueCallback(self, control, event):
30 self._onChange=True
31 self.slider.Value = float(self.value.Text)
32 self._linkedproperty.Data = float(self.value.Text)
33 self.value.Text = "%3.2f" % float(self.value.Text)
34 self._onChange=False
35 if self.key.State==1:
36 self._isCandidate=True
37
38 def _nameCallback(self, control, event):
39 print("NameChanged")
40
41 def _keyCallback(self, control, event):
42 self.Key()
43
44 def _clearCallback(self, control, event):
45 self.ClearAnimation()
46
47 def _IdleCallback(self, control, event):
48 if not self._onChange:
49 self.updateView()
50
51 def __init__(self, Aproperty):
52 from pyfbsdk import FBAddRegionParam
53 from pyfbsdk import FBAttachType
54
55 FBVBoxLayout.__init__(self)
56 self._linkedproperty = Aproperty
57 self._onChange = False
58 self._isCandidate = False
59 self.slider = pyfbsdk.FBSlider()
60 self.value = pyfbsdk.FBEdit()
61 self.name = pyfbsdk.FBLabel()
62 self.name.Justify = FBTextJustify.kFBTextJustifyRight
63 self.key = pyfbsdk.FBButton()
64 self.key.State=1
65 self.key.Caption = "Key"
66 self.clear = pyfbsdk.FBButton()
67 self.clear.Caption = "Clear"
68
69 if Aproperty.IsAnimatable() and Aproperty.GetDataTypeName().lower()=="shape":
70 self.slider.Min = Aproperty.GetMin()
71 self.slider.Max = Aproperty.GetMax()
72 self.slider.Value = Aproperty.Data
73 self.value.Text = "%3.2f" % Aproperty.Data
74 self.name.Caption = Aproperty.GetName()
75 else:
76 print("notAdouble")
77
78 self.slider.OnChange.Add(self._sliderCallback)
79 self.value.OnChange.Add(self._valueCallback)
80 self.key.OnClick.Add(self._keyCallback)
81 self.OnIdle.Add(self._IdleCallback)
82 self.clear.OnClick.Add(self._clearCallback)
83
84
85 self.Add(self.slider, 150, width = 35)
86
87
88 self.Add(self.clear, 25)
89
90
91 self.Add(self.key, 25)
92
93
94 self.Add(self.name, 25)
95
96
97
98 self.Add(self.value, 25)
99
100
101 def add(self,name,content):
102 self.tabpanel.Items.append(name)
103 self.tabcontents.append(content)
104 self.setContent(len(self.tabpanel.Items) - 1)
105
106 def setContent(self,index):
107 self.tabpanel.ItemIndex = index
108 self.SetControl("mainlyt",self.tabcontents[index])
109
110 def Key(self):
111 self._linkedproperty.Key()
112 self._isCandidate=False
113
114 def Reset(self):
115 self._isCandidate=True
116 self.value.Text="0.0"
117 self._valueCallback(None,FBEventChange())
118
119 def ClearAnimation(self):
120 self._isCandidate=True
121 self._linkedproperty.GetAnimationNode().FCurve.EditClear()
122
123
124 def Clear(self):
125 self._linkedproperty.GetAnimationNode().KeyRemove()
126
127 def updateView(self):
128 if not self._onChange:
129 precision = 0.005
130 currentvalue = float(self.value.Text)
131 if currentvalue < self._linkedproperty.Data-precision or currentvalue > self._linkedproperty.Data+precision:
132 self.value.Text="%3.2f" %self._linkedproperty.Data
133 self.slider.Value = self._linkedproperty.Data
134 if not self._isCandidate and self._linkedproperty.GetAnimationNode().IsKey():
135 if self.key.State!=1:
136 self.key.State=1
137 else:
138 if self.key.State!=0:
139 self.key.State=0
140 if self._linkedproperty.IsAnimatable() and self._linkedproperty.GetAnimationNode().KeyCount>0:
141 self.key.Caption="Key *"
142 else:
143 self.key.Caption="Key"
144
145def GetBlendShapeProp(aModel):
146 myproplist = list()
147 for prop in aModel.PropertyList:
148 if prop != None and prop.IsAnimatable() and prop.GetDataTypeName().lower()=="shape":
149 myproplist.append(prop)
150 return myproplist
151
152class ModelBlendShapeUI (FBHBoxLayout):
153 def _KeyAllCallBack(self,control, event):
154 for each in self._mySliderList:
155 each.Key()
156
157 def _ResetAllCallBack(self,control, event):
158 for each in self._mySliderList:
159 each.Reset()
160
161 def _ClearAllCallBack(self,control, event):
162 for each in self._mySliderList:
163 each.ClearAnimation()
164
165 def __init__(self, Amodel):
166 from pyfbsdk import FBAddRegionParam
167 from pyfbsdk import FBAttachType
168
169 FBHBoxLayout.__init__(self)
170 self._linkedModel = Amodel
171 self._mySliderList=list()
172
173 self.bkeyall=FBButton()
174 self.bkeyall.Caption="Key All"
175 self.brstall=FBButton()
176 self.brstall.Caption="Reset All"
177 self.bclrall=FBButton()
178 self.bclrall.Caption="Clear All"
179
180
181 self._myButtonsLay = FBVBoxLayout()
182 self.Add(self._myButtonsLay, 75)
183
184 self.bkeyall.OnClick.Add(self._KeyAllCallBack)
185 self._myButtonsLay.Add(self.bkeyall, 25)
186
187
188 self.brstall.OnClick.Add(self._ResetAllCallBack)
189 self._myButtonsLay.Add(self.brstall, 25)
190
191
192 self.bclrall.OnClick.Add(self._ClearAllCallBack)
193 self._myButtonsLay.Add(self.bclrall, 25)
194
195 # add all the slider ctrl
196 for prop in GetBlendShapeProp(self._linkedModel):
197 slider = SliderControl(prop)
198 self._mySliderList.append(slider)
199 self.Add(slider, 75, space = 10)
200
201
202
203def GetBlendShapeModel():
204 modelslist = list()
205 for component in FBSystem().Scene.Components:
206 if str(type(component)).lower().find("fbmodel")>-1:
207 bblend=False
208 for prop in component.PropertyList:
209 if not prop==None and prop.IsAnimatable() and prop.GetDataTypeName().lower()=="shape":
210 bblend=True
211 break
212 if bblend:
213 modelslist.append(component)
214 return modelslist
215
216
217def DetachFromBlendShape(control, event):
218 global regions
219 global models
220
221 for region in regions.values():
222 lyt.RemoveRegion(region)
223 regions = {}
224 models = []
225
226def AttachToBlendShape(control, event):
227 DetachFromBlendShape(None, None)
228
229 global models
230 models = GetBlendShapeModel()
231
232 anchor = FBAttachType.kFBAttachTop
233 anchorRegion = ""
234 for i, model in enumerate(models):
235 lytName = model.Name
236 blendShapeEditor = ModelBlendShapeUI(model)
237
238 arrowName = "ArrowName" + str( i )
239 x = FBAddRegionParam(0,FBAttachType.kFBAttachLeft,"")
240 y = FBAddRegionParam(0,anchor,anchorRegion)
241 w = FBAddRegionParam(2000,FBAttachType.kFBAttachNone,"")
242 h = FBAddRegionParam(0,FBAttachType.kFBAttachNone,"")
243 lyt.AddRegion(arrowName ,arrowName , x, y, w, h)
244
245 b = FBArrowButton()
246 regions[model] = arrowName
247 lyt.SetControl(arrowName ,b)
248
249 # important : we set the content AFTER having added the button arrow
250 # to its parent layout
251 b.SetContent( model.Name, blendShapeEditor, 2000, 300 )
252 blendShapeEditor.Restructure(True)
253
254 anchor = FBAttachType.kFBAttachBottom
255 anchorRegion = arrowName
256
257
258def SceneChanged(scene, event):
259 if event.Type == FBSceneChangeType.kFBSceneChangeDetach and \
260 event.ChildComponent in models:
261 lyt.RemoveRegion(regions[event.ChildComponent])
262 models.remove(event.ChildComponent)
263
264
265def OnToolDestroy(control,event):
266 # Important: each time we run this script we need to remove
267 # the SceneChanged from the Scene else they will accumulate
268 FBSystem().Scene.OnChange.Remove(SceneChanged)
269
270
271models = []
272regions = {}
273
274# Tool creation will serve as the hub for all other controls
275tool = FBCreateUniqueTool("Blend Shape Editor")
276
277tool.StartSizeX = 400
278tool.StartSizeY = 200
279
280scroll = FBScrollBox()
281scroll.SetContentSize(2000,10000)
282
283mainLyt = FBVBoxLayout()
284x = FBAddRegionParam(0,FBAttachType.kFBAttachLeft,"")
285y = FBAddRegionParam(0,FBAttachType.kFBAttachTop,"")
286w = FBAddRegionParam(0,FBAttachType.kFBAttachRight,"")
287h = FBAddRegionParam(0,FBAttachType.kFBAttachBottom,"")
288tool.AddRegion("main","main", x, y, w, h)
289tool.SetControl("main",mainLyt)
290
291btnbar = FBHBoxLayout()
292btn = FBButton()
293btn.Caption = "Attach"
294btn.OnClick.Add(AttachToBlendShape)
295btnbar.Add(btn, 75)
296
297btn = FBButton()
298btn.Caption = "Detach"
299btn.OnClick.Add(DetachFromBlendShape)
300btnbar.Add(btn, 75)
301
302mainLyt.Add(btnbar, 30)
303
304mainLyt.AddRelative(scroll)
305
306lyt = scroll.Content
307
308# Register for scene event
309FBSystem().Scene.OnChange.Add(SceneChanged)
310
311# register when this tool is destroyed.
312tool.OnUnbind.Add(OnToolDestroy)
313
314ShowTool(tool)
Creates a button which opens a layout to display content.
Definition: pyfbsdk_generated.h:1173
Used to create and manage buttons in a user interface.
Definition: pyfbsdk_generated.h:2442
Scroll Box.
Definition: pyfbsdk_generated.h:16979
Provides access to the underlying system, and the MotionBuilder scene.
Definition: pyfbsdk_generated.h:18771
Python built-in float class.
Definition: pyfbsdk.h:53
Python built-in list container class.
Definition: pyfbsdk.h:65
Used to create and manage buttons in a user interface.
Definition: pyfbsdk.h:4105
Text edit box.
Definition: pyfbsdk.h:7661
Text label.
Definition: pyfbsdk.h:11492
Slider.
Definition: pyfbsdk.h:19123
Python built-in string class.
Definition: pyfbsdk.h:77