def updateValue(self, value, updateNormals=1, skipUpdate=False): if self.verts is None and self.faces is None: self.buildLists() # Update detail state old_detail = [self.human.getDetail(target[0]) for target in self.targets] self.setValue(value, skipDependencies = True) new_detail = [self.human.getDetail(target[0]) for target in self.targets] # Apply changes for target, old, new in zip(self.targets, old_detail, new_detail): if new == old: continue if self.human.isPosed(): # Apply target with pose transformation animatedMesh = self.human else: animatedMesh = None algos3d.loadTranslationTarget(self.human.meshData, target[0], new - old, None, 0, 0, animatedMesh=animatedMesh) if skipUpdate: # Used for dependency updates (avoid dependency loops and double updates to human) return # Update dependent modifiers self.propagateUpdate(realtime = True) # Update vertices if updateNormals: self.human.meshData.calcNormals(1, 1, self.verts, self.faces) self.human.meshData.update() event = events3d.HumanEvent(self.human, self.eventType) event.modifier = self.fullName self.human.callEvent('onChanging', event)
def updateValue(self, human, value, updateNormals=1): # Collect vertex and face indices if we didn't yet if not (self.verts or self.faces): # Collect verts self.verts = [] for target in self.targets: t = algos3d.getTarget(human.meshData, target[0]) self.verts.extend(t.verts) self.verts = list(set(self.verts)) # collect faces self.faces = [] for vindex in self.verts: self.faces += [face.idx for face in human.meshData.verts[vindex].sharedFaces] self.faces = list(set(self.faces)) # Remove old targets for target in self.targets: algos3d.loadTranslationTarget(human.meshData, target[0], -human.getDetail(target[0]), None, 0, 0) # Update detail state self.setValue(human, value) # Add new targets for target in self.targets: algos3d.loadTranslationTarget(human.meshData, target[0], human.getDetail(target[0]), None, 0, 0) # Update vertices faces = [human.meshData.faces[i] for i in self.faces] vertices = [human.meshData.verts[i] for i in self.verts] if updateNormals: human.meshData.calcNormals(1, 1, vertices, faces) human.meshData.update(vertices, updateNormals)
def updateValue(self, value, updateNormals=1, skipUpdate=False): if self.verts is None and self.faces is None: self.buildLists() # Update detail state old_detail = [ self.human.getDetail(target[0]) for target in self.targets ] self.setValue(value, skipDependencies=True) new_detail = [ self.human.getDetail(target[0]) for target in self.targets ] # Apply changes for target, old, new in zip(self.targets, old_detail, new_detail): if new == old: continue algos3d.loadTranslationTarget(self.human.meshData, target[0], new - old, None, 0, 0) if skipUpdate: # Used for dependency updates (avoid dependency loops and double updates to human) return # Update dependent modifiers self.propagateUpdate(realtime=True) # Update vertices if updateNormals: self.human.meshData.calcNormals(1, 1, self.verts, self.faces) self.human.meshData.update() event = events3d.HumanEvent(self.human, self.eventType) event.modifier = self.fullName self.human.callEvent('onChanging', event)
def applyAllTargets(self, progressCallback=None, update=True): """ This method applies all targets, in function of age and sex **Parameters:** None. progressCallback will automatically be set to G.app.progress if the progressCallback parameter is left to None. Set it to False to disable progress reporting. """ if progressCallback is None: progressCallback = G.app.progress if progressCallback: progressCallback(0.0) # First call progressCalback (which often processes events) before resetting mesh # so that mesh is not drawn in its reset state algos3d.resetObj(self.meshData) progressVal = 0.0 progressIncr = 0.5 / (len(self.targetsDetailStack) + 1) for (targetPath, morphFactor) in self.targetsDetailStack.iteritems(): algos3d.loadTranslationTarget(self.meshData, targetPath, morphFactor, None, 0, 0) progressVal += progressIncr if progressCallback: progressCallback(progressVal) # Update all verts self.getSeedMesh().update() self.updateProxyMesh() if self.isSubdivided(): self.updateSubdivisionMesh() if progressCallback: progressCallback(0.7) self.mesh.calcNormals() if progressCallback: progressCallback(0.8) if update: self.mesh.update() else: self.meshData.calcNormals(1, 1) if progressCallback: progressCallback(0.8) if update: self.meshData.update() if progressCallback: progressCallback(1.0) #self.traceStack(all=True) #self.traceBuffer(all=True, vertsToList=0) self.callEvent('onChanged', events3d.HumanEvent(self, 'targets'))
def symmetrize(self, direction='r'): """ This method applies either left to right or right to left symmetry to the currently selected body parts. Parameters ---------- direction: *string*. A string indicating whether to apply left to right symmetry (\"r\") or right to left symmetry (\"l\"). """ if direction == 'l': prefix1 = 'l-' prefix2 = 'r-' else: prefix1 = 'r-' prefix2 = 'l-' # Remove current values for target in self.targetsDetailStack.keys(): targetName = os.path.basename(target) # Reset previous targets on symm side if targetName[:2] == prefix2: targetVal = self.targetsDetailStack[target] algos3d.loadTranslationTarget(self.meshData, target, -targetVal, None, 1, 0) del self.targetsDetailStack[target] # Apply symm target. For horiz movement the value must be inverted for target in self.targetsDetailStack.keys(): targetName = os.path.basename(target) if targetName[:2] == prefix1: targetSym = os.path.join(os.path.dirname(target), prefix2 + targetName[2:]) targetSymVal = self.targetsDetailStack[target] if 'trans-in' in targetSym: targetSym = targetSym.replace('trans-in', 'trans-out') elif 'trans-out' in targetSym: targetSym = targetSym.replace('trans-out', 'trans-in') algos3d.loadTranslationTarget(self.meshData, targetSym, targetSymVal, None, 1, 1) self.targetsDetailStack[targetSym] = targetSymVal self.updateProxyMesh() if self.isSubdivided(): self.getSubdivisionMesh()
def symmetrize(self, direction='r'): """ This method applies either left to right or right to left symmetry to the currently selected body parts. Parameters ---------- direction: *string*. A string indicating whether to apply left to right symmetry (\"r\") or right to left symmetry (\"l\"). """ if direction == 'l': prefix1 = 'l-' prefix2 = 'r-' else: prefix1 = 'r-' prefix2 = 'l-' # Remove current values for target in self.targetsDetailStack.keys(): targetName = os.path.basename(target) # Reset previous targets on symm side if targetName[:2] == prefix2: targetVal = self.targetsDetailStack[target] algos3d.loadTranslationTarget(self.meshData, target, -targetVal, None, 1, 0) del self.targetsDetailStack[target] # Apply symm target. For horiz movement the value must be inverted for target in self.targetsDetailStack.keys(): targetName = os.path.basename(target) if targetName[:2] == prefix1: targetSym = os.path.join(os.path.dirname(target), prefix2 + targetName[2:]) targetSymVal = self.targetsDetailStack[target] if 'trans-in' in targetSym: targetSym = targetSym.replace('trans-in', 'trans-out') elif 'trans-out' in targetSym: targetSym = targetSym.replace('trans-out', 'trans-in') algos3d.loadTranslationTarget(self.meshData, targetSym, targetSymVal, None, 1, 1) self.targetsDetailStack[targetSym] = targetSymVal self.updateProxyMesh() if self.isSubdivided(): self.getSubdivisionMesh() gui3d.app.redraw()
def applyAllTargets(self, progressCallback=None, update=True, forceWarpReset=False): """ This method applies all targets, in function of age and sex **Parameters:** None. """ self.muscleWeightModifier.setValue(self, 1.0) self.baseModifier.setValue(self, 1.0) algos3d.resetObj(self.meshData) self.syncShadowVerts() if progressCallback: progressCallback(0.0) progressVal = 0.0 progressIncr = 0.5 / (len(self.targetsDetailStack) + 1) self.resetAllWarpTargets(forceWarpReset) for (targetPath, morphFactor) in self.targetsDetailStack.iteritems(): algos3d.loadTranslationTarget(self.meshData, targetPath, morphFactor, None, 0, 0) progressVal += progressIncr if progressCallback: progressCallback(progressVal) # Update all verts self.getSeedMesh().update() self.updateProxyMesh() if self.isSubdivided(): self.updateSubdivisionMesh() if progressCallback: progressCallback(0.7) self.mesh.calcNormals() if progressCallback: progressCallback(0.8) if update: self.mesh.update() else: self.meshData.calcNormals(1, 1) if progressCallback: progressCallback(0.8) if update: self.meshData.update() if progressCallback: progressCallback(1.0) self.callEvent('onChanged', HumanEvent(self, 'targets'))
def applyPose(self,savePath=None): if savePath: try: fileDescriptor = open(savePath,'w') except: print "Error in saving %s" %savePath self.resetTransf() self.character.restoreMesh() #restore the mesh without rotations self.loadTargets() if self.rotOrder == "xyz": rotSequence = [self.rotx,self.roty,self.rotz] if self.rotOrder == "xzy": rotSequence = [self.rotx,self.rotz,self.roty] if self.rotOrder == "zyx": rotSequence = [self.rotz,self.roty,self.rotx] if self.rotOrder == "zxy": rotSequence = [self.rotz,self.rotx,self.roty] if self.rotOrder == "yxz": rotSequence = [self.roty,self.rotx,self.rotz] if self.rotOrder == "yzx": rotSequence = [self.roty,self.rotz,self.rotx] traslPaths = self.trasl.keys() traslPaths.sort() scale = None for targetPath in traslPaths: if (scale == None): scale = algos3d.computeScale(self.oBoundingBox, targetPath, self.character.meshData) morphFactor = self.trasl[targetPath] algos3d.loadTranslationTarget(self.character, targetPath, morphFactor, None, 1, 0, scale) if savePath: fileDescriptor.write("%s %f\n" % (targetPath, morphFactor)) for rotation in rotSequence: rotPaths = rotation.keys() rotPaths.sort() for targetPath in rotPaths: morphFactor = rotation[targetPath] algos3d.loadRotationTarget(self.character.meshData, targetPath, morphFactor) if savePath: fileDescriptor.write("%s %f\n" % (targetPath, morphFactor)) self.character.meshData.calcNormals(facesToUpdate=[f for f in self.character.meshData.faces]) self.character.meshData.update() if savePath: fileDescriptor.close()
def _threadSafeApplyAllTargets(self): algos3d.resetObj(self.human.meshData) for (targetPath, morphFactor) in self.human.targetsDetailStack.iteritems(): algos3d.loadTranslationTarget(self.human.meshData, targetPath, morphFactor, None, 0, 0) self.human._updateOriginalMeshCoords(self.human.meshData.name, self.human.meshData.coord) self.human.updateProxyMesh() self.human.callEvent('onChanged', events3d.HumanEvent(self.human, 'targets')) self.human.refreshStaticMeshes() if self.human.isSubdivided(): self.human.updateSubdivisionMesh() self.human.mesh.calcNormals() self.human.mesh.update() else: self.human.meshData.calcNormals(1, 1) self.human.meshData.update() pass
def applyAllTargets(self, progressCallback=None, update=True): """ This method applies all targets, in function of age and sex **Parameters:** None. """ algos3d.resetObj(self.meshData) if progressCallback: progressCallback(0.0) progressVal = 0.0 progressIncr = 0.5 / (len(self.targetsDetailStack) + 1) for (targetPath, morphFactor) in self.targetsDetailStack.iteritems(): algos3d.loadTranslationTarget(self.meshData, targetPath, morphFactor, None, 0, 0) progressVal += progressIncr if progressCallback: progressCallback(progressVal) # Update all verts self.getSeedMesh().update() self.updateProxyMesh() if self.isSubdivided(): self.updateSubdivisionMesh() if progressCallback: progressCallback(0.7) self.mesh.calcNormals() if progressCallback: progressCallback(0.8) if update: self.mesh.update() else: self.meshData.calcNormals(1, 1) if progressCallback: progressCallback(0.8) if update: self.meshData.update() if progressCallback: progressCallback(1.0) self.callEvent('onChanged', events3d.HumanEvent(self, 'targets'))
def applyAllTargets(self, progressCallback=None, update=True): """ This method applies all targets, in function of age and sex **Parameters:** None. """ algos3d.resetObj(self.meshData) if progressCallback: progressCallback(0.0) progressVal = 0.0 progressIncr = 0.5 / (len(self.targetsDetailStack) + 1) for (targetPath, morphFactor) in list(self.targetsDetailStack.items()): algos3d.loadTranslationTarget(self.meshData, targetPath, morphFactor, None, 0, 0) progressVal += progressIncr if progressCallback: progressCallback(progressVal) # Update all verts self.getSeedMesh().update() self.updateProxyMesh() if self.isSubdivided(): self.updateSubdivisionMesh() if progressCallback: progressCallback(0.7) self.mesh.calcNormals() if progressCallback: progressCallback(0.8) if update: self.mesh.update() else: self.meshData.calcNormals(1, 1) if progressCallback: progressCallback(0.8) if update: self.meshData.update() if progressCallback: progressCallback(1.0) self.callEvent('onChanged', events3d.HumanEvent(self, 'targets'))
def updateValue(self, human, value, updateNormals=1): if self.verts is None and self.faces is None: self.buildLists() # Update detail state old_detail = [human.getDetail(target[0]) for target in self.targets] self.setValue(human, value) new_detail = [human.getDetail(target[0]) for target in self.targets] # Apply changes for target, old, new in zip(self.targets, old_detail, new_detail): if new == old: continue algos3d.loadTranslationTarget(human.meshData, target[0], new - old, None, 0, 0) # Update vertices if updateNormals: human.meshData.calcNormals(1, 1, self.verts, self.faces) human.meshData.update(self.verts, updateNormals) human.warpNeedReset = True human.callEvent('onChanging', events3d.HumanEvent(human, self.eventType))
def applyAllTargets(self, update=True): """ This method applies all targets, in function of age and sex **Parameters:** None. """ progress = Progress() progress(0.0, 0.5) # First call progress callback (which often processes events) before resetting mesh # so that mesh is not drawn in its reset state algos3d.resetObj(self.meshData) # Reset mesh is in rest pose # Apply targets to seedmesh coordinates itprog = Progress(len(self.targetsDetailStack)) for (targetPath, morphFactor) in self.targetsDetailStack.iteritems(): algos3d.loadTranslationTarget(self.meshData, targetPath, morphFactor, None, 0, 0) itprog.step() # Make sure self.getRestposeCoordinates is up-to-date directly (required for proxy fitting) self._updateOriginalMeshCoords(self.meshData.name, self.meshData.coord) # Update all verts self.getSeedMesh().update() self.updateProxyMesh() #self.traceStack(all=True) #self.traceBuffer(all=True, vertsToList=0) # Update skeleton joint positions if self.getSkeleton(): log.debug("Updating skeleton joint positions") self.getSkeleton().updateJoints(self.meshData) self.resetBakedAnimations() # TODO decide whether we require calling this manually, or whether animatedMesh automatically tracks updates of skeleton and updates accordingly self.callEvent('onChanged', events3d.HumanEvent(self, 'targets')) # Restore pose, and shadow copy of vertex positions # (We do this after onChanged event so that proxies are already updated) self.refreshStaticMeshes() # TODO document: an external plugin that modifies the rest pose verts outside of an onHumanChang(ing/ed) event should explicitly call this method on the human # Update subdivision mesh if self.isSubdivided(): progress(0.5, 0.7) self.updateSubdivisionMesh() progress(0.7, 0.8) self.mesh.calcNormals() progress(0.8, 0.99) if update: self.mesh.update() else: progress(0.5, 0.8) if not self.isPosed(): # Update seedmesh normals (if not already done so by posing) self.meshData.calcNormals(1, 1) progress(0.8, 0.99) if update: self.meshData.update() progress(1.0)
def rotateLimb(self, targetPath, morphFactor): targetPath1 = targetPath+".target" targetPath2 = targetPath+".rot" algos3d.loadTranslationTarget(self.meshData, targetPath1, morphFactor, None, 1, 0) algos3d.loadRotationTarget(self.meshData, targetPath2, morphFactor)