def invoke(self, context, event): # Get current pose selected = Get.selected(context, mirror=True) for src in selected: pose.base[repr(src)] = Get.matrix(src, basis=True) # Disable animation and get pose from lower layers base_anim = dict() for src in selected: obj = src.id_data anim = obj.animation_data if (anim) and (obj not in base_anim): tracks = list() if anim.use_tweak_mode: # Find the strip to disable for track in reversed(anim.nla_tracks): for _strip in track.strips: if _strip.active: strip = _strip break elif _strip.action == anim.action: # backup in case strip isn't "active" strip = _strip else: tracks.append((track, track.mute)) # track.mute = True continue break base_anim[obj] = [strip, strip.mute, tracks] strip.mute = True # anim.use_tweak_mode = False else: base_anim[obj] = [None, anim.action_influence, tracks] anim.action_influence = 0 utils.update(context) pose.reset[repr(src)] = Get.matrix(src, basis=True) # Re-enable animation for obj in base_anim: anim = obj.animation_data (strip, value, tracks) = base_anim[obj] if strip: # for (track, track_mute) in tracks: # track.mute = track_mute strip.mute = value # anim.use_tweak_mode = True else: anim.action_influence = value utils.update(context) # context.window_manager.modal_handler_add(self) # return {'RUNNING_MODAL'} return self.execute(context)
def store_matrix(mats=dict()): # Get the matrix in world space. # Save the matrix for src in srcs: mats[src] = Get.matrix(src) return mats
def get_driver_matrix(src, space='LOCAL_SPACE'): from zpy import Get if space == 'LOCAL_SPACE': mat = Get.matrix_local(src) elif space == 'TRANSFORM_SPACE': mat = Get.matrix(src, basis=True) else: # WORLD mat = Get.matrix(src) driver = type( '', (), dict( location=mat.to_translation(), rotation=mat.to_euler('XYZ' if src.rotation_mode in ( 'QUATERNION', 'AXIS_ANGLE') else src.rotation_mode), scale=mat.to_scale(), )) return driver
def execute(self, context): rig = context.active_object active = None if context.mode == 'PAINT_WEIGHT': for obj in context.selected_objects: if obj.type == 'ARMATURE': active = rig rig = obj Set.active(context, rig) # if rig.type =='ARMATURE' and context.mode != 'EDIT_ARMATURE': meshes = self.get_meshes(context, rig) bone1 = context.active_pose_bone # bone2 = context.selected_pose_bones[1] for bone2 in context.selected_pose_bones: if bone2 == bone1: continue found = None for mesh in meshes: utils.merge_vertex_groups( mesh, bone1.name, bone2.name, # If remove is False, and the bone stayed, it would be equivalent to transferring only partial weights remove=(self.mode == 'remove')) found = True # if found: # if self.mode == 'hide': # bone2.hide = True # elif self.mode == 'show': # bone2.hide = False # elif self.mode == 'remove': if (found and self.mode == 'remove'): for ch in bone2.id_data.children: if (ch.parent_type == 'BONE') and (ch.parent_bone == bone2.name): mat = Get.matrix(ch) ch.parent_bone = bone1.name Set.matrix(ch, mat) name2 = bone2.name Set.mode(context, mode='EDIT') bone2 = rig.data.edit_bones[name2] rig.data.edit_bones.remove(bone2) Set.mode(context, mode='POSE') if active: Set.active(context, active) return {'FINISHED'}
def rigify_to_meta(rigify, metarig): """Retarget Rigify meshes to Metarig""" pose = (metarig.data.pose_position, rigify.data.pose_position) (metarig.data.pose_position, rigify.data.pose_position) = ('REST', 'REST') utils.update(bpy.context) for obj in bpy.data.objects: if Is.curve(obj) and obj.name.startswith(rigify.name + '-MCH-'): # Splines from angavrilov's spline rig continue for mod in obj.modifiers: if hasattr(mod, 'object') and mod.object == rigify: mod.object = metarig metafy_vgroups(rigify, obj, metarig) if (obj.parent == rigify): rigify_bone = obj.parent_bone if rigify_bone: if rigify_bone.startswith('DEF-'): meta_bone = rigify_bone[4:] else: meta_bone = rigify_bone if meta_bone in metarig.data.bones: mat = Get.matrix(obj) # pmat = obj.matrix_parent_inverse.copy() obj.parent = metarig obj.parent_bone = meta_bone # obj.matrix_parent_inverse = pmat Set.matrix(obj, mat) else: obj.parent = metarig if Is.mesh(obj): meshes = {obj.data} if hasattr(obj, 'variants'): # The LoDs store the mesh datas and drivers without an object for layer in obj.variants.layers: if layer.mesh: meshes.add(layer.mesh) for lod in layer.lods: meshes.add(lod.mesh) for mesh in meshes: if mesh: rigify_drivers(rigify, metarig, mesh.shape_keys) for mat in bpy.data.materials: rigify_drivers(rigify, metarig, mat) rigify_drivers(rigify, metarig, mat.node_tree) (metarig.data.pose_position, rigify.data.pose_position) = pose
def hook(curve, target, index): mod = curve.modifiers.new("Modifier Name", 'HOOK') mod.object = target.id_data if Is.posebone(target): mod.subtarget = target.name # modifier sets indices (which are the points + their two handles) mod_points = (index * 3 + 0, index * 3 + 1, index * 3 + 2) mod.vertex_indices_set(mod_points) mod.matrix_inverse = Get.matrix(target).inverted_safe() # Set the matrix, to allow the hook to stay with the "posed" bones # Don't get target's matrix, because it hasn't been updated yet mod.show_expanded = False return mod
def meta_to_rigify(metarig, rigify): """Retarget Metarig meshes to Rigify rig""" pose = (metarig.data.pose_position, rigify.data.pose_position) (metarig.data.pose_position, rigify.data.pose_position) = ('REST', 'REST') utils.update(bpy.context) for obj in bpy.data.objects: for mod in obj.modifiers: if hasattr(mod, 'object') and mod.object == metarig: mod.object = rigify rigify_vgroups(metarig, rigify, obj) if obj.parent == metarig: if obj.parent_bone: rigify_bone = vg_names.get(obj.parent_bone, False) if rigify_bone is False: rigify_bone = 'DEF-' + obj.parent_bone if rigify_bone and rigify_bone in rigify.data.bones: mat = Get.matrix(obj) # pmat = obj.matrix_parent_inverse.copy() obj.parent = rigify obj.parent_bone = rigify_bone # obj.matrix_parent_inverse = pmat Set.matrix(obj, mat) else: obj.parent = rigify if Is.mesh(obj): meshes = {obj.data} if hasattr(obj, 'variants'): # The LoDs store the mesh datas and drivers without an object for layer in obj.variants.layers: if layer.mesh: meshes.add(layer.mesh) for lod in layer.lods: meshes.add(lod.mesh) for mesh in meshes: if mesh: rigify_drivers(metarig, rigify, mesh.shape_keys) for mat in bpy.data.materials: rigify_drivers(metarig, rigify, mat) rigify_drivers(metarig, rigify, mat.node_tree) (metarig.data.pose_position, rigify.data.pose_position) = pose
def get_pole(pole, line): from math import radians from mathutils import Matrix bone["pole_vector"] = 0 pole = get(pole) line = get(line) # lock rotation/scale, since bone only suppose to be moved pole.rotation_mode = 'XYZ' pole.lock_rotation_w = True pole.lock_rotation = (True, True, True) pole.lock_scale = (True, True, True) utils.update(bpy.context) mat = getmat(pole, line) @ Matrix.Rotation(radians(180), 4, 'X') rotcopy(pole, mat) utils.update(bpy.context) poles[pole.name] = Get.matrix(pole) rotcopy(pole, Matrix()) pole.location = (0, 0, 0)
def generate(self, context, ob, rig, coll): scn = context.scene faceverts, vertfaces = self.getVertFaces(ob) majors = {} skip = [] for vgrp in ob.vertex_groups: if vgrp.name in rig.data.bones: majors[vgrp.index] = [] else: skip.append(vgrp.index) for v in ob.data.vertices: wmax = 1e-3 vbest = None for g in v.groups: if g.weight > wmax and g.group not in skip: wmax = g.weight vbest = v gbest = g.group if vbest is not None: majors[gbest].append(vbest) roots = [bone for bone in rig.data.bones if bone.parent is None] for bone in roots: self.remapBones(bone, ob.vertex_groups, majors, None) face_mats = dict() if ob.data.materials: for f in ob.data.polygons: face_mats[( f.area, *f.center, *f.normal)] = ob.material_slots[f.material_index].material nobs = [] for vgrp in ob.vertex_groups: if (vgrp.name not in rig.pose.bones.keys() or vgrp.index not in majors.keys()): continue fnums = [] for v in majors[vgrp.index]: for fn in vertfaces[v.index]: fnums.append(fn) fnums = list(set(fnums)) nverts = [] nfaces = [] for fn in fnums: f = ob.data.polygons[fn] nverts += f.vertices nfaces.append(f.vertices) if not nfaces: continue nverts = list(set(nverts)) nverts.sort() bone = rig.pose.bones[vgrp.name] head = bone.bone.head_local # verts = [ob.data.vertices[vn].co - head for vn in nverts] verts = [ob.data.vertices[vn].co for vn in nverts] assoc = dict([(vn, n) for n, vn in enumerate(nverts)]) faces = [] for fverts in nfaces: faces.append([assoc[vn] for vn in fverts]) name = ob.name[0:3] + "_" + vgrp.name me = bpy.data.meshes.new(name) me.from_pydata(verts, [], faces) nob = bpy.data.objects.new(name, me) coll.objects.link(nob) nob.DazMannequin = True # nob.location = head # nob.lock_location = nob.lock_rotation = nob.lock_scale = (True,True,True) nobs.append((nob, bone)) if ob.data.materials: for b in me.polygons: mat_i = face_mats.get((b.area, *b.center, *b.normal)) if mat_i is None: # Add an empty material if mat is None: from random import random mat = bpy.data.materials.new(ob.name + 'Mannequin') mat.diffuse_color[0:3] = (random(), random(), random()) # for omat in ob.data.materials: # mat.diffuse_color = omat.diffuse_color if mat.name not in me.materials: me.materials.append(mat) continue if mat_i.name not in me.materials: me.materials.append(mat_i) for (i, mat_c) in enumerate(nob.material_slots): if mat_c.material == mat_i: b.material_index = i break else: if mat is None: from random import random mat = bpy.data.materials.new(ob.name + 'Mannequin') mat.diffuse_color[0:3] = (random(), random(), random()) # for omat in ob.data.materials: # mat.diffuse_color = omat.diffuse_color if mat.name not in me.materials: me.materials.append(mat) utils.update(context) for (nob, bone) in nobs: mat = Get.matrix(nob) # pmat = nob.matrix_parent_inverse.copy() nob.parent = rig nob.parent_bone = bone.name nob.parent_type = 'BONE' # nob.matrix_parent_inverse = pmat Set.matrix(nob, mat)