Пример #1
0
    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'}
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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
Пример #6
0
    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('****************************************')
Пример #7
0
    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
Пример #8
0
 def applyAdditionalTransformConstraints(self):
     arm = self.armature()
     if arm:
         FnBone.apply_additional_transformation(arm)
Пример #9
0
 def cleanAdditionalTransformConstraints(self):
     arm = self.armature()
     if arm:
         FnBone.clean_additional_transformation(arm)
Пример #10
0
 def execute(self, context):
     arm = context.active_object
     FnBone.apply_auto_bone_roll(arm)
     return {'FINISHED'}
Пример #11
0
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)
Пример #12
0
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
Пример #13
0
    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