Beispiel #1
0
    def parse(cls, version_name: str):
        parser = argparse.ArgumentParser()
        parser.add_argument('--motion_path',
                            dest='motion_path',
                            help='input vmd',
                            type=str)
        parser.add_argument('--model_path',
                            dest='model_path',
                            help='model_path',
                            type=str)
        parser.add_argument('--loop_cnt',
                            dest='loop_cnt',
                            help='loop_cnt',
                            type=int)
        parser.add_argument('--interpolation',
                            dest='interpolation',
                            help='interpolation',
                            type=int)
        parser.add_argument("--verbose", type=int, default=20)

        args = parser.parse_args()

        # ログディレクトリ作成
        os.makedirs("log", exist_ok=True)

        MLogger.initialize(level=args.verbose, is_file=True)

        try:
            motion = VmdReader(args.motion_path).read_data()
            model = PmxReader(args.model_path).read_data()

            # 出力ファイルパス
            output_vmd_path = MFileUtils.get_output_smooth_vmd_path(
                motion.path, model.path, "", args.interpolation, args.loop_cnt,
                True)

            options = MSmoothOptions(\
                version_name=version_name, \
                logging_level=args.verbose, \
                motion=motion, \
                model=model, \
                output_path=output_vmd_path, \
                loop_cnt=args.loop_cnt, \
                interpolation=args.interpolation, \
                monitor=sys.stdout, \
                is_file=True, \
                outout_datetime=logger.outout_datetime, \
                max_workers=1)

            return options
        except SizingException as se:
            logger.error("スムージング処理が処理できないデータで終了しました。\n\n%s",
                         se.message,
                         decoration=MLogger.DECORATION_BOX)
        except Exception as e:
            logger.critical("スムージング処理が意図せぬエラーで終了しました。",
                            e,
                            decoration=MLogger.DECORATION_BOX)
Beispiel #2
0
    def test_separate(self):
        MLogger.initialize(level=MLogger.TEST, is_file=True)
        logger = MLogger(__name__, level=MLogger.TEST)

        # motion = VmdReader("D:\\MMD\\MikuMikuDance_v926x64\\UserFile\\Motion\\ダンス_1人\\桃源恋歌配布用motion moka\\ノーマルTda式用0-2000.vmd").read_data()
        model = PmxReader(
            "D:\\MMD\\MikuMikuDance_v926x64\\UserFile\\Model\\VOCALOID\\初音ミク\\Tda式初音ミク・アペンドVer1.10\\Tda式初音ミク・アペンド_Ver1.10.pmx",
            is_check=False).read_data()

        bone_axis_dict = {}
        for bone_name in ["左ひじ", "右ひじ"]:
            local_x_axis = model.get_local_x_axis("左ひじ")
            local_z_axis = MVector3D(0, 0, -1)
            local_y_axis = MVector3D.crossProduct(local_x_axis,
                                                  local_z_axis).normalized()
            bone_axis_dict[bone_name] = {
                "x": local_x_axis,
                "y": local_y_axis,
                "z": local_z_axis
            }

        new_ik_qq = MQuaternion.fromEulerAngles(24.58152072747821,
                                                135.9182003500461,
                                                56.36785502950723)
        ik_bone = model.bones["左ひじ"]
        fno = 394

        x_qq, y_qq, z_qq, yz_qq = MServiceUtils.separate_local_qq(
            fno, ik_bone.name, new_ik_qq, bone_axis_dict[ik_bone.name]["x"])

        logger.debug(
            f"now: {new_ik_qq.toEulerAngles()} -> {(y_qq * x_qq * z_qq).toEulerAngles()}"
        )
        logger.debug(
            f"now: x: {x_qq.toDegree()}, y: {y_qq.toDegree()}, z: {z_qq.toDegree()}"
        )

        for (x_sign, y_sign,
             z_sign) in list(itertools.product((1, -1), (1, -1), (1, -1))):
            new_x_qq = MQuaternion.fromAxisAndAngle(x_qq.vector(),
                                                    x_qq.toDegree() * x_sign)
            new_y_qq = MQuaternion.fromAxisAndAngle(y_qq.vector(),
                                                    y_qq.toDegree() * y_sign)
            new_z_qq = MQuaternion.fromAxisAndAngle(z_qq.vector(),
                                                    z_qq.toDegree() * z_sign)

            logger.debug(
                f"x: {x_sign}, y: {y_sign}, z: {z_sign} -> {(new_y_qq * new_x_qq * new_z_qq).toEulerAngles()}"
            )

        self.assertTrue(True)
import wx
import argparse
import numpy as np
import multiprocessing

from form.MainFrame import MainFrame
from utils.MLogger import MLogger

VERSION_NAME = "ver1.00"

# 指数表記なし、有効小数点桁数6、30を超えると省略あり、一行の文字数200
np.set_printoptions(suppress=True, precision=6, threshold=30, linewidth=200)

# Windowsマルチプロセス対策
multiprocessing.freeze_support()

if __name__ == '__main__':
    # 引数解釈
    parser = argparse.ArgumentParser()
    parser.add_argument("--verbose", default=20, type=int)
    args = parser.parse_args()

    # ロガー初期化
    MLogger.initialize(level=args.verbose, is_file=False)

    # GUI起動
    app = wx.App(False)
    frame = MainFrame(None, VERSION_NAME, args.verbose)
    frame.Show(True)
    app.MainLoop()
Beispiel #4
0
#
import os
import wx
import wx.lib.newevent
import sys

from form.panel.BasePanel import BasePanel
from form.parts.BaseFilePickerCtrl import BaseFilePickerCtrl
from form.parts.HistoryFilePickerCtrl import HistoryFilePickerCtrl
from form.parts.ConsoleCtrl import ConsoleCtrl
from form.parts.TargetBoneDialog import TargetBoneDialog
from form.worker.MultiJoinWorkerThread import MultiJoinWorkerThread
from utils import MFormUtils, MFileUtils
from utils.MLogger import MLogger  # noqa

logger = MLogger(__name__)
TIMER_ID = wx.NewId()

# イベント定義
(MultiJoinThreadEvent, EVT_SMOOTH_THREAD) = wx.lib.newevent.NewEvent()


class MultiJoinPanel(BasePanel):
    def __init__(self, frame: wx.Frame, multi_join: wx.Notebook, tab_idx: int):
        super().__init__(frame, multi_join, tab_idx)
        self.timer = wx.Timer(self, TIMER_ID)
        self.convert_multi_join_worker = None

        self.header_sizer = wx.BoxSizer(wx.VERTICAL)

        self.description_txt = wx.StaticText(self, wx.ID_ANY, u"モーションの指定ボーンの移動量XYZと回転量XYZを統合します。\n" \
Beispiel #5
0
# -*- coding: utf-8 -*-
#
import copy
import numpy as np  # noqa
import math  # noqa
from collections import OrderedDict

from mmd.PmxData import PmxModel, Vertex, Material, Bone, Morph, DisplaySlot, RigidBody, Joint  # noqa
from mmd.VmdData import VmdMotion, VmdBoneFrame, VmdCameraFrame, VmdInfoIk, VmdLightFrame, VmdMorphFrame, VmdShadowFrame, VmdShowIkFrame  # noqa
from module.MMath import MRect, MVector2D, MVector3D, MVector4D, MQuaternion, MMatrix4x4  # noqa
from module.MOptions import MOptions, MOptionsDataSet  # noqa
from module.MParams import BoneLinks  # noqa
from utils import MBezierUtils  # noqa
from utils.MLogger import MLogger  # noqa

logger = MLogger(__name__, level=1)


# IK計算
# target_pos: IKリンクの目的位置
# ik_links: IKリンク
def calc_IK(model: PmxModel,
            links: BoneLinks,
            motion: VmdMotion,
            fno: int,
            target_pos: MVector3D,
            ik_links: BoneLinks,
            max_count=10):
    for bone_name in list(ik_links.all().keys())[1:]:
        # bfをモーションに登録
        bf = motion.calc_bf(bone_name, fno)
Beispiel #6
0
    def parse(cls, version_name: str):
        parser = argparse.ArgumentParser()
        parser.add_argument("--motion_path",
                            required=True,
                            type=(lambda x: list(map(str, x.split(';')))))
        parser.add_argument("--org_model_path",
                            required=True,
                            type=(lambda x: list(map(str, x.split(';')))))
        parser.add_argument("--rep_model_path",
                            required=True,
                            type=(lambda x: list(map(str, x.split(';')))))
        parser.add_argument("--detail_stance_flg",
                            required=True,
                            type=(lambda x: list(map(int, x.split(';')))))
        parser.add_argument("--twist_flg",
                            required=True,
                            type=(lambda x: list(map(int, x.split(';')))))
        parser.add_argument("--arm_process_flg_avoidance", type=int, default=0)
        parser.add_argument("--avoidance_target_list",
                            default=[],
                            type=(lambda x: list(map(str, x.split(';')))))
        parser.add_argument("--arm_process_flg_alignment", type=int, default=0)
        parser.add_argument("--alignment_finger_flg", type=int, default=0)
        parser.add_argument("--alignment_floor_flg", type=int, default=0)
        parser.add_argument("--alignment_distance_wrist",
                            type=float,
                            default=1.7)
        parser.add_argument("--alignment_distance_finger",
                            type=float,
                            default=1.4)
        parser.add_argument("--alignment_distance_floor",
                            type=float,
                            default=1.8)
        parser.add_argument("--arm_check_skip_flg", type=int, default=0)
        parser.add_argument("--camera_motion_path", type=str, default="")
        parser.add_argument("--camera_org_model_path",
                            default=[],
                            type=(lambda x: list(map(str, x.split(';')))))
        parser.add_argument("--camera_offset_y",
                            default=[],
                            type=(lambda x: list(map(str, x.split(';')))))
        parser.add_argument("--verbose", type=int, default=20)

        args = parser.parse_args()

        # ログディレクトリ作成
        os.makedirs("log", exist_ok=True)

        MLogger.initialize(level=args.verbose, is_file=True)

        try:
            arm_process_flg_avoidance = True if args.arm_process_flg_avoidance == 1 else False
            arm_process_flg_alignment = True if args.arm_process_flg_alignment == 1 else False
            alignment_finger_flg = True if args.alignment_finger_flg == 1 else False
            alignment_floor_flg = True if args.alignment_floor_flg == 1 else False
            arm_check_skip_flg = True if args.arm_check_skip_flg == 1 else False

            arm_options = MArmProcessOptions(
                arm_process_flg_avoidance, \
                {0: [(a.strip() if len(a.strip()) > 0 else "") for a in args.avoidance_target_list]}, \
                arm_process_flg_alignment, \
                alignment_finger_flg, \
                alignment_floor_flg, \
                args.alignment_distance_wrist, \
                args.alignment_distance_finger, \
                args.alignment_distance_floor, \
                arm_check_skip_flg
            )

            # 元モデルが未指定の場合、空で処理する
            if not args.camera_org_model_path or (
                    len(args.camera_org_model_path) == 1
                    and len(args.camera_org_model_path[0]) == 0):
                args.camera_org_model_path = []
                for org_path in args.org_model_path:
                    args.camera_org_model_path.append("")

            # オフセットYが未指定の場合、0で処理する
            if not args.camera_offset_y or (len(args.camera_offset_y) == 1 and
                                            len(args.camera_offset_y[0]) == 0):
                args.camera_offset_y = []
                for org_path in args.org_model_path:
                    args.camera_offset_y.append(0)

            data_set_list = []
            for set_no, (motion_path, org_model_path, rep_model_path, detail_stance_flg_val, twist_flg_val, camera_org_model_path, camera_offset_y) in enumerate( \
                zip(args.motion_path, args.org_model_path, args.rep_model_path, args.detail_stance_flg, args.twist_flg, args.camera_org_model_path, \
                    args.camera_offset_y)): # noqa

                display_set_no = "【No.{0}】".format(set_no + 1)

                # モーションパス --------
                logger.info("%s 調整対象モーションVMD/VPDファイル 読み込み開始", display_set_no)

                file_name, input_ext = os.path.splitext(
                    os.path.basename(motion_path))
                if input_ext.lower() == ".vmd":
                    motion_reader = VmdReader(motion_path)
                elif input_ext.lower() == ".vpd":
                    motion_reader = VpdReader(motion_path)
                else:
                    raise SizingException(
                        "{0}.motion_path 読み込み失敗(拡張子不正): {1}".format(
                            display_set_no, os.path.basename(motion_path)))

                motion = motion_reader.read_data()

                logger.info("%s 調整対象モーションVMD/VPDファイル 読み込み成功 %s",
                            display_set_no, os.path.basename(motion_path))

                # 元モデル ----------
                logger.info("%s モーション作成元モデルPMXファイル 読み込み開始", display_set_no)

                file_name, input_ext = os.path.splitext(
                    os.path.basename(org_model_path))
                if input_ext.lower() == ".pmx":
                    org_model_reader = PmxReader(org_model_path)
                else:
                    raise SizingException(
                        "{0}.org_model_path 読み込み失敗(拡張子不正): {1}".format(
                            display_set_no, os.path.basename(org_model_path)))

                org_model = org_model_reader.read_data()

                logger.info("%s モーション作成元モデルPMXファイル 読み込み成功 %s", display_set_no,
                            os.path.basename(org_model_path))

                # 先モデル ----------
                logger.info("%s モーション変換先モデルPMXファイル 読み込み開始", display_set_no)

                file_name, input_ext = os.path.splitext(
                    os.path.basename(rep_model_path))
                if input_ext.lower() == ".pmx":
                    rep_model_reader = PmxReader(rep_model_path)
                else:
                    raise SizingException(
                        "{0}.rep_model_path 読み込み失敗(拡張子不正): {1}".format(
                            display_set_no, os.path.basename(rep_model_path)))

                rep_model = rep_model_reader.read_data()

                logger.info("%s モーション変換先モデルPMXファイル 読み込み成功 %s", display_set_no,
                            os.path.basename(rep_model_path))

                # 元モデル ----------
                if len(camera_org_model_path) > 0:
                    logger.info("%s カメラ作成元モデルPMXファイル 読み込み開始", display_set_no)

                    file_name, input_ext = os.path.splitext(
                        os.path.basename(camera_org_model_path))
                    if input_ext.lower() == ".pmx":
                        camera_org_model_reader = PmxReader(
                            camera_org_model_path)
                    else:
                        raise SizingException(
                            "{0}.camera_org_model_path 読み込み失敗(拡張子不正): {1}".
                            format(display_set_no,
                                   os.path.basename(camera_org_model_path)))

                    camera_org_model = camera_org_model_reader.read_data()

                    logger.info("%s カメラ作成元モデルPMXファイル 読み込み成功 %s",
                                display_set_no,
                                os.path.basename(camera_org_model_path))
                else:
                    # カメラ元モデルが未指定の場合、作成元モデルをそのまま流用
                    camera_org_model = org_model

                detail_stance_flg = True if detail_stance_flg_val == 1 else False
                twist_flg = True if twist_flg_val == 1 else False

                # 出力ファイルパス
                output_vmd_path = MFileUtils.get_output_vmd_path(
                    motion_path, rep_model_path, detail_stance_flg, twist_flg,
                    arm_process_flg_avoidance, arm_process_flg_alignment,
                    False, "", True)

                data_set = MOptionsDataSet(
                    motion, org_model, rep_model, output_vmd_path,
                    detail_stance_flg, twist_flg, [], camera_org_model,
                    camera_offset_y, [
                        "センターXZ補正", "上半身補正", "下半身補正", "足IK補正", "つま先IK補正",
                        "つま先補正", "肩補正", "センターY補正"
                    ])

                data_set_list.append(data_set)

            if len(args.camera_motion_path) != 0:
                # カメラパス --------
                logger.info("調整対象カメラVMDファイル 読み込み開始")

                file_name, input_ext = os.path.splitext(
                    os.path.basename(args.camera_motion_path))
                if input_ext.lower() == ".vmd":
                    camera_motion_reader = VmdReader(args.camera_motion_path)
                else:
                    raise SizingException(
                        "camera_motion_path 読み込み失敗(拡張子不正): %s",
                        os.path.basename(args.camera_motion_path))

                camera_motion = camera_motion_reader.read_data()
                camera_output_vmd_path = MFileUtils.get_output_camera_vmd_path(
                    args.camera_motion_path, data_set_list[0].rep_model.path,
                    "")

                logger.info("調整対象カメラVMD/VPDファイル 読み込み成功 %s",
                            os.path.basename(args.camera_motion_path))
            else:
                camera_motion = None
                camera_output_vmd_path = None

            options = MOptions(\
                version_name=version_name, \
                logging_level=args.verbose, \
                data_set_list=data_set_list, \
                arm_options=arm_options, \
                camera_motion=camera_motion, \
                camera_output_vmd_path=camera_output_vmd_path, \
                monitor=sys.stdout, \
                is_file=True, \
                outout_datetime=logger.outout_datetime, \
                max_workers=1)

            return options
        except SizingException as se:
            logger.error("サイジング処理が処理できないデータで終了しました。\n\n%s",
                         se.message,
                         decoration=MLogger.DECORATION_BOX)
        except Exception as e:
            logger.critical("サイジング処理が意図せぬエラーで終了しました。",
                            e,
                            decoration=MLogger.DECORATION_BOX)