def checkMappedDrive(self): schemaDriveLetter = str(schemaObj.artRoot[0]) if not self.sceneName[0] == schemaDriveLetter.upper() and not self.sceneName[0] == schemaDriveLetter.lower(): moBuLogger.warning("Current scene '%s' was not loaded from '%s:' drive" % (self.sceneName, schemaDriveLetter)) return 0 else: return 1
def zeroTimeline(self, character=None): ''' moves timeline to zero with character animation Params: character: FBcharacterNode Returns: True/False ''' # find start of current take currentTake = FBSystem().CurrentTake currentTimeSpan = currentTake.LocalTimeSpan currentTakeStartTimeInt = int(currentTimeSpan.GetStart().GetTimeString()) # check timeline if currentTakeStartTimeInt == 0: # abort moBuLogger.warning("No need to run zeroTimeline, first frame is already 0.") return False # find stop and offset currentTakeStopTimeInt = int(currentTimeSpan.GetStop().GetTimeString()) offset = FBTime(0, 0, 0, -1 * currentTakeStartTimeInt) # create track lTrackContainer = FBStoryTrack(FBStoryTrackType.kFBStoryTrackCharacter) # lTrackContainer = FBStoryTrack(FBStoryTrackType.kFBStoryTrackAnimation) # find character if not character: character = MoBuSceneCore().getCharacter(hipsJoint='') if not character: moBuLogger.error("Failed to find character.") # plot to control rig if not character.GetCurrentControlSet(): character.CreateControlRig(True) character.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, self.SetPlotOptions()) # assign character to track lTrackContainer.Character = character # create clip, and offset it lTrackContainer.CopyTakeIntoTrack(currentTimeSpan, currentTake, offset) # move timeline newTimeSpan = FBTimeSpan() newTimeSpan.Set(FBTime(0, 0, 0, 0), FBTime(0, 0, 0, currentTakeStopTimeInt - currentTakeStartTimeInt)) currentTake.LocalTimeSpan = newTimeSpan # plot back down self.plotCharacter(character=character, nSpace='', quiet=True) # nuke story track lTrackContainer.FBDelete() moBuLogger.info("Zeroed-out timeline.") return True
def getTimeInt(self, time): ''' gets frame of time in integer format Params: time: FBTime object Returns: frame (int) ''' strTime = time.GetTimeString() if '*' in strTime: strTime = strTime[:-1] moBuLogger.warning("Sub frame (%s*) found in FBTime object: %s" % (strTime, time)) # convert to int intTime = int(strTime) return intTime
def clearAnimCurve(self, pAnimNode): ''' Clears curves from passed FBAnimationNode Params: pAnimNode: FBAnimationNode to clear curves with Returns: True/False ''' if not isinstance(pAnimNode, FBAnimationNode): moBuLogger.error("Was not passed FBAnimationNode object: '%s'" % pAnimNode) if not len(pAnimNode.Nodes) == 3: moBuLogger.warning("No subAnimNodes found on: '%s'" % pAnimNode) else: pAnimNode.Nodes[0].FCurve.EditClear() pAnimNode.Nodes[1].FCurve.EditClear() pAnimNode.Nodes[2].FCurve.EditClear() return True return False
def readNote(self, nameOrFBNote=''): ''' read from FBNote Params: nameOrFBNote: name of note OR FBNote object Returns: content/False ''' if isinstance(nameOrFBNote, FBNote): ourNote = nameOrFBNote else: ourNote = self.getObjectFromWildcardName(pattern=nameOrFBNote, byName=True, returnLongNames=False, byType=FBNote) if not ourNote: moBuLogger.warning("Could not find FBNote: '%s'" % nameOrFBNote) return False content = ourNote.StaticComment return content
def deleteAllInSet(self, setName='', quiet=False): ''' deletes all items in passed set name Params: setName: name of set quiet: suppress dialogs Returns: True/False ''' mySet = self.findSet(name=setName, quiet=quiet) if not mySet: moBuLogger.warning("Could not find Set %s" % setName) return False if len(mySet.Items) == 0: moBuLogger.warning("No items in Set %s" % setName) return False success = self.deleteAll(mySet.Items) # delete set itself mySet.FBDelete() return success
def validate(self, pModel, _type, pyMB=None): ''' checks for object type and returns True/false Params: pModel: model object to check _type: object type to check against pyMB: is 'OK' if pyMoBu object type Returns: True/False ''' # check for string accidentally passed as pModel if isinstance(pModel, str): # string was passed, get object pModel = self.getObject(pModel) # not string type if isinstance(pModel, _type): return True elif pyMB and isinstance(pModel, PMBModel) and isinstance(pModel.component, _type): return True else: moBuLogger.warning("Object '%s' not of type '%s'" % (pModel, _type)) return False
def getObject(self, name, pyMB=False, exact=False, quiet=False): ''' gets FBObject or PMBObject Params: name: string name of object pyMB: return PMBObject type exact: if true search namespace as well quiet: if true does not warn when object doesn't exist Returns: FBObject/PMBObject ''' # use 2014 command if self.mobuVer == 2014: FBFindModelByName = FBFindModelByLabelName if not isinstance(name, str): moBuLogger.debug("MoBu.getObject() was passed '%s'" % name) # probably already an object if pyMB: if not isinstance(name, PMBModel): pModel = name.ConvertToPyMoBu() return pModel return name pModel = FBFindModelByName(name) exactWord = '' if exact: # Need to find EXACT name pModel = FBFindModelByLabelName(name) exactWord = 'exact ' # convert to PMBModel? if pModel: if pyMB: if not isinstance(pModel, PMBModel): pModel = pModel.ConvertToPyMoBu() return pModel if not quiet: moBuLogger.warning("Could not find object with %sname '%s'" % (exactWord, name)) return None
def deleteAll(self, pObjects=[]): ''' deletes all objects passed in the list Params: pObjects: list of FBObjects Returns: True/False ''' success = True # try selected if nothing passed if len(pObjects) == 0: pObjects = self.getSelected(_type='all', found=False) if len(pObjects) == 0: moBuLogger.warning("Must pass list or have something selected.") return False # covert to python list from FBPropertyListComponent pObjectsList = [] if isinstance(pObjects, FBPropertyListComponent): for obj in pObjects: pObjectsList.append(obj) else: pObjectsList = pObjects # cull FBModelSkeleton type out to delete last deleteList = [] modelSkels = [] for _object in pObjectsList: if not isinstance(_object, FBModelSkeleton): deleteList.append(_object) else: modelSkels.append(_object) # delete everything but FBModelSkeletons count = 0 for obj in deleteList: try: # stupid list and unbound, have to test try: name = obj.Name # have to store before deleting obj.FBDelete() moBuLogger.debug("Deleted: %s" % name) count += 1 except UnboundWrapperError: moBuLogger.debug("%s already deleted, skipping." % name) except: moBuLogger.debug("Failed to delete: %s" % name) success = False ##WARNING!! Must delete other objects BEFORE ##deleting FBModelSkeletons via children first # destroy FBModelSkeleton from hier up for modelSkel in modelSkels: try: # stupid list and unbound, have to test try: name = modelSkel.Name # have to store before deleting modelSkel.FBDelete() moBuLogger.debug("Deleted: %s" % name) count += 1 except UnboundWrapperError: moBuLogger.debug("%s already deleted, skipping." % name) except: moBuLogger.debug("Failed to delete: %s" % name) success = False moBuLogger.info("Deleted '%d' objects" % count) # clean del(pObjectsList, pObjects) return success
def customFBFbxOptions(self, pLoad=False, saveAllTakes=True, allElements=True, selection=False, **kwargs): """ create save/load options Params: pLoad: True if loading, False if saving saveAllTakes: Set to False if save current take only allElements: Set to False and pass kwargs to save/load/merge specific elements selection: True to save selected only Returns: FBFbxOptions object """ if self.mobuVer == 2010: moBuLogger.warning("FBFbxOptions are not valid for 2010") return None elif self.mobuVer == 2012 or self.mobuVer == 2013 or self.mobuVer == 2014: # create object pFbxOptions = FBFbxOptions(pLoad) if not allElements: # set all ElementActions and Base properties to false pFbxOptions.SetAll(FBElementAction.kFBElementActionDiscard, False) baseProperties = [ "BaseCameras", "CameraSwitcher", "CameraSwitcherSettings", "CurrentCamera", "CurrentCameraSettings", "GlobalLighting", "GlobalLightingSettings", "Transport", "TransportSettings", "EmbedMedia", "SaveSelectedModelsOnly", ] for bProperty in baseProperties: exec ("pFbxOptions.%s=False" % bProperty) # process kwargs for key in kwargs: # check for non-strings passed in if not isinstance(kwargs[key], str): moBuLogger.error("A non-string type arg was passed in: '%s'" % kwargs[key]) if "kFBElementAction" in kwargs[key]: # FBPropertyElementAction exec ("pFbxOptions.%s = FBElementAction.%s" % (key, kwargs[key])) else: # FBPropertyBase exec ("pFbxOptions.%s=%s" % (key, kwargs[key])) # save selected for saves if not pLoad and selection: pFbxOptions.SaveSelectedModelsOnly = True # skip takes if not saveAllTakes: currentTake = self.system.CurrentTake pTakeIndex = 0 for take in self.scene.Takes: # save current take only if not pLoad: if not take.Name == currentTake.Name: pFbxOptions.SetTakeSelect(pTakeIndex, False) # merge no takes else: pFbxOptions.SetTakeSelect(pTakeIndex, False) pTakeIndex += 1 # save ASCII pFbxOptions.UseASCIIFormat = True return pFbxOptions else: moBuLogger.error("Wrong version of MotionBuilder '%s'" % self.mobuVer)
def savePCSoptions(self, pathFile=None, quiet=True, pOptions=None, p4=True): """ saves with customFBFbxOptions Params: pathFile: complete file path to save quiet: suppress messages pOptions: pre-made options p4: markForAdd/checkout or not Returns: True/False """ text = "Saved with PCSoptions" # pick file if not passed if not pathFile: if not quiet: pathFile = self.openFileDialog(openSave="save") else: moBuLogger.error("No pathFile passed and quiet=True") return False if not pathFile: moBuLogger.info("Cancelled") return False # add extension if they didn't type it if not Path(pathFile).ext: pathFile = "%s.fbx" % pathFile # # checkout from perforce # if p4: # if self.pcsParseObj.isp4Active: # self.p4.fileName = pathFile # if self.p4.isP4Connected: # try: # self.p4.p4CheckOut(desc=text) ## except P4.P4Exception: # except: # moBuLogger.warning("Failed to checkout: '%s'" % pathFile) # else: # if not quiet: # moBuLogger.warning('P4Active setting FALSE, not checking out.') # else: # if not quiet: # moBuLogger.warning("p4 arg passed as False, not checking out for file: '%s'." % pathFile) if not pOptions: pOptions = self.customFBFbxOptions(pLoad=False, saveAllTakes=True) # 2010 save process currentTakeObject = FBSystem().CurrentTake if self.mobuVer == 2010: lMgr = FBFbxManager() # @UndefinedVariable lMgr.SaveBegin(str(pathFile)) lMgr.Selected = True for strEach in lMgr.Takes: if strEach.Name != currentTakeObject.Name: strEach.Import = False lMgr.EmbedMedia = False lMgr.BaseCameras = False lMgr.CameraSwitcherSettings = False lMgr.CurrentCameraSettings = False lMgr.GlobalLightingSettings = False lMgr.TransportSettings = False if not lMgr.Save(): moBuLogger.errorDialog("There is a problem saving the file", "Cannot Save") if not lMgr.SaveEnd(): moBuLogger.errorDialog("There is a problem saving the file", "Cannot Save") # 2012 save process elif self.mobuVer == 2012 or self.mobuVer == 2013 or self.mobuVer == 2014: alreadyExists = False if Path(pathFile).exists(): alreadyExists = True if not self.app.FileSave(str(pathFile), pOptions): # cancelled? moBuLogger.warning("Cancelled") return False if not alreadyExists: # check to see if new file is there res = os.path.exists(str(pathFile)) if res: if not quiet: moBuLogger.info("%s, '%s'" % (text, str(pathFile))) return True else: moBuLogger.errorDialog("Failed to save '%s'" % str(pathFile)) return False else: # TODO: check to see if different? if not quiet: moBuLogger.info("%s, '%s'" % (text, str(pathFile))) return True