def AddCorrected(fromFlexName, weight = 1.0, falloff_distance = 0.0, falloff_type = 'BELL'): global mesh global meshSel global temp_key global abs_correctors global rel_correctors if mesh == None: raise ValueError("The mesh is not set. Set it with OperateOnMesh first") if fromFlexName in abs_correctors: __MakeRelativeRecursive(fromFlexName) if falloff_distance > 0.0: bm = bmesh.new() bm.from_object(mesh, bpy.context.scene) meshSel = selections.BuildSoftSelection(bm, meshSel, falloff_distance, falloff_type, True) # Get sub-keys for shapeName in shapetools.YeildSubShapeNames(fromFlexName): if shapeName in abs_correctors: __MakeRelativeRecursive(fromFlexName) subkey = shapetools.FindShapeKey(mesh, shapeName) if subkey: shapetools.Add(mesh, meshSel, subkey, temp_key, weight) key = shapetools.FindShapeKey(mesh, fromFlexName) if key == None: raise ValueError('AddCorrected({}) failed: shape not found on mesh {}!'.format(fromFlexName, mesh.name)) shapetools.Add(mesh, meshSel, key, temp_key, weight) __DiscardSoftSel()
def __MakeRelativeRecursive(flexName): global mesh global abs_correctors fromFlex = shapetools.FindShapeKey(mesh, flexName) for shapeName in shapetools.YeildSubShapeNames(fromFlex.name): subKey = shapetools.FindShapeKey(mesh, shapeName) rank = shapetools.GetShapeRank(shapeName) if rank > 2: __MakeRelativeRecursive(shapeName) if subKey and rank > 1: shapetools.Corr_AbsToRel(mesh, mesh, subKey, subKey) abs_correctors.pop(fromFlex.name) else: return
def SaveDelta(flexName): global mesh global temp_key global abs_correctors global rel_correctors if mesh == None: raise ValueError("The mesh is not set. Set it with OperateOnMesh first") toKey = shapetools.FindShapeKey(mesh, flexName) if toKey: # Check that all sub-shapes are already relative: for name in shapetools.YeildSubShapeNames(toKey.name): flex = shapetools.FindShapeKey(mesh, name) if flex: if flex.name in abs_correctors: __MakeRelativeRecursive(fromFlexName) if flexName in override_correctors: # Don't overwrite overridden correctors, only convert them to deltas print ('Overridden', flexName) shapetools.Corr_AbsToRel(mesh, mesh, toKey, toKey) abs_correctors.remove(flexName) rel_correctors.append(flexName) return if toKey: print ('SaveDelta({}): shape replaced.'.format(flexName)) else: toKey = shapetools.AddShapeKey(mesh, flexName) shapetools.Corr_AbsToRel(mesh, mesh, toKey, toKey) exactFlexName = shapetools.FindShapeKey(mesh, flexName).name if exactFlexName in abs_correctors: abs_correctors.remove(exactFlexName)
def SetState(flexName): global mesh global meshSel if mesh == None: raise ValueError("The mesh is not set. Set it with OperateOnMesh first") flex = shapetools.FindShapeKey(mesh, flexName) if flex == None: raise ValueError('SetState({}) failed: flex not found on mesh {}!'.format(flexName, mesh.name)) bm = bmesh.new() bm.from_mesh(mesh.data) oldSel = meshSel meshSel = selections.SelectAll(bm) ResetState() Interp(flexName, 1.0) meshSel = oldSel
def DeleteDelta(Name): global mesh global abs_correctors global override_correctors if mesh == None: raise ValueError("The mesh is not set. Set it with OperateOnMesh first") shape = shapetools.FindShapeKey(mesh, Name) if not shape: shape = shapetools.FindShapeKey(mesh, SELECTOR_PREFIX + Name) if not shape: raise ValueError("DeleteDelta('{}') failed: not found.".format(Name)) # Check if it is a sub-shape nameSet = set(Name.split('_')) for shapekey in mesh.data.shape_keys.key_blocks: candNameSet = set(shapekey.name.split('_')) if nameSet in candNameSet: # It's safe to delete a sub-shape of an absolute corrector # Is this one absolute? if shapekey.name in abs_correctors: shapetools.RemoveShapeKey(mesh, shape.name) abs_correctors.pop(shape.name) else: raise ValueError("DeleteDelta({''}) failed: {} is a sub-shape of {} which is already in relative mode. You shouldn't delete sub-shapes of a relative corrector!".format(Name, Name, shapekey.name)) # It's not a sub-shape, then there's no problem at all shapetools.RemoveShapeKey(mesh, shape.name) if shapekey.name in abs_correctors: abs_correctors.pop(shape.name) if shapekey.name in override_correctors: override_correctors.pop(shape.name)
def Add(fromFlexName, weight = 1.0, falloff_distance = 0.0, falloff_type = 'BELL'): global mesh global meshSel global temp_key if mesh == None: raise ValueError("The mesh is not set. Set it with OperateOnMesh first") fromKey = shapetools.FindShapeKey(mesh, fromFlexName) toKey = temp_key if falloff_distance > 0.0: bm = bmesh.new() bm.from_object(mesh, bpy.context.scene) meshSel = selections.BuildSoftSelection(bm, meshSel, falloff_distance, falloff_type, True) if not fromKey: raise ValueError('Add({}) failed: flex not found on mesh {}!'.format(FlexName, mesh.name)) shapetools.Add(mesh, meshSel, fromKey, toKey, weight)
def Select(arg, name = ''): ''' MUST HANDLE Select("LowerLip") as well as Select("add", "LowerLip") This is ugly, though ''' global meshSel global mesh if mesh == None: raise ValueError("The mesh is not set. Set it with OperateOnMesh first") if arg.lower() in {'add', 'all', 'intersect', 'subtract'}: # Operation is specified operation = arg.lower() if shapetools.FindShapeKey(mesh, arg, True): raise ValueError("It's forbidden to have shapes with names 'add', 'all', 'intersect', 'subtract'!") if operation == 'all': for i in range(len(mesh.data.vertices)): meshSel[i] = 1.0 return if operation == 'none': meshSel = dict() return flex = shapetools.FindShapeKey(mesh, name, False) if not flex: flex = shapetools.FindShapeKey(mesh, SELECTOR_PREFIX + name, False) if not flex: raise ValueError('Select("{}") failed: not found.'.format(name)) deltas = shapetools.GetDeltaCoords(mesh, flex) # How does this one differ from Basis? secondarySel = dict() for i in range(len(deltas)): if abs(deltas[i].x) + abs(deltas[i].y) + abs(deltas[i].z) > 0.001: # i-th vtx is displaced secondarySel[i] = 1.0 if operation == 'add': meshSel = shapetools.SelectAdd(meshSel, secondarySel) return if operation == 'intersect': meshSel = shapetools.SelectIntersect(meshSel, secondarySel) return if operation == 'subtract': meshSel = shapetools.SelectSubtract(meshSel, secondarySel) return else: # Only flex name specified = new selection flex = shapetools.FindShapeKey(mesh, arg, True) if not flex: flex = shapetools.FindShapeKey(mesh, SELECTOR_PREFIX + arg, False) if not flex: raise ValueError('Select("{}") failed: not found.'.format(arg)) deltas = shapetools.GetDeltaCoords(mesh, flex) meshSel = dict() for i in range(len(deltas)): if abs(deltas[i].x) + abs(deltas[i].y) + abs(deltas[i].z) > 0.001: # i-th vtx is displaced meshSel[i] = 1.0 return