Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
from pyfbsdk import *
def UnselAll():
selModels = FBModelList()
FBGetSelectedModels (selModels, None, True)
for model in selModels:
model.Selected = False;
del(selModels)
UnselAll()
Models = FBModelList()
Skeleton = list()
FBGetSelectedModels (Models, None, False)
for model in Models:
if model.ClassName() == 'FBModelSkeleton':
Skeleton.append(model)
Deter = FBFindModelByName("Bip01").Children[0].Name.split(":")
for i in range(len(Skeleton)):
if Deter[1][5] == " ":
SplName = Skeleton[i].Name.split(":")
SplName[1] = SplName[1].replace(" ","_")
Skeleton[i].Name = SplName[0] + ":" + SplName[1]
else:
SplName = Skeleton[i].Name.split(":")
if SplName[1][0] == "_":
SplName[1] = SplName[1].replace("_"," ")
SplName[1] = SplName[1].replace(" ","_",1)
Skeleton[i].Name = SplName[0] + ":" + SplName[1]
else:
SplName[1] = SplName[1].replace("_"," ")
Skeleton[i].Name = SplName[0] + ":" + SplName[1]
+139
View File
@@ -0,0 +1,139 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
#cryLib.py
#some useful functions and classes
from pyfbsdk import *
from euclid import *
#casts point3 strings to pyEuclid vectors
def vec3(point3):
return Vector3(point3[0], point3[1], point3[2])
#casts a pyEuclid vector to FBVector3d
def fbv(point3):
return FBVector3d(point3.x, point3.y, point3.z)
#returns average position of an FBModelList as FBVector3d
def avgPos(models):
mLen = len(models)
if mLen == 1:
return models[0].Translation
total = vec3(models[0].Translation)
for i in range (1, mLen):
total += vec3(models[i].Translation)
avgTranslation = total/mLen
return fbv(avgTranslation)
#returns an array of models when given an array of model names
#useful with external apps/telnetlib ui
def modelsFromStrings(modelNames):
output = []
for name in modelNames:
output.append(FBFindModelByName(name))
return output
#stabilizes face markers, input 4 FBModelList arrays, leaveOrig <bool> for lraving original markers
def stab(right,left,center,markers,leaveOrig):
pMatrix = FBMatrix()
lSystem=FBSystem()
lScene = lSystem.Scene
newMarkers = []
def faceOrient():
lScene.Evaluate()
Rpos = vec3(avgPos(right))
Lpos = vec3(avgPos(left))
Cpos = vec3(avgPos(center))
faceAttach.GetMatrix(pMatrix)
xVec = (Cpos - Rpos)
xVec = xVec.normalize()
zVec = ((Cpos - vec3(faceAttach.Translation)).normalize()).cross(xVec)
zVec = zVec.normalize()
yVec = xVec.cross(zVec)
yVec = yVec.normalize()
facePos = (Rpos + Lpos)/2
pMatrix[0] = xVec.x
pMatrix[1] = xVec.y
pMatrix[2] = xVec.z
pMatrix[4] = yVec.x
pMatrix[5] = yVec.y
pMatrix[6] = yVec.z
pMatrix[8] = zVec.x
pMatrix[9] = zVec.y
pMatrix[10] = zVec.z
pMatrix[12] = facePos.x
pMatrix[13] = facePos.y
pMatrix[14] = facePos.z
faceAttach.SetMatrix(pMatrix,FBModelTransformationMatrix.kModelTransformation,True)
lScene.Evaluate()
def keyTransRot(animNodeList):
for lNode in animNodeList:
if (lNode.Name == 'Lcl Translation'):
lNode.KeyCandidate()
if (lNode.Name == 'Lcl Rotation'):
lNode.KeyCandidate()
Rpos = vec3(avgPos(right))
Lpos = vec3(avgPos(left))
Cpos = vec3(avgPos(center))
faceAttach = FBModelNull("faceAttach")
faceAttach.Show = True
faceAttach.Translation = fbv((Rpos + Lpos)/2)
faceOrient()
for obj in markers:
new = FBModelNull(obj.Name + '_stab')
newTran = vec3(obj.Translation)
new.Translation = fbv(newTran)
new.Show = True
new.Size = 20
new.Parent = faceAttach
newMarkers.append(new)
Take = lScene.Takes[1]
FStart = int(Take.LocalTimeSpan.GetStart().GetFrame(True))
FStop = int(Take.LocalTimeSpan.GetStop().GetFrame(True)+1)
lPlayerControl = FBPlayerControl()
lPlayerControl.GotoStart()
animNodes = faceAttach.AnimationNode.Nodes
lFbp = FBProgress()
lFbp.Caption = "Stabilization"
lFbp.Text = "Progress..."
for frame in range(FStart,FStop):
faceOrient()
for m in range (0,len(newMarkers)):
markerAnimNodes = newMarkers[m].AnimationNode.Nodes
newMarkers[m].SetVector(markers[m].Translation.Data)
lScene.Evaluate()
keyTransRot(markerAnimNodes)
keyTransRot(animNodes)
lPlayerControl.StepForward()
lVal = (frame/FStop)*10
lFbp.Percent = lVal
+83
View File
@@ -0,0 +1,83 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
from pyfbsdk import FBSystem, FBFilePopup, FBFilePopupStyle, FBFolderPopup, FBFbxManager, FBFbxManagerLoadAnimationMethod, FBPlotOptions, FBCharacterPlotWhere,FBFindModelByName, FBModelList, FBGetSelectedModels
# Lets define the actual loading and retargetting function
def LoadAndRetAnim (FileLoc,pOptions):
manager = FBFbxManager()
Char = FBSystem().Scene.Characters[0]
manager.LoadAnimationOnCharacter(FileLoc,Char,0,0,1,1,FBFbxManagerLoadAnimationMethod.kFBFbxManagerLoadConnect,pOptions,0,0,0)
Char.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig,pOptions)
Char.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton,pOptions)
del (manager, Char)
# Unselect all function
def UnselAll():
selModels = FBModelList()
FBGetSelectedModels (selModels, None, True)
for model in selModels:
model.Selected = False;
del(selModels)
# For the purpose of being able to clean up the file later on, we need to have
# all of the objects in the scene which need to stay there, be held in memory
UnselAll()
StartList = FBModelList()
StartListNames = list()
FBGetSelectedModels (StartList, None, False)
for model in StartList:
StartListNames.append(model.Name)
# Now we need to assign animation plot options
pOpt = FBPlotOptions()
pOpt.UseConstantKeyReducer = False
pOpt.PlotAllTakes = True
#Filter needs to be set, otherwise it will crash
FileOpen = FBFilePopup()
FileOpen.Filter = '*.fbx'
FileOpen.Caption = "Select the animation to Retarget"
FileOpen.Style = FBFilePopupStyle.kFBFilePopupOpen
FileOpen.Path = r'J:\temp'
if FileOpen.Execute():
File = FileOpen.FullFilename
LoadAndRetAnim (File, pOpt)
else:
print 'CANCEL'
#Get rid of imported trash
for name in StartListNames:
FBFindModelByName(name).Selected = True
EndList = FBModelList()
FBGetSelectedModels (EndList, None, False)
for model in EndList:
model.FBDelete()
UnselAll()
#for i in EndListNames:
# a = FBFindModelByName(i)
# a.FBDelete()
FBSystem().Scene.Characters[1].Components[0].FBDelete()
FBSystem().Scene.Characters[1].FBDelete()
# Cleanup.
del(StartList, StartListNames, EndList, EndListNames)
del(FBSystem, FBFilePopup, FBFilePopupStyle, FBFolderPopup, FBFbxManager, FBFbxManagerLoadAnimationMethod, FBPlotOptions, FBCharacterPlotWhere,FBFindModelByName, FBModelList, FBGetSelectedModels)
+27
View File
@@ -0,0 +1,27 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
from pyfbsdk import *
lSystem = FBSystem()
myCamera = FBCamera('charCamera')
myCamera.Parent = FBFindModelByName('Bip01')
myCamera.Show = True
myCamera.Selected = True
FBApplication().SwitchViewerCamera(myCamera)
myCamera.FrameSizeMode = FBCameraFrameSizeMode.kFBFrameSizeFixedResolution
myCamera.ResolutionHeight = 1080
myCamera.ResolutionWidth = 1920
myCamera.PixelAspectRatio = 1
myCamera.UseFrameColor = True
+267
View File
@@ -0,0 +1,267 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
#An example implementation for communicating with MotionBuilder
#through the Python Remote Server
#
#
#Christopher Evans - Apr 2008
import wx
import telnetlib
import win32gui
import win32com.client
import os
import sys
import time
import traceback
def process_is_running(proc_name):
#From Adam Pletcher's "Python for Tech Artsts" (http://www.volition-inc.com/gdc/)
import win32pdh
proc_name = os.path.splitext(proc_name)[0].lower()
junk, instances = win32pdh.EnumObjectItems(None,None,'Process', win32pdh.PERF_DETAIL_WIZARD)
for proc_inst in instances:
if (proc_inst.lower() == proc_name):
return True
return False
class MB_Sub_Frame(wx.Frame):
#This comes from Adam Pletcher's "Python for Tech Artsts" free GDC course materials
_top_mb_window_handle = None
def __init__(self, parent, app, id=-1, title="Motion Builder Tool", pos=(60, 120), size=(350, 200), name='frame', resize=True, style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.FRAME_NO_TASKBAR):
wx.Frame.__init__(self, parent, id, title, pos, size, style)
self.app = app
self.panel = None
self.initialPosOffset = pos
self._runningModal = False
# resizable windows is the default in wxPython, but we allow caller to override that.
if (not resize):
wx.Frame.ToggleWindowStyle(self, wx.RESIZE_BORDER)
# Tool window's background color. This should be made to match the user's BG color in Max.
bg_color = (197, 197, 197)
self.SetBackgroundStyle(wx.BG_STYLE_COLOUR)
self.SetBackgroundColour(wx.Color(bg_color[0], bg_color[1], bg_color[2]))
# Event Bindings
self.Bind(wx.EVT_CLOSE, self.on_close)
@classmethod
def create(cls, *args, **kw):
"""
Call this static class method to create a new instance of your subframe.
This will use the 3dsmax window as a parent for the current frame.
Limitation: If > 1 copy of 3dsmax is open, uses the first one it finds.
Could probably be fixed, however.
"""
if (not process_is_running('motionbuilder.exe')):
raise WindowsError('*** ERROR: MotionBuilder is not running')
else:
app = wx.GetApp()
if (app == None):
app = wx.App(redirect=False)
val = MB_Sub_Frame._get_top_mb_window()
topHandle = val[0]
if (topHandle == None):
raise WindowsError('*** ERROR: Motion Builder window handle not found.')
else:
windowPos = val[1]
toolFrame = wx.PreFrame()
toolFrame.AssociateHandle(topHandle)
toolFrame.PostCreate(toolFrame)
app.SetTopWindow(toolFrame)
try:
frame = cls(toolFrame, app, *args, **kw)
frame.Show(True)
except:
print cls.__name__
print traceback.format_exc()
frame = None
toolFrame.DissociateHandle()
return frame
@staticmethod
def _get_top_mb_window():
if MB_Sub_Frame._top_mb_window_handle is not None:
return MB_Sub_Frame._top_mb_window_handle
# EnumWindows requires a callback function
def callback(handle, winList):
winList.append(handle)
return True
# Get list of open windows
windows = []
win32gui.EnumWindows(callback, windows)
# Find window belonging to 3ds Max
for handle in windows:
title = win32gui.GetWindowText(handle)
if ('MotionBuilder 7.5' in title):
# Maximize the window if it's minimized
import win32con
window = win32gui.ShowWindow(handle, win32con.SW_MAXIMIZE)
# Get upper left desktop coords of MB window
pos = win32gui.GetWindowRect(handle)[:2]
# Set handle id in our instance
MB_Sub_Frame._top_mb_window_handle = handle
return (handle, pos)
# MB window not found
return None
def on_close(self, evt):
"""
Event handler for EVT_CLOSE event.
"""
self.Show(False)
self.Destroy()
win32gui.DestroyWindow(self.GetHandle())
# Regular wx Destroy waits for the application to destroy the window.
# Since there is no wxApp running, we do it ourselves.
win32gui.SetFocus(MB_Sub_Frame._top_mb_window_handle)
def show_modal_dialog(self, dlg):
"""
Method to display a modal dialog that also disables the 3dsmax window.
"""
mb_disabled = self._runningModal # Save enabled state, so we can restore it when this modal dialog is done
if (not mb_disabled):
self._runningModal = True
top = MB_Sub_Frame._top_mb_window_handle # get MB window handle
win32gui.EnableWindow(top, False) # disable it
ret_val = dlg.ShowModal() # show our dialog - won't continue until dialog is closed
if (not mb_disabled): # enables 3dsmax window again, if it was enabled when this dialog started
win32gui.EnableWindow(top, True)
self._runningModal = False
return ret_val
#------------------------------------------------------------------------------------------------------------------------
host = telnetlib.Telnet("127.0.0.1", 4242)
def mbPipe(command):
host.read_until('>>>', .01)
#write the command
host.write(command + '\n')
print ('Sending>>> '+ command)
#read all data returned
raw = str(host.read_until('>>>', .1))
#removing garbage i don't want
raw = raw.replace('\n\r>>>','')
raw = raw.replace('\r','')
rawArr = raw.split('\n')
#cleanArr = [item.replace('\r', '') for item in rawArr]
return rawArr
def getSelection():
selectedItems = []
mbPipe("selectedModels = FBModelList()")
mbPipe("FBGetSelectedModels(selectedModels,None,True)")
for item in (mbPipe("for item in selectedModels: print item.Name")):
selectedItems.append(item)
return selectedItems
class MyFrame(MB_Sub_Frame):
rStabMarkers = []
lStabMarkers = []
cStabMarkers = []
mSetMarkers = []
def __init__(self,parent,app):
# create a frame, no parent, default to wxID_ANY
MB_Sub_Frame.__init__(self, parent, app, id=-1, title='Face Stabilization',pos=(300, 150), size=(200, 190))
self.rStab = wx.Button(self, id=-1, label='Right STAB Markers',pos=(8, 8), size=(175, 28))
self.rStab.Bind(wx.EVT_BUTTON,self.rStabClick)
self.rStab.SetToolTip(wx.ToolTip("Select 1+ Right Stabilization Markers and Press"))
self.lStab = wx.Button(self, id=-1, label='Left STAB Markers',pos=(8, 38), size=(175, 28))
self.lStab.Bind(wx.EVT_BUTTON, self.lStabClick)
self.lStab.SetToolTip(wx.ToolTip("Select 1+ Left Stabilization Markers and Press"))
self.cStab = wx.Button(self, id=-1, label='Center STAB Markers',pos=(8, 68), size=(175, 28))
self.cStab.Bind( wx.EVT_BUTTON, self.cStabClick )
self.cStab.SetToolTip(wx.ToolTip("Select 1+ Center Stabilization Markers"))
self.markerSet = wx.Button(self, id=-1, label='Markers to Stabilize',pos=(8, 98), size=(175, 28))
self.markerSet.Bind(wx.EVT_BUTTON, self.markerSetClick)
self.markerSet.SetToolTip(wx.ToolTip("Select All Markers to Stabilize"))
self.stabilize = wx.Button(self, id=-1, label='Stabilize Markerset',pos=(8, 128), size=(175, 28))
self.stabilize.Bind(wx.EVT_BUTTON, self.stabilizeClick)
self.stabilize.SetToolTip(wx.ToolTip("Press to Stabilize the Markers"))
def rStabClick(self,event):
self.rStabMarkers = getSelection()
print str(self.rStabMarkers)
self.rStab.Label = (str(len(self.rStabMarkers)) + " Right Markers")
def lStabClick(self,event):
self.lStabMarkers = getSelection()
print str(self.lStabMarkers)
self.lStab.Label = (str(len(self.lStabMarkers)) + " Light Markers")
def cStabClick(self,event):
self.cStabMarkers = getSelection()
print str(self.cStabMarkers)
self.cStab.Label = (str(len(self.cStabMarkers)) + " Center Markers")
def markerSetClick(self,event):
self.mSetMarkers = getSelection()
print str(self.mSetMarkers)
self.markerSet.Label = (str(len(self.mSetMarkers)) + " Markers to Stabilize")
def stabilizeClick(self,event):
mbPipe('from euclid import *')
mbPipe('from cryLib import *')
mbPipe('rStab = modelsFromStrings(' + str(self.rStabMarkers) + ')')
mbPipe('lStab = modelsFromStrings(' + str(self.lStabMarkers) + ')')
mbPipe('cStab = modelsFromStrings(' + str(self.cStabMarkers) + ')')
mbPipe('markerset = modelsFromStrings(' + str(self.mSetMarkers) + ')')
mbPipe('stab(rStab,lStab,cStab,markerset,False)')
def on_close(self, event):
#This method is bound by MB_Sub_Frame to the EVT_CLOSE event.
print 'Shutting down...'
host.close()
self.user_exit = True
self.Destroy()
application = wx.PySimpleApp()
window = MyFrame.create()
application.MainLoop()