def execute(self, context): arm = context.active_object if not arm or arm.type != 'ARMATURE': self.report({'ERROR'}, 'Active object is not an armature object') return {'CANCELLED'} if self.type == 'APPLY': FnBone.apply_bone_local_axes(arm) #FnBone.apply_additional_transformation(arm) else: FnBone.load_bone_local_axes(arm, enable=(self.type=='LOAD')) return {'FINISHED'}
def _setAdditionalTransformBone(prop, value): arm = prop.id_data prop['is_additional_transform_dirty'] = True if value not in arm.pose.bones.keys(): prop['additional_transform_bone_id'] = -1 return pose_bone = arm.pose.bones[value] bone = FnBone(pose_bone) prop['additional_transform_bone_id'] = bone.bone_id
def _getAdditionalTransformBone(prop): arm = prop.id_data bone_id = prop.get('additional_transform_bone_id', -1) if bone_id < 0: return '' fnBone = FnBone.from_bone_id(arm, bone_id) if not fnBone: return '' return fnBone.pose_bone.name
def _set_bone(prop, value): root = prop.id_data fnModel = FnModel(root) arm = fnModel.armature() if value not in arm.pose.bones.keys(): prop['bone_id'] = -1 return pose_bone = arm.pose.bones[value] fnBone = FnBone(pose_bone) prop['bone_id'] = fnBone.bone_id
def _get_bone(prop): bone_id = prop.get('bone_id', -1) if bone_id < 0: return '' root = prop.id_data fnModel = FnModel(root) arm = fnModel.armature() fnBone = FnBone.from_bone_id(arm, bone_id) if not fnBone: return '' return fnBone.pose_bone.name
def execute(self, **args): if 'pmx' in args: self.__model = args['pmx'] else: self.__model = pmx.load(args['filepath']) self.__fixRepeatedMorphName() types = args.get('types', set()) clean_model = args.get('clean_model', False) remove_doubles = args.get('remove_doubles', False) self.__scale = args.get('scale', 1.0) self.__use_mipmap = args.get('use_mipmap', True) self.__sph_blend_factor = args.get('sph_blend_factor', 1.0) self.__spa_blend_factor = args.get('spa_blend_factor', 1.0) self.__fix_IK_links = args.get('fix_IK_links', False) self.__apply_bone_fixed_axis = args.get('apply_bone_fixed_axis', False) self.__translator = args.get('translator', None) logging.info('****************************************') logging.info(' mmd_tools.import_pmx module') logging.info('----------------------------------------') logging.info(' Start to load model data form a pmx file') logging.info(' by the mmd_tools.pmx modlue.') logging.info('') start_time = time.time() self.__createObjects() if 'MESH' in types: if clean_model: _PMXCleaner.clean(self.__model, 'MORPHS' not in types) if remove_doubles: self.__vertex_map = _PMXCleaner.remove_doubles( self.__model, 'MORPHS' not in types) self.__createMeshObject() self.__importVertices() self.__importMaterials() self.__importFaces() self.__meshObj.data.update() self.__assignCustomNormals() self.__storeVerticesSDEF() if 'ARMATURE' in types: # for tracking bone order if 'MESH' not in types: self.__createMeshObject() self.__importVertexGroup() self.__importBones() if args.get('rename_LR_bones', False): use_underscore = args.get('use_underscore', False) self.__renameLRBones(use_underscore) if self.__translator: self.__translateBoneNames() if self.__apply_bone_fixed_axis: FnBone.apply_bone_fixed_axis(self.__armObj) FnBone.apply_additional_transformation(self.__armObj) if 'PHYSICS' in types: self.__importRigids() self.__importJoints() if 'DISPLAY' in types: self.__importDisplayFrames() else: self.__rig.initialDisplayFrames() if 'MORPHS' in types: self.__importGroupMorphs() self.__importVertexMorphs() self.__importBoneMorphs() self.__importMaterialMorphs() self.__importUVMorphs() if self.__meshObj: self.__addArmatureModifier(self.__meshObj, self.__armObj) #bpy.context.scene.gravity[2] = -9.81 * 10 * self.__scale root = self.__root if 'ARMATURE' in types: root.mmd_root.show_armature = True if 'MESH' in types: root.mmd_root.show_meshes = True self.__targetScene.active_object = root root.select = True logging.info(' Finished importing the model in %f seconds.', time.time() - start_time) logging.info('----------------------------------------') logging.info(' mmd_tools.import_pmx module') logging.info('****************************************')
def __createEditBones(self, obj, pmx_bones): """ create EditBones from pmx file data. @return the list of bone names which can be accessed by the bone index of pmx data. """ editBoneTable = [] nameTable = [] specialTipBones = [] dependency_cycle_ik_bones = [] #for i, p_bone in enumerate(pmx_bones): # if p_bone.isIK: # if p_bone.target != -1: # t = pmx_bones[p_bone.target] # if p_bone.parent == t.parent: # dependency_cycle_ik_bones.append(i) from math import isfinite def _VectorXZY(v): return Vector(v).xzy if all(isfinite(n) for n in v) else Vector( (0, 0, 0)) with bpyutils.edit_object(obj) as data: for i in pmx_bones: bone = data.edit_bones.new(name=i.name) loc = _VectorXZY(i.location) * self.__scale bone.head = loc editBoneTable.append(bone) nameTable.append(bone.name) for i, (b_bone, m_bone) in enumerate(zip(editBoneTable, pmx_bones)): if m_bone.parent != -1: if i not in dependency_cycle_ik_bones: b_bone.parent = editBoneTable[m_bone.parent] else: b_bone.parent = editBoneTable[m_bone.parent].parent for b_bone, m_bone in zip(editBoneTable, pmx_bones): if isinstance(m_bone.displayConnection, int): if m_bone.displayConnection != -1: b_bone.tail = editBoneTable[ m_bone.displayConnection].head else: b_bone.tail = b_bone.head else: loc = _VectorXZY(m_bone.displayConnection) * self.__scale b_bone.tail = b_bone.head + loc for b_bone, m_bone in zip(editBoneTable, pmx_bones): if m_bone.isIK and m_bone.target != -1: logging.debug(' - checking IK links of %s', b_bone.name) b_target = editBoneTable[m_bone.target] for i in range(len(m_bone.ik_links)): b_bone_link = editBoneTable[m_bone.ik_links[i].target] if self.__fix_IK_links or b_bone_link.length < 0.001: b_bone_tail = b_target if i == 0 else editBoneTable[ m_bone.ik_links[i - 1].target] loc = b_bone_tail.head - b_bone_link.head if loc.length < 0.001: logging.warning(' ** unsolved IK link %s **', b_bone_link.name) elif b_bone_tail.parent != b_bone_link: logging.warning(' ** skipped IK link %s **', b_bone_link.name) elif (b_bone_link.tail - b_bone_tail.head).length > 1e-4: logging.debug(' * fix IK link %s', b_bone_link.name) b_bone_link.tail = b_bone_link.head + loc for b_bone, m_bone in zip(editBoneTable, pmx_bones): # Set the length of too short bones to 1 because Blender delete them. if b_bone.length < 0.001: if not self.__apply_bone_fixed_axis and m_bone.axis is not None: fixed_axis = Vector(m_bone.axis) if fixed_axis.length: b_bone.tail = b_bone.head + fixed_axis.xzy.normalized( ) * self.__scale else: b_bone.tail = b_bone.head + Vector( (0, 0, 1)) * self.__scale else: b_bone.tail = b_bone.head + Vector( (0, 0, 1)) * self.__scale if m_bone.displayConnection != -1 and m_bone.displayConnection != [ 0.0, 0.0, 0.0 ]: logging.debug(' * special tip bone %s, display %s', b_bone.name, str(m_bone.displayConnection)) specialTipBones.append(b_bone.name) for b_bone, m_bone in zip(editBoneTable, pmx_bones): if m_bone.localCoordinate is not None: FnBone.update_bone_roll(b_bone, m_bone.localCoordinate.x_axis, m_bone.localCoordinate.z_axis) elif FnBone.has_auto_local_axis(m_bone.name): FnBone.update_auto_bone_roll(b_bone) for b_bone, m_bone in zip(editBoneTable, pmx_bones): if isinstance(m_bone.displayConnection, int) and m_bone.displayConnection >= 0: t = editBoneTable[m_bone.displayConnection] if t.parent is None or t.parent != b_bone: logging.warning(' * disconnected: %s (%d)<> %s', b_bone.name, len(b_bone.children), t.name) continue if pmx_bones[m_bone.displayConnection].isMovable: logging.warning(' * disconnected: %s (%d)-> %s', b_bone.name, len(b_bone.children), t.name) continue if (b_bone.tail - t.head).length > 1e-4: logging.warning(' * disconnected: %s (%d)=> %s', b_bone.name, len(b_bone.children), t.name) continue t.use_connect = True return nameTable, specialTipBones
def applyAdditionalTransformConstraints(self): arm = self.armature() if arm: FnBone.apply_additional_transformation(arm)
def cleanAdditionalTransformConstraints(self): arm = self.armature() if arm: FnBone.clean_additional_transformation(arm)
def execute(self, context): arm = context.active_object FnBone.apply_auto_bone_roll(arm) return {'FINISHED'}
def _updateMMDBoneAdditionalTransform(prop, context): prop['is_additional_transform_dirty'] = True p_bone = context.active_pose_bone if p_bone and p_bone.mmd_bone.as_pointer() == prop.as_pointer(): FnBone.apply_additional_transformation(prop.id_data)
def _updateAdditionalTransformInfluence(prop, context): p_bone = context.active_pose_bone if p_bone and p_bone.mmd_bone.as_pointer() == prop.as_pointer(): FnBone(p_bone).update_additional_transform_influence() else: prop['is_additional_transform_dirty'] = True
def __createEditBones(self, obj, pmx_bones): """ create EditBones from pmx file data. @return the list of bone names which can be accessed by the bone index of pmx data. """ editBoneTable = [] nameTable = [] specialTipBones = [] dependency_cycle_ik_bones = [] #for i, p_bone in enumerate(pmx_bones): # if p_bone.isIK: # if p_bone.target != -1: # t = pmx_bones[p_bone.target] # if p_bone.parent == t.parent: # dependency_cycle_ik_bones.append(i) with bpyutils.edit_object(obj) as data: for i in pmx_bones: bone = data.edit_bones.new(name=i.name) loc = mathutils.Vector(i.location) * self.__scale * self.TO_BLE_MATRIX bone.head = loc editBoneTable.append(bone) nameTable.append(bone.name) for i, (b_bone, m_bone) in enumerate(zip(editBoneTable, pmx_bones)): if m_bone.parent != -1: if i not in dependency_cycle_ik_bones: b_bone.parent = editBoneTable[m_bone.parent] else: b_bone.parent = editBoneTable[m_bone.parent].parent for b_bone, m_bone in zip(editBoneTable, pmx_bones): if isinstance(m_bone.displayConnection, int): if m_bone.displayConnection != -1: b_bone.tail = editBoneTable[m_bone.displayConnection].head else: b_bone.tail = b_bone.head else: loc = mathutils.Vector(m_bone.displayConnection) * self.TO_BLE_MATRIX * self.__scale b_bone.tail = b_bone.head + loc for b_bone, m_bone in zip(editBoneTable, pmx_bones): if isinstance(m_bone.displayConnection, int) and m_bone.displayConnection >= 0: t = editBoneTable[m_bone.displayConnection] if t.parent is not None and t.parent == b_bone: t.use_connect = not pmx_bones[m_bone.displayConnection].isMovable for b_bone, m_bone in zip(editBoneTable, pmx_bones): if m_bone.isIK and m_bone.target != -1: logging.debug(' - checking IK links of %s', b_bone.name) b_target = editBoneTable[m_bone.target] for i in range(len(m_bone.ik_links)): b_bone_link = editBoneTable[m_bone.ik_links[i].target] if self.__fix_IK_links or b_bone_link.length < 0.001: b_bone_tail = b_target if i == 0 else editBoneTable[m_bone.ik_links[i-1].target] loc = b_bone_tail.head - b_bone_link.head if loc.length < 0.001: logging.warning(' ** unsolved IK link %s **', b_bone_link.name) elif b_bone_tail.parent != b_bone_link: logging.warning(' ** skipped IK link %s **', b_bone_link.name) elif (b_bone_link.tail - b_bone_tail.head).length > 1e-4: logging.debug(' * fix IK link %s', b_bone_link.name) b_bone_link.tail = b_bone_link.head + loc for b_bone, m_bone in zip(editBoneTable, pmx_bones): # Set the length of too short bones to 1 because Blender delete them. if b_bone.length < 0.001: loc = mathutils.Vector([0, 0, 1]) * self.__scale b_bone.tail = b_bone.head + loc if m_bone.displayConnection != -1 and m_bone.displayConnection != [0.0, 0.0, 0.0]: logging.debug(' * special tip bone %s, display %s', b_bone.name, str(m_bone.displayConnection)) specialTipBones.append(b_bone.name) for b_bone, m_bone in zip(editBoneTable, pmx_bones): if m_bone.localCoordinate is not None: FnBone.update_bone_roll(b_bone, m_bone.localCoordinate.x_axis, m_bone.localCoordinate.z_axis) return nameTable, specialTipBones