from pyfbsdk import *
from pyfbsdk_additions import *
class SliderControl(VBoxLayout):
def _sliderCallback(self,control,event):
if event.Name == FBEventName.kFBEventChange:
self.value.Text = "%3.2f" % self.slider.Value
self._linkedproperty.Data=self.slider.Value
if self.key.State==1:
self._isCandidate=True
elif event.Name ==FBEventName.kFBEventOnClick:
self._onChange=True
elif event.Name ==FBEventName.kFBEventExit:
self._onChange=False
def _valueCallback(self, control, event):
self._onChange=True
self.slider.Value = float(self.value.Text)
self._linkedproperty.Data = float(self.value.Text)
self.value.Text = "%3.2f" % float(self.value.Text)
self._onChange=False
if self.key.State==1:
self._isCandidate=True
def _nameCallback(self, control, event):
print "NameChanged"
def _keyCallback(self, control, event):
self.Key()
def _clearCallback(self, control, event):
self.ClearAnimation()
def _IdleCallback(self, control, event):
if not self._onChange:
self.updateView()
def __init__(self, Aproperty):
from pyfbsdk import FBAddRegionParam
from pyfbsdk import FBAttachType
VBoxLayout.__init__(self)
self._linkedproperty = Aproperty
self._onChange = False
self._isCandidate = False
self.slider = pyfbsdk.FBSlider()
self.value = pyfbsdk.FBEdit()
self.name = pyfbsdk.FBLabel()
self.name.Justify = FBTextJustify.kFBTextJustifyRight
self.key = pyfbsdk.FBButton()
self.key.State=1
self.key.Caption = "Key"
self.clear = pyfbsdk.FBButton()
self.clear.Caption = "Clear"
if Aproperty.IsAnimatable() and Aproperty.GetDataTypeName().lower()=="shape":
self.slider.Min = Aproperty.GetMin()
self.slider.Max = Aproperty.GetMax()
self.slider.Value = Aproperty.Data
self.value.Text = "%3.2f" % Aproperty.Data
self.name.Caption = Aproperty.GetName()
else:
print "notAdouble"
self.slider.OnChange.Add(self._sliderCallback)
self.value.OnChange.Add(self._valueCallback)
self.key.OnClick.Add(self._keyCallback)
self.OnIdle.Add(self._IdleCallback)
self.clear.OnClick.Add(self._clearCallback)
self.Add(self.slider, 150, width = 35)
self.Add(self.clear, 25)
self.Add(self.key, 25)
self.Add(self.name, 25)
self.Add(self.value, 25)
def add(self,name,content):
self.tabpanel.Items.append(name)
self.tabcontents.append(content)
self.setContent(len(self.tabpanel.Items) - 1)
def setContent(self,index):
self.tabpanel.ItemIndex = index
self.SetControl("mainlyt",self.tabcontents[index])
def Key(self):
self._linkedproperty.Key()
self._isCandidate=False
def Reset(self):
self._isCandidate=True
self.value.Text="0.0"
self._valueCallback(None,FBEventChange())
def ClearAnimation(self):
self._isCandidate=True
self._linkedproperty.GetAnimationNode().FCurve.EditClear()
def Clear(self):
self._linkedproperty.GetAnimationNode().KeyRemove()
def updateView(self):
if not self._onChange:
precision = 0.005
currentvalue = float(self.value.Text)
if currentvalue < self._linkedproperty.Data-precision or currentvalue > self._linkedproperty.Data+precision:
self.value.Text="%3.2f" %self._linkedproperty.Data
self.slider.Value = self._linkedproperty.Data
if not self._isCandidate and self._linkedproperty.GetAnimationNode().IsKey():
if self.key.State!=1:
self.key.State=1
else:
if self.key.State!=0:
self.key.State=0
if self._linkedproperty.IsAnimatable() and self._linkedproperty.GetAnimationNode().KeyCount>0:
self.key.Caption="Key *"
else:
self.key.Caption="Key"
def GetBlendShapeProp(aModel):
myproplist = list()
for prop in aModel.PropertyList:
if prop != None and prop.IsAnimatable() and prop.GetDataTypeName().lower()=="shape":
myproplist.append(prop)
return myproplist
class ModelBlendShapeUI (HBoxLayout):
def _KeyAllCallBack(self,control, event):
for each in self._mySliderList:
each.Key()
def _ResetAllCallBack(self,control, event):
for each in self._mySliderList:
each.Reset()
def _ClearAllCallBack(self,control, event):
for each in self._mySliderList:
each.ClearAnimation()
def __init__(self, Amodel):
from pyfbsdk import FBAddRegionParam
from pyfbsdk import FBAttachType
HBoxLayout.__init__(self)
self._linkedModel = Amodel
self._mySliderList=list()
self.bkeyall=FBButton()
self.bkeyall.Caption="Key All"
self.brstall=FBButton()
self.brstall.Caption="Reset All"
self.bclrall=FBButton()
self.bclrall.Caption="Clear All"
self._myButtonsLay = VBoxLayout()
self.Add(self._myButtonsLay, 75)
self.bkeyall.OnClick.Add(self._KeyAllCallBack)
self._myButtonsLay.Add(self.bkeyall, 25)
self.brstall.OnClick.Add(self._ResetAllCallBack)
self._myButtonsLay.Add(self.brstall, 25)
self.bclrall.OnClick.Add(self._ClearAllCallBack)
self._myButtonsLay.Add(self.bclrall, 25)
for prop in GetBlendShapeProp(self._linkedModel):
slider = SliderControl(prop)
self._mySliderList.append(slider)
self.Add(slider, 75, space = 10)
def GetBlendShapeModel():
modelslist = list()
for component in FBSystem().Scene.Components:
if str(type(component)).lower().find("fbmodel")>-1:
bblend=False
for prop in component.PropertyList:
if not prop==None and prop.IsAnimatable() and prop.GetDataTypeName().lower()=="shape":
bblend=True
break
if bblend:
modelslist.append(component)
return modelslist
def DetachFromBlendShape(control, event):
global regions
global models
for region in regions.itervalues():
lyt.RemoveRegion(region)
regions = {}
models = []
def AttachToBlendShape(control, event):
DetachFromBlendShape(None, None)
global models
models = GetBlendShapeModel()
anchor = FBAttachType.kFBAttachTop
anchorRegion = ""
for i, model in enumerate(models):
lytName = model.Name
blendShapeEditor = ModelBlendShapeUI(model)
arrowName = "ArrowName" + str( i )
x = FBAddRegionParam(0,FBAttachType.kFBAttachLeft,"")
y = FBAddRegionParam(0,anchor,anchorRegion)
w = FBAddRegionParam(2000,FBAttachType.kFBAttachNone,"")
h = FBAddRegionParam(0,FBAttachType.kFBAttachNone,"")
lyt.AddRegion(arrowName ,arrowName , x, y, w, h)
b = FBArrowButton()
regions[model] = arrowName
lyt.SetControl(arrowName ,b)
b.SetContent( model.Name, blendShapeEditor, 2000, 300 )
blendShapeEditor.Restructure(True)
anchor = FBAttachType.kFBAttachBottom
anchorRegion = arrowName
def SceneChanged(scene, event):
if event.Type == FBSceneChangeType.kFBSceneChangeDetach and \
event.ChildComponent in models:
lyt.RemoveRegion(regions[event.ChildComponent])
models.remove(event.ChildComponent)
def OnToolDestroy(control,event):
FBSystem().Scene.OnChange.Remove(SceneChanged)
models = []
regions = {}
tool = CreateUniqueTool("Blend Shape Editor")
tool.StartSizeX = 400
tool.StartSizeY = 200
scroll = FBScrollBox()
scroll.SetContentSize(2000,10000)
mainLyt = VBoxLayout()
x = FBAddRegionParam(0,FBAttachType.kFBAttachLeft,"")
y = FBAddRegionParam(0,FBAttachType.kFBAttachTop,"")
w = FBAddRegionParam(0,FBAttachType.kFBAttachRight,"")
h = FBAddRegionParam(0,FBAttachType.kFBAttachBottom,"")
tool.AddRegion("main","main", x, y, w, h)
tool.SetControl("main",mainLyt)
btnbar = HBoxLayout()
btn = FBButton()
btn.Caption = "Attach"
btn.OnClick.Add(AttachToBlendShape)
btnbar.Add(btn, 75)
btn = FBButton()
btn.Caption = "Detach"
btn.OnClick.Add(DetachFromBlendShape)
btnbar.Add(btn, 75)
mainLyt.Add(btnbar, 30)
mainLyt.AddRelative(scroll)
lyt = scroll.Content
FBSystem().Scene.OnChange.Add(SceneChanged)
tool.OnUnbind.Add(OnToolDestroy)
ShowTool(tool)