def test_split_bf_by_fno(self): motion = VmdReader(u"test/data/補間曲線テスト01.vmd").read_data() model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/ダミーボーン頂点追加2.pmx" ).read_data() target_bone_name = "ボーン01" prev_bf = motion.bones[target_bone_name][0] next_bf = motion.bones[target_bone_name][15] motion.split_bf_by_fno(target_bone_name, prev_bf, next_bf, 8) for fno in motion.get_bone_fnos(target_bone_name): bf = motion.bones[target_bone_name][fno] print("fno: %s ------------" % bf.fno) print("position: %s" % bf.position) print("rotation: %s" % bf.rotation.toEulerAngles4MMD()) print("int move x: %s, %s, %s, %s" % (bf.interpolation[MBezierUtils.MX_x1_idxs[3]], bf.interpolation[MBezierUtils.MX_y1_idxs[3]], \ bf.interpolation[MBezierUtils.MX_x2_idxs[3]], bf.interpolation[MBezierUtils.MX_y2_idxs[3]])) print("int move y: %s, %s, %s, %s" % (bf.interpolation[MBezierUtils.MY_x1_idxs[3]], bf.interpolation[MBezierUtils.MY_y1_idxs[3]], \ bf.interpolation[MBezierUtils.MY_x2_idxs[3]], bf.interpolation[MBezierUtils.MY_y2_idxs[3]])) print("int move z: %s, %s, %s, %s" % (bf.interpolation[MBezierUtils.MZ_x1_idxs[3]], bf.interpolation[MBezierUtils.MZ_y1_idxs[3]], \ bf.interpolation[MBezierUtils.MZ_x2_idxs[3]], bf.interpolation[MBezierUtils.MZ_y2_idxs[3]])) print("int rot: %s, %s, %s, %s" % (bf.interpolation[MBezierUtils.R_x1_idxs[3]], bf.interpolation[MBezierUtils.R_y1_idxs[3]], \ bf.interpolation[MBezierUtils.R_x2_idxs[3]], bf.interpolation[MBezierUtils.R_y2_idxs[3]])) data_set = MOptionsDataSet( motion, model, model, "E:/WebDownload/test_split_bf_by_fno_{0:%Y%m%d_%H%M%S}.vmd".format( datetime.now()), False, False) VmdWriter(data_set).write() print(data_set.output_vmd_path)
def not_test_stance_shoulder_02(self): motion = VmdReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Motion/_VMDサイジング/鳳仙花/鳳仙花mkmk髭切007bミュ第一_0-2000.vmd" ).read_data() model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/刀剣乱舞/107_髭切/髭切【刀ミュ】mkmk008d 刀剣乱舞/髭切【刀ミュ】mkmk008d/髭切【刀ミュ3】mkmk008d_鳳仙花.pmx" ).read_data() # 傾きパターン test_slope_param = ["arm_name", "shoulder_name", "首根元"] all_slope_test_params = list( itertools.product(test_slope_param, repeat=2)) slope_test_params = [(x00, x01) for (x00, x01) in all_slope_test_params if x00 != x01] print(len(slope_test_params)) # 数値パターン test_number_param = [0, -1, 1] all_number_test_params = list( itertools.product(test_number_param, repeat=3)) number_test_params = [(x00, x01, x02) for (x00, x01, x02) in all_number_test_params if x00 == 0 or x01 == 0 or x02 == 0] print(len(number_test_params)) target_test_params = list( itertools.product(slope_test_params, number_test_params)) print(len(target_test_params)) random.shuffle(target_test_params) for params in target_test_params: print(params) copy_motion = motion.copy() dataset = MOptionsDataSet(copy_motion, model, model, "", False, False) dataset.test_params = params options = MOptions("", "", [dataset]) service = StanceService(options) service.adjust_shoulder_stance(0, dataset) print("stance: %s" % dataset.motion.bones["右肩"][1625].rotation.toEulerAngles()) print("original: %s" % motion.bones["右肩"][1625].rotation.toEulerAngles()) self.assertTrue(True)
def test_stance_shoulder_09(self): # motion = VmdReader("E:/MMD/MikuMikuDance_v926x64/Work/202001_sizing/肩/折岸みつ肩2.vmd").read_data() # org_model = PmxReader("D:/MMD/MikuMikuDance_v926x64/UserFile/Model/オリジナル/折岸みつ つみだんご/折岸みつ.pmx").read_data() # rep_model = PmxReader("D:/MMD/MikuMikuDance_v926x64/UserFile/Model/刀剣乱舞/055_鶯丸/鶯丸 さばそ式ver1.75配布用/さばそ式鶯丸(通常・刀無)ver1.75.pmx").read_data() motion = VmdReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Motion/運動/バレエっぽいターン グレイ/バレエっぽいターン.vmd" ).read_data() org_model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/VOCALOID/初音ミク/あぴミク01_Ver.1.04 アレン・ベルル/Appearance Miku_01_Ver.1.04_準標準.pmx" ).read_data() rep_model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/VOCALOID/初音ミク/底辺508式初音ミク_素足モデル せんと(鈍棒P)/miku_v3(素足_袖なし).pmx" ).read_data() # 数値パターン test_number_param = [0, -1, 1] all_number_test_params = list( itertools.product(test_number_param, repeat=3)) number_test_params = [(x00, x01, x02) for (x00, x01, x02) in all_number_test_params if x00 == 0 or x01 == 0 or x02 == 0] print(len(number_test_params)) for params in number_test_params: print(params) copy_motion = motion.copy() dataset = MOptionsDataSet(copy_motion, org_model, rep_model, "", True, False, []) dataset.test_params = params options = MOptions("", "", [dataset], None, None, False, None) service = StanceService(options) service.adjust_shoulder_stance(0, dataset) print("right stance: %s" % dataset.motion.bones["右肩"][0].rotation.toEulerAngles()) print("right original: %s" % motion.bones["右肩"][0].rotation.toEulerAngles()) print("left stance: %s" % dataset.motion.bones["左肩"][0].rotation.toEulerAngles()) print("left original: %s" % motion.bones["左肩"][0].rotation.toEulerAngles()) pass self.assertTrue(True)
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)
def not_test_adjust_upper_stance01(self): motion = VmdReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Motion/運動/バレエっぽいターン グレイ/バレエっぽいターン.vmd" ).read_data() org_model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/VOCALOID/初音ミク/あぴミク01_Ver.1.04 アレン・ベルル/Appearance Miku_01_Ver.1.04_準標準.pmx" ).read_data() rep_model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/VOCALOID/初音ミク/底辺508式初音ミク_素足モデル せんと(鈍棒P)/miku_v3(素足_袖なし).pmx" ).read_data() # 数値パターン test_number_param = [0, -1, 1] all_number_test_params = list( itertools.product(test_number_param, repeat=3)) number_test_params = [(x00, x01, x02) for (x00, x01, x02) in all_number_test_params if x00 == 0 or x01 == 0 or x02 == 0] print(len(number_test_params)) for params in number_test_params: print(params) copy_motion = motion.copy() dataset = MOptionsDataSet(copy_motion, org_model, rep_model, "", True, False, []) dataset.test_params = params options = MOptions("", "", [dataset], None, None, False, None) service = StanceService(options) service.adjust_upper_stance(0, dataset) print("stance: %s" % dataset.motion.bones["上半身"][44].rotation.toEulerAngles()) print("original: %s" % motion.bones["上半身"][44].rotation.toEulerAngles()) print("original: %s" % motion.bones["上半身"][0].rotation.toEulerAngles()) self.assertTrue(True)
def get_model_name(self): try: if self.picker.is_aster: base_file_path = self.picker.file_ctrl.GetPath() if os.path.exists(base_file_path): file_path_list = [base_file_path] else: file_path_list = [p for p in glob.glob(base_file_path) if os.path.isfile(p)] if len(file_path_list) == 0: return "取得失敗" file_path = file_path_list[0] else: file_path = self.picker.file_ctrl.GetPath() file_name, input_ext = os.path.splitext(os.path.basename(file_path)) model_name = "未設定" if input_ext.lower() == ".vmd": reader = VmdReader(file_path) elif input_ext.lower() == ".vpd": reader = VpdReader(file_path) elif input_ext.lower() == ".pmx": reader = PmxReader(file_path) else: return "対象外拡張子" try: model_name = reader.read_model_name() except Exception: model_name = "取得失敗" logger.test("model_name: %s, ", model_name) return model_name except Exception as e: logger.test("get_model_name 失敗", e) return "取得失敗"
def test_vmd_output(self): motion = VmdReader(u"test/data/補間曲線テスト01.vmd").read_data() model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/ダミーボーン頂点追加2.pmx" ).read_data() for n in range(100): fill_fno = 8 fill_bone_name = "右腕{0:03d}".format(n) fill_bf = motion.calc_bf(fill_bone_name, fill_fno) fill_bf.key = True motion.bones[fill_bone_name][fill_fno] = fill_bf data_set = MOptionsDataSet( motion, model, model, "E:/WebDownload/test_vmd_output_{0:%Y%m%d_%H%M%S}.vmd".format( datetime.now()), False, False) VmdWriter(data_set).write() print(data_set.output_vmd_path)
def test_calc_relative_rotation01(self): motion = VmdReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Motion/ダンス_1人/ドラマツルギー motion 配布用 moka/ドラマツルギー_0-500.vmd" ).read_data() model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/VOCALOID/初音ミク/Tda式デフォ服ミク_ver1.1 金子卵黄/Tda式初音ミク_デフォ服ver.pmx" ).read_data() # -------------- links = model.create_link_2_top_one("右手首") # --------- add_qs = MServiceUtils.calc_relative_rotation(model, links, motion, 414) # SIZING_ROOT_BONE self.assertAlmostEqual(add_qs[0].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[0].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[0].toEulerAngles4MMD().z(), 0, delta=0.1) # 全ての親 self.assertAlmostEqual(add_qs[1].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[1].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[1].toEulerAngles4MMD().z(), 0, delta=0.1) # センター self.assertAlmostEqual(add_qs[2].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[2].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[2].toEulerAngles4MMD().z(), 0, delta=0.1) # グルーブ self.assertAlmostEqual(add_qs[3].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[3].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[3].toEulerAngles4MMD().z(), 0, delta=0.1) # 腰 self.assertAlmostEqual(add_qs[4].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[4].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[4].toEulerAngles4MMD().z(), 0, delta=0.1) # 上半身 self.assertAlmostEqual(add_qs[5].toEulerAngles4MMD().x(), -13.2, delta=0.1) self.assertAlmostEqual(add_qs[5].toEulerAngles4MMD().y(), -5.0, delta=0.1) self.assertAlmostEqual(add_qs[5].toEulerAngles4MMD().z(), 1.1, delta=0.1) # 上半身2 self.assertAlmostEqual(add_qs[6].toEulerAngles4MMD().x(), -9.1, delta=0.1) self.assertAlmostEqual(add_qs[6].toEulerAngles4MMD().y(), -7.1, delta=0.1) self.assertAlmostEqual(add_qs[6].toEulerAngles4MMD().z(), 3.7, delta=0.1) # 首根元 self.assertAlmostEqual(add_qs[7].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[7].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[7].toEulerAngles4MMD().z(), 0, delta=0.1) # 右肩P self.assertAlmostEqual(add_qs[8].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[8].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[8].toEulerAngles4MMD().z(), 0, delta=0.1) # 右肩 self.assertAlmostEqual(add_qs[9].toEulerAngles4MMD().x(), -1.7, delta=0.1) self.assertAlmostEqual(add_qs[9].toEulerAngles4MMD().y(), 14.4, delta=0.1) self.assertAlmostEqual(add_qs[9].toEulerAngles4MMD().z(), 13.5, delta=0.1) # 右肩C self.assertAlmostEqual(add_qs[10].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[10].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[10].toEulerAngles4MMD().z(), 0, delta=0.1) # 右腕 self.assertAlmostEqual(add_qs[11].toEulerAngles4MMD().x(), -5.0, delta=0.1) self.assertAlmostEqual(add_qs[11].toEulerAngles4MMD().y(), 58.9, delta=0.1) self.assertAlmostEqual(add_qs[11].toEulerAngles4MMD().z(), 11.5, delta=0.1) # 右腕捩 self.assertAlmostEqual(add_qs[12].toEulerAngles4MMD().x(), -0.1, delta=0.1) self.assertAlmostEqual(add_qs[12].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[12].toEulerAngles4MMD().z(), 0, delta=0.1) # 右ひじ self.assertAlmostEqual(add_qs[13].toEulerAngles4MMD().x(), 30.6, delta=0.1) self.assertAlmostEqual(add_qs[13].toEulerAngles4MMD().y(), 48.3, delta=0.1) self.assertAlmostEqual(add_qs[13].toEulerAngles4MMD().z(), 14.0, delta=0.1) # 右ひじ下(スルー) self.assertAlmostEqual(add_qs[14].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[14].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[14].toEulerAngles4MMD().z(), 0, delta=0.1) # 右手捩 self.assertAlmostEqual(add_qs[15].toEulerAngles4MMD().x(), -7.1, delta=0.1) self.assertAlmostEqual(add_qs[15].toEulerAngles4MMD().y(), 5.4, delta=0.1) self.assertAlmostEqual(add_qs[15].toEulerAngles4MMD().z(), -0.2, delta=0.1) # 右手首 self.assertAlmostEqual(add_qs[16].toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(add_qs[16].toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(add_qs[16].toEulerAngles4MMD().z(), -37.8, delta=0.1)
def execute(self): logging.basicConfig(level=self.options.logging_level, format="%(message)s [%(module_name)s]") try: service_data_txt = "VMDサイジング処理実行\n------------------------\nexeバージョン: {version_name}\n".format(version_name=self.options.version_name) for data_set_idx, data_set in enumerate(self.options.data_set_list): service_data_txt = "{service_data_txt}\n【No.{no}】 --------- \n".format(service_data_txt=service_data_txt, no=(data_set_idx+1)) # noqa service_data_txt = "{service_data_txt} モーション: {motion}\n".format(service_data_txt=service_data_txt, motion=os.path.basename(data_set.motion.path)) # noqa service_data_txt = "{service_data_txt} 作成元モデル: {trace_model} ({model_name})\n".format(service_data_txt=service_data_txt, trace_model=os.path.basename(data_set.org_model.path), model_name=data_set.org_model.name) # noqa service_data_txt = "{service_data_txt} 変換先モデル: {replace_model} ({model_name})\n".format(service_data_txt=service_data_txt, replace_model=os.path.basename(data_set.rep_model.path), model_name=data_set.rep_model.name) # noqa if data_set.camera_org_model: service_data_txt = "{service_data_txt} カメラ作成元モデル: {trace_model} ({model_name})\n".format(service_data_txt=service_data_txt, trace_model=os.path.basename(data_set.camera_org_model.path), model_name=data_set.camera_org_model.name) # noqa service_data_txt = "{service_data_txt} Yオフセット: {camera_offset_y}\n".format(service_data_txt=service_data_txt, camera_offset_y=data_set.camera_offset_y) # noqa service_data_txt = "{service_data_txt} スタンス追加補正有無: {detail_stance_flg}\n".format(service_data_txt=service_data_txt, detail_stance_flg=data_set.detail_stance_flg) # noqa if data_set.detail_stance_flg: # スタンス追加補正がある場合、そのリストを表示 service_data_txt = "{service_data_txt} {detail_stance_flg}\n".format(service_data_txt=service_data_txt, detail_stance_flg=", ".join(data_set.selected_stance_details)) # noqa service_data_txt = "{service_data_txt} 捩り分散有無: {twist_flg}\n".format(service_data_txt=service_data_txt, twist_flg=data_set.twist_flg) # noqa morph_list = [] for (org_morph_name, rep_morph_name, morph_ratio) in data_set.morph_list: morph_list.append(f"{org_morph_name} → {rep_morph_name} ({morph_ratio})") morph_txt = ", ".join(morph_list) service_data_txt = "{service_data_txt} モーフ置換: {morph_txt}\n".format(service_data_txt=service_data_txt, morph_txt=morph_txt) # noqa if data_set_idx in self.options.arm_options.avoidance_target_list: service_data_txt = "{service_data_txt} 対象剛体名: {avoidance_target}\n".format(service_data_txt=service_data_txt, avoidance_target=", ".join(self.options.arm_options.avoidance_target_list[data_set_idx])) # noqa service_data_txt = "{service_data_txt}\n--------- \n".format(service_data_txt=service_data_txt) # noqa if self.options.arm_options.avoidance: service_data_txt = "{service_data_txt}剛体接触回避: {avoidance}\n".format(service_data_txt=service_data_txt, avoidance=self.options.arm_options.avoidance) # noqa if self.options.arm_options.alignment: service_data_txt = "{service_data_txt}手首位置合わせ: {alignment} ({distance})\n".format(service_data_txt=service_data_txt, alignment=self.options.arm_options.alignment, distance=self.options.arm_options.alignment_distance_wrist) # noqa service_data_txt = "{service_data_txt}指位置合わせ: {alignment} ({distance})\n".format(service_data_txt=service_data_txt, alignment=self.options.arm_options.alignment_finger_flg, distance=self.options.arm_options.alignment_distance_finger) # noqa service_data_txt = "{service_data_txt}床位置合わせ: {alignment} ({distance})\n".format(service_data_txt=service_data_txt, alignment=self.options.arm_options.alignment_floor_flg, distance=self.options.arm_options.alignment_distance_floor) # noqa if self.options.arm_options.arm_check_skip_flg: service_data_txt = "{service_data_txt}腕チェックスキップ: {arm_check_skip}\n".format(service_data_txt=service_data_txt, arm_check_skip=self.options.arm_options.arm_check_skip_flg) # noqa if self.options.camera_motion: service_data_txt = "{service_data_txt}カメラ: {camera}({camera_length})\n".format(service_data_txt=service_data_txt, camera=os.path.basename(self.options.camera_motion.path), camera_length=self.options.camera_length) # noqa service_data_txt = "{service_data_txt} 距離制限: {camera_length}{camera_length_umlimit}\n".format(service_data_txt=service_data_txt, camera_length=self.options.camera_length, camera_length_umlimit=("" if self.options.camera_length < 5 else "(無制限)")) # noqa service_data_txt = "{service_data_txt}------------------------".format(service_data_txt=service_data_txt) # noqa if self.options.total_process_ctrl: self.options.total_process_ctrl.write(str(self.options.total_process)) self.options.now_process_ctrl.write("0") self.options.now_process_ctrl.write(str(self.options.now_process)) logger.info(service_data_txt, decoration=MLogger.DECORATION_BOX) if self.options.is_sizing_camera_only is True: # カメラサイジングのみ実行する場合、出力結果VMDを読み込む for data_set_idx, data_set in enumerate(self.options.data_set_list): reader = VmdReader(data_set.output_vmd_path) data_set.motion = reader.read_data() else: for data_set_idx, data_set in enumerate(self.options.data_set_list): # 足IKのXYZの比率 data_set.original_xz_ratio, data_set.original_y_ratio = MServiceUtils.calc_leg_ik_ratio(data_set) # 足IKの比率再計算 self.options.calc_leg_ratio() # 移動補正 if not MoveService(self.options).execute(): return False # スタンス補正 if not StanceService(self.options).execute(): return False # 剛体接触回避 if self.options.arm_options.avoidance: if not ArmAvoidanceService(self.options).execute(): return False # 手首位置合わせ if self.options.arm_options.alignment: if not ArmAlignmentService(self.options).execute(): return False # カメラ補正 if self.options.camera_motion: if not CameraService(self.options).execute(): return False if self.options.is_sizing_camera_only is False: # モーフ置換 if not MorphService(self.options).execute(): return False for data_set_idx, data_set in enumerate(self.options.data_set_list): # 実行後、出力ファイル存在チェック try: # 出力 VmdWriter(data_set).write() Path(data_set.output_vmd_path).resolve(True) logger.info("【No.%s】 出力終了: %s", (data_set_idx + 1), os.path.basename(data_set.output_vmd_path), decoration=MLogger.DECORATION_BOX, title="サイジング成功") except FileNotFoundError as fe: logger.error("【No.%s】出力VMDファイルが正常に作成されなかったようです。\nパスを確認してください。%s\n\n%s", (data_set_idx + 1), data_set.output_vmd_path, fe, decoration=MLogger.DECORATION_BOX) if self.options.camera_motion: try: camera_model = PmxModel() camera_model.name = "カメラ・照明" data_set = MOptionsDataSet(self.options.camera_motion, None, camera_model, self.options.camera_output_vmd_path, 0, 0, [], None, 0, []) # 出力 VmdWriter(data_set).write() Path(data_set.output_vmd_path).resolve(True) logger.info("カメラ出力終了: %s", os.path.basename(data_set.output_vmd_path), decoration=MLogger.DECORATION_BOX, title="サイジング成功") except FileNotFoundError as fe: logger.error("カメラ出力VMDファイルが正常に作成されなかったようです。\nパスを確認してください。%s\n\n%s", self.options.camera_output_vmd_path, fe, decoration=MLogger.DECORATION_BOX) if int(self.options.total_process) != int(self.options.now_process): logger.warning("一部処理がスキップされました。\n画面左下の進捗数をクリックすると、スキップされた処理がグレーで表示されています。", decoration=MLogger.DECORATION_BOX) return True except MKilledException: return False except SizingException as se: logger.error("サイジング処理が処理できないデータで終了しました。\n\n%s", se, decoration=MLogger.DECORATION_BOX) return False except Exception as e: logger.critical("サイジング処理が意図せぬエラーで終了しました。", e, decoration=MLogger.DECORATION_BOX) return False finally: logging.shutdown()
def a_test_split_bf_by_fno02(self): original_motion = VmdReader(u"test/data/補間曲線テスト01.vmd").read_data() model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/ダミーボーン頂点追加2.pmx" ).read_data() target_bone_name = "ボーン01" links = BoneLinks() links.append(model.bones["SIZING_ROOT_BONE"]) links.append(model.bones["ボーン01"]) base_params = [0, 16, 32, 127] # https://qiita.com/wakame1367/items/0744268e928a28810c20 for xparams, yparams, zparams, rparams in zip(np.array(np.meshgrid(base_params, base_params, base_params, base_params)).T.reshape(-1, 4), \ np.array(np.meshgrid(base_params, base_params, base_params, base_params)).T.reshape(-1, 4), \ np.array(np.meshgrid(base_params, base_params, base_params, base_params)).T.reshape(-1, 4), \ np.array(np.meshgrid(base_params, base_params, base_params, base_params)).T.reshape(-1, 4)): try: for fill_fno in range( original_motion.get_bone_fnos(target_bone_name)[0] + 1, original_motion.get_bone_fnos(target_bone_name)[-1]): motion = cPickle.loads(cPickle.dumps(original_motion, -1)) # bfの補間曲線を再設定する next_bf = motion.bones[target_bone_name][ motion.get_bone_fnos(target_bone_name)[-1]] motion.reset_interpolation_parts(target_bone_name, next_bf, [None, MVector2D(xparams[0], xparams[1]), MVector2D(xparams[2], xparams[3]), None], \ MBezierUtils.MX_x1_idxs, MBezierUtils.MX_y1_idxs, MBezierUtils.MX_x2_idxs, MBezierUtils.MX_y2_idxs) motion.reset_interpolation_parts(target_bone_name, next_bf, [None, MVector2D(yparams[0], yparams[1]), MVector2D(yparams[2], yparams[3]), None], \ MBezierUtils.MY_x1_idxs, MBezierUtils.MY_y1_idxs, MBezierUtils.MY_x2_idxs, MBezierUtils.MY_y2_idxs) motion.reset_interpolation_parts(target_bone_name, next_bf, [None, MVector2D(zparams[0], zparams[1]), MVector2D(zparams[2], zparams[3]), None], \ MBezierUtils.MZ_x1_idxs, MBezierUtils.MZ_y1_idxs, MBezierUtils.MZ_x2_idxs, MBezierUtils.MZ_y2_idxs) motion.reset_interpolation_parts(target_bone_name, next_bf, [None, MVector2D(rparams[0], rparams[1]), MVector2D(rparams[2], rparams[3]), None], \ MBezierUtils.R_x1_idxs, MBezierUtils.R_y1_idxs, MBezierUtils.R_x2_idxs, MBezierUtils.R_y2_idxs) # 補間曲線を再設定したモーションを再保持 org_motion = cPickle.loads(cPickle.dumps(motion, -1)) # 間のキーフレをテスト prev_bf = motion.bones[target_bone_name][ motion.get_bone_fnos(target_bone_name)[0]] next_bf = motion.bones[target_bone_name][ motion.get_bone_fnos(target_bone_name)[-1]] result = motion.split_bf_by_fno(target_bone_name, prev_bf, next_bf, fill_fno) # 分割に成功した場合、誤差小。失敗してる場合は誤差大 delta = 0.3 if result else 1 # print("-----------------------------") # for now_fno in motion.get_bone_fnos(target_bone_name): # # 有効なキーフレをテスト # now_bf = motion.calc_bf(target_bone_name, now_fno) # org_pos_dic = MServiceUtils.calc_global_pos(model, links, org_motion, now_fno) # now_pos_dic = MServiceUtils.calc_global_pos(model, links, motion, now_fno) # print("fill_fno: %s, now_fno: %s key: %s ------------" % (fill_fno, now_bf.fno, now_bf.key)) # print("xparams: %s" % xparams) # print("yparams: %s" % yparams) # print("zparams: %s" % zparams) # print("rparams: %s" % rparams) # print("position: %s" % now_bf.position) # print("rotation: %s" % now_bf.rotation.toEulerAngles4MMD()) # print("int move x: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MX_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MX_y1_idxs[3]], \ # now_bf.interpolation[MBezierUtils.MX_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MX_y2_idxs[3]])) # print("int move y: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MY_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MY_y1_idxs[3]], \ # now_bf.interpolation[MBezierUtils.MY_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MY_y2_idxs[3]])) # print("int move z: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MZ_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MZ_y1_idxs[3]], \ # now_bf.interpolation[MBezierUtils.MZ_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MZ_y2_idxs[3]])) # print("int rot: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.R_x1_idxs[3]], now_bf.interpolation[MBezierUtils.R_y1_idxs[3]], \ # now_bf.interpolation[MBezierUtils.R_x2_idxs[3]], now_bf.interpolation[MBezierUtils.R_y2_idxs[3]])) # self.assertAlmostEqual(org_pos_dic[target_bone_name].x(), now_pos_dic[target_bone_name].x(), delta=(delta * 2)) # self.assertAlmostEqual(org_pos_dic[target_bone_name].y(), now_pos_dic[target_bone_name].y(), delta=(delta * 3)) # self.assertAlmostEqual(org_pos_dic[target_bone_name].z(), now_pos_dic[target_bone_name].z(), delta=(delta * 4)) print("-----------------------------") for fno in range( motion.get_bone_fnos(target_bone_name)[-1]): # org_bf = org_motion.calc_bf(target_bone_name, fno) now_bf = motion.calc_bf(target_bone_name, fno) org_pos_dic = MServiceUtils.calc_global_pos( model, links, org_motion, fno) now_pos_dic = MServiceUtils.calc_global_pos( model, links, motion, fno) print("** fill_fno: %s, fno: %s key: %s ------------" % (fill_fno, now_bf.fno, now_bf.key)) print("xparams: %s" % xparams) print("yparams: %s" % yparams) print("zparams: %s" % zparams) print("rparams: %s" % rparams) print("** position: %s" % now_bf.position) print("** rotation: %s" % now_bf.rotation.toEulerAngles4MMD()) print("** int move x: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MX_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MX_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MX_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MX_y2_idxs[3]])) print("** int move y: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MY_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MY_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MY_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MY_y2_idxs[3]])) print("** int move z: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MZ_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MZ_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MZ_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MZ_y2_idxs[3]])) print("** int rot: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.R_x1_idxs[3]], now_bf.interpolation[MBezierUtils.R_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.R_x2_idxs[3]], now_bf.interpolation[MBezierUtils.R_y2_idxs[3]])) self.assertAlmostEqual( org_pos_dic[target_bone_name].x(), now_pos_dic[target_bone_name].x(), delta=(delta * 2)) self.assertAlmostEqual( org_pos_dic[target_bone_name].y(), now_pos_dic[target_bone_name].y(), delta=(delta * 3)) self.assertAlmostEqual( org_pos_dic[target_bone_name].z(), now_pos_dic[target_bone_name].z(), delta=(delta * 4)) # now = datetime.now() # data_set = MOptionsDataSet(motion, model, model, "E:/WebDownload/test_split_bf_by_fno01_{0:%Y%m%d_%H%M%S%f}.vmd".format(now), False, False) # VmdWriter(data_set).write() # print(data_set.output_vmd_path) # data_set = MOptionsDataSet(org_motion, model, model, "E:/WebDownload/test_split_bf_by_fno01_{0:%Y%m%d_%H%M%S%f}_orignal.vmd".format(now), False, False) # VmdWriter(data_set).write() # print(data_set.output_vmd_path) except Exception as e: # エラーになったらデータを出力する now = datetime.now() data_set = MOptionsDataSet( motion, model, model, "E:/WebDownload/test_split_bf_by_fno01_{0:%Y%m%d_%H%M%S%f}.vmd" .format(now), False, False) VmdWriter(data_set).write() print(data_set.output_vmd_path) data_set = MOptionsDataSet( org_motion, model, model, "E:/WebDownload/test_split_bf_by_fno01_{0:%Y%m%d_%H%M%S%f}_orignal.vmd" .format(now), False, False) VmdWriter(data_set).write() print(data_set.output_vmd_path) raise e
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)
def test_calc_bf_02(self): motion = VmdReader(u"test/data/補間曲線テスト01.vmd").read_data() bf = motion.calc_bf("ボーン01", 0) print(bf) self.assertAlmostEqual(bf.position.x(), 0, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0, delta=0.1) bf = motion.calc_bf("ボーン01", 15) print(bf) self.assertAlmostEqual(bf.position.x(), 20, delta=0.1) self.assertAlmostEqual(bf.position.y(), 30, delta=0.1) self.assertAlmostEqual(bf.position.z(), 40, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 50, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 60.00003815, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 70, delta=0.1) bf = motion.calc_bf("ボーン01", 1) print(bf) self.assertAlmostEqual(bf.position.x(), 0.032109514, delta=0.1) self.assertAlmostEqual(bf.position.y(), 10.18260956, delta=0.1) self.assertAlmostEqual(bf.position.z(), 4.065711975, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0.000829206, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.000238923, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.000410508, delta=0.1) bf = motion.calc_bf("ボーン01", 2) print(bf) self.assertAlmostEqual(bf.position.x(), 0.140442505, delta=0.1) self.assertAlmostEqual(bf.position.y(), 12.61500168, delta=0.1) self.assertAlmostEqual(bf.position.z(), 8.287061691, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0.007236294, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.002085242, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.003582553, delta=0.1) bf = motion.calc_bf("ボーン01", 3) print(bf) self.assertAlmostEqual(bf.position.x(), 0.348192513, delta=0.1) self.assertAlmostEqual(bf.position.y(), 13.84411716, delta=0.1) self.assertAlmostEqual(bf.position.z(), 12.79018593, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0.026710032, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.007699313, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.013225263, delta=0.1) bf = motion.calc_bf("ボーン01", 4) print(bf) self.assertAlmostEqual(bf.position.x(), 0.698622525, delta=0.1) self.assertAlmostEqual(bf.position.y(), 14.49679756, delta=0.1) self.assertAlmostEqual(bf.position.z(), 17.72015953, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0.069654942, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.020092424, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.034498487, delta=0.1) bf = motion.calc_bf("ボーン01", 5) print(bf) self.assertAlmostEqual(bf.position.x(), 1.264359236, delta=0.1) self.assertAlmostEqual(bf.position.y(), 14.82721519, delta=0.1) self.assertAlmostEqual(bf.position.z(), 23.55570602, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0.151426569, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.043738037, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.07503701, delta=0.1) bf = motion.calc_bf("ボーン01", 6) print(bf) self.assertAlmostEqual(bf.position.x(), 2.228799105, delta=0.1) self.assertAlmostEqual(bf.position.y(), 14.96385574, delta=0.1) self.assertAlmostEqual(bf.position.z(), 28.47421646, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0.293533772, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.084980235, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.145587772, delta=0.1) bf = motion.calc_bf("ボーン01", 7) print(bf) self.assertAlmostEqual(bf.position.x(), 4.250654697, delta=0.1) self.assertAlmostEqual(bf.position.y(), 14.99863911, delta=0.1) self.assertAlmostEqual(bf.position.z(), 29.97695541, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0.529829144, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.153979659, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.263184816, delta=0.1) bf = motion.calc_bf("ボーン01", 8) print(bf) self.assertAlmostEqual(bf.position.x(), 15.74932003, delta=0.1) self.assertAlmostEqual(bf.position.y(), 15.00131607, delta=0.1) self.assertAlmostEqual(bf.position.z(), 31.17938614, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0.91197902, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.266692847, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.454135865, delta=0.1) bf = motion.calc_bf("ボーン01", 9) print(bf) self.assertAlmostEqual(bf.position.x(), 17.77118301, delta=0.1) self.assertAlmostEqual(bf.position.y(), 15.03609848, delta=0.1) self.assertAlmostEqual(bf.position.z(), 32.36212158, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 1.525828362, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.450684816, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.762894511, delta=0.1) bf = motion.calc_bf("ボーン01", 10) print(bf) self.assertAlmostEqual(bf.position.x(), 18.73562622, delta=0.1) self.assertAlmostEqual(bf.position.y(), 15.17386436, delta=0.1) self.assertAlmostEqual(bf.position.z(), 33.57285309, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 2.53502202, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0.761205316, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 1.276175618, delta=0.1) bf = motion.calc_bf("ボーン01", 11) print(bf) self.assertAlmostEqual(bf.position.x(), 19.3013649, delta=0.1) self.assertAlmostEqual(bf.position.y(), 15.50316238, delta=0.1) self.assertAlmostEqual(bf.position.z(), 34.80752563, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 4.252967358, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 1.313556314, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 2.167253256, delta=0.1) bf = motion.calc_bf("ボーン01", 12) print(bf) self.assertAlmostEqual(bf.position.x(), 19.65179825, delta=0.1) self.assertAlmostEqual(bf.position.y(), 16.15584373, delta=0.1) self.assertAlmostEqual(bf.position.z(), 36.06707764, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 7.438279152, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 2.422097683, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 3.884207487, delta=0.1) bf = motion.calc_bf("ボーン01", 13) print(bf) self.assertAlmostEqual(bf.position.x(), 19.85955048, delta=0.1) self.assertAlmostEqual(bf.position.y(), 17.38496399, delta=0.1) self.assertAlmostEqual(bf.position.z(), 37.35407639, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 14.49954891, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 5.332914352, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 8.068556786, delta=0.1) bf = motion.calc_bf("ボーン01", 14) print(bf) self.assertAlmostEqual(bf.position.x(), 19.96788788, delta=0.1) self.assertAlmostEqual(bf.position.y(), 19.81736565, delta=0.1) self.assertAlmostEqual(bf.position.z(), 38.66796112, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 33.70291519, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 18.53442383, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 24.47537041, delta=0.1)
def test_calc_bf_01(self): motion = VmdReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Motion/ダンス_1人/ドラマツルギー motion 配布用 moka/ドラマツルギー_0-500.vmd" ).read_data() bf = motion.calc_bf("右腕", 101) print(bf) self.assertAlmostEqual(bf.position.x(), 0, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 27.1, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 16.2, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), -32.9, delta=0.1) bf = motion.calc_bf("右腕", 143) print(bf) self.assertAlmostEqual(bf.position.x(), 0, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 32.2, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 57.3, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), -23.6, delta=0.1) bf = motion.calc_bf("右腕", 107) print(bf) self.assertAlmostEqual(bf.position.x(), 0, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 27.2, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 16.7, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), -32.8, delta=0.1) bf = motion.calc_bf("右腕", 121) print(bf) self.assertAlmostEqual(bf.position.x(), 0, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 28.6, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 24.5, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), -31.4, delta=0.1) bf = motion.calc_bf("右腕", 137) print(bf) self.assertAlmostEqual(bf.position.x(), 0, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 32.1, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 55.2, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), -24.1, delta=0.1) bf = motion.calc_bf("センター", 108) print(bf) self.assertAlmostEqual(bf.position.x(), 1.00, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 1.75, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0, delta=0.1) bf = motion.calc_bf("センター", 143) print(bf) self.assertAlmostEqual(bf.position.x(), 1.20, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 1.90, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0, delta=0.1) bf = motion.calc_bf("センター", 135) print(bf) self.assertAlmostEqual(bf.position.x(), 1.18, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), 1.89, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0, delta=0.1) bf = motion.calc_bf("センター", 340) print(bf) self.assertAlmostEqual(bf.position.x(), 3.21, delta=0.1) self.assertAlmostEqual(bf.position.y(), 0, delta=0.1) self.assertAlmostEqual(bf.position.z(), -0.96, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 0, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0, delta=0.1) bf = motion.calc_bf("右足IK", 417) print(bf) self.assertAlmostEqual(bf.position.x(), 2.75, delta=0.1) self.assertAlmostEqual(bf.position.y(), 2.92, delta=0.1) self.assertAlmostEqual(bf.position.z(), 2.19, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), -29.6, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), -25.2, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 5.0, delta=0.1) bf = motion.calc_bf("左足IK", 420) print(bf) self.assertAlmostEqual(bf.position.x(), 2.47, delta=0.1) self.assertAlmostEqual(bf.position.y(), 2.28, delta=0.1) self.assertAlmostEqual(bf.position.z(), 1.39, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().x(), -17.4, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().y(), 1.9, delta=0.1) self.assertAlmostEqual(bf.rotation.toEulerAngles4MMD().z(), 0.7, delta=0.1)
def load(self, file_idx=0, is_check=True): if not self.is_set_path(): # パスが指定されてない場合、そのまま終了 self.data = None return True if not self.is_valid(): # 読み込み可能か self.data = None return False try: if self.set_no == 0: # CSVとかのファイルは番号出力なし display_set_no = "" else: display_set_no = "【No.{0}】 ".format(self.set_no) if self.is_aster and self.set_no == 1: base_file_path = self.file_ctrl.GetPath() if os.path.exists(base_file_path): file_path_list = [base_file_path] else: file_path_list = [p for p in glob.glob(base_file_path) if os.path.isfile(p)] if len(file_path_list) == 0: # 読み込み可能か self.data = None return False file_path = file_path_list[file_idx] else: file_path = self.file_ctrl.GetPath() file_name, input_ext = os.path.splitext(os.path.basename(file_path)) # 拡張子別にリーダー生成 if input_ext.lower() == ".vmd": reader = VmdReader(file_path) elif input_ext.lower() == ".vpd": reader = VpdReader(file_path) elif input_ext.lower() == ".pmx": reader = PmxReader(file_path, is_check=is_check) else: logger.error("%s%s 読み込み失敗(拡張子不正): %s", display_set_no, self.title, os.path.basename(file_path), decoration=MLogger.DECORATION_BOX) return False # ハッシュ値取得 new_data_digest = reader.hexdigest() # 新規データがあり、かつハッシュが違う場合、置き換え if new_data_digest and ((self.data and self.data.digest != new_data_digest) or not self.data): # ハッシュが取得できてて、過去データがないかハッシュが違う場合、読み込み self.data = reader.read_data() logger.info("%s%s 読み込み成功: %s", display_set_no, self.title, os.path.basename(file_path)) return True elif new_data_digest and self.data and self.data.digest == new_data_digest: # ハッシュが同じ場合、そのままスルー logger.info("%s%s 読み込み成功: %s", display_set_no, self.title, os.path.basename(file_path)) return True except MKilledException: logger.warning("読み込み処理を中断します。", decoration=MLogger.DECORATION_BOX) 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) finally: logging.shutdown() logger.error("%s%s 読み込み失敗: %s", display_set_no, self.title, os.path.basename(file_path), decoration=MLogger.DECORATION_BOX) return False
def test_calc_relative_position01(self): motion = VmdReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Motion/ダンス_1人/ドラマツルギー motion 配布用 moka/ドラマツルギー_0-500.vmd" ).read_data() model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/VOCALOID/初音ミク/Tda式デフォ服ミク_ver1.1 金子卵黄/Tda式初音ミク_デフォ服ver.pmx" ).read_data() # -------------- links = model.create_link_2_top_one("グルーブ") # --------- trans_vs = MServiceUtils.calc_relative_position( model, links, motion, 407) self.assertEqual(4, len(trans_vs)) # SIZING_ROOT_BONE self.assertAlmostEqual(trans_vs[0].x(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[0].y(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[0].z(), 0, delta=0.1) # 全ての親 self.assertAlmostEqual(trans_vs[1].x(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[1].y(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[1].z(), 0, delta=0.1) # センター self.assertAlmostEqual(trans_vs[2].x(), 3.30 + links.get("センター").position.x(), delta=0.1) self.assertAlmostEqual(trans_vs[2].y(), 0.00 + links.get("センター").position.y(), delta=0.1) self.assertAlmostEqual(trans_vs[2].z(), -0.15 + links.get("センター").position.z(), delta=0.1) # グルーブ self.assertAlmostEqual(trans_vs[3].x(), 0 + links.get("グルーブ").position.x() - links.get("センター").position.x(), delta=0.1) self.assertAlmostEqual(trans_vs[3].y(), -4.40 + links.get("グルーブ").position.y() - links.get("センター").position.y(), delta=0.1) self.assertAlmostEqual(trans_vs[3].z(), 0 + links.get("グルーブ").position.z() - links.get("センター").position.z(), delta=0.1) # --------- trans_vs = MServiceUtils.calc_relative_position( model, links, motion, 420) self.assertEqual(4, len(trans_vs)) # SIZING_ROOT_BONE self.assertAlmostEqual(trans_vs[0].x(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[0].y(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[0].z(), 0, delta=0.1) # 全ての親 self.assertAlmostEqual(trans_vs[1].x(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[1].y(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[1].z(), 0, delta=0.1) # センター self.assertAlmostEqual(trans_vs[2].x(), 3.21 + links.get("センター").position.x(), delta=0.1) self.assertAlmostEqual(trans_vs[2].y(), 0.00 + links.get("センター").position.y(), delta=0.1) self.assertAlmostEqual(trans_vs[2].z(), 2.77 + links.get("センター").position.z(), delta=0.1) # グルーブ self.assertAlmostEqual(trans_vs[3].x(), 0 + links.get("グルーブ").position.x() - links.get("センター").position.x(), delta=0.1) self.assertAlmostEqual(trans_vs[3].y(), -0.22 + links.get("グルーブ").position.y() - links.get("センター").position.y(), delta=0.1) self.assertAlmostEqual(trans_vs[3].z(), 0 + links.get("グルーブ").position.z() - links.get("センター").position.z(), delta=0.1) # -------------- links = model.create_link_2_top_one("右足IK") # --------- trans_vs = MServiceUtils.calc_relative_position( model, links, motion, 415) self.assertEqual(4, len(trans_vs)) # SIZING_ROOT_BONE self.assertAlmostEqual(trans_vs[0].x(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[0].y(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[0].z(), 0, delta=0.1) # 全ての親 self.assertAlmostEqual(trans_vs[1].x(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[1].y(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[1].z(), 0, delta=0.1) # 右足IK親 self.assertAlmostEqual(trans_vs[2].x(), 0 + links.get("右足IK親").position.x(), delta=0.1) self.assertAlmostEqual(trans_vs[2].y(), 0 + links.get("右足IK親").position.y(), delta=0.1) self.assertAlmostEqual(trans_vs[2].z(), 0 + links.get("右足IK親").position.z(), delta=0.1) # 右足IK self.assertAlmostEqual(trans_vs[3].x(), 2.43 + links.get("右足IK").position.x() - links.get("右足IK親").position.x(), delta=0.1) self.assertAlmostEqual(trans_vs[3].y(), 0.00 + links.get("右足IK").position.y() - links.get("右足IK親").position.y(), delta=0.1) self.assertAlmostEqual(trans_vs[3].z(), 1.52 + links.get("右足IK").position.z() - links.get("右足IK親").position.z(), delta=0.1) # --------- trans_vs = MServiceUtils.calc_relative_position( model, links, motion, 418) self.assertEqual(4, len(trans_vs)) # SIZING_ROOT_BONE self.assertAlmostEqual(trans_vs[0].x(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[0].y(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[0].z(), 0, delta=0.1) # 全ての親 self.assertAlmostEqual(trans_vs[1].x(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[1].y(), 0, delta=0.1) self.assertAlmostEqual(trans_vs[1].z(), 0, delta=0.1) # 右足IK親 self.assertAlmostEqual(trans_vs[2].x(), 0 + links.get("右足IK親").position.x(), delta=0.1) self.assertAlmostEqual(trans_vs[2].y(), 0 + links.get("右足IK親").position.y(), delta=0.1) self.assertAlmostEqual(trans_vs[2].z(), 0 + links.get("右足IK親").position.z(), delta=0.1) # 右足IK self.assertAlmostEqual(trans_vs[3].x(), 2.92 + links.get("右足IK").position.x() - links.get("右足IK親").position.x(), delta=0.1) self.assertAlmostEqual(trans_vs[3].y(), 4.17 + links.get("右足IK").position.y() - links.get("右足IK親").position.y(), delta=0.1) self.assertAlmostEqual(trans_vs[3].z(), 2.45 + links.get("右足IK").position.z() - links.get("右足IK親").position.z(), delta=0.1)
def test_calc_global_pos01(self): motion = VmdReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Motion/ダンス_1人/ドラマツルギー motion 配布用 moka/ドラマツルギー_0-500.vmd" ).read_data() model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/VOCALOID/初音ミク/Tda式デフォ服ミク_ver1.1 金子卵黄/Tda式初音ミク_デフォ服ver.pmx" ).read_data() # -------------- links = model.create_link_2_top_one("グルーブ") # --------- pos_dic = MServiceUtils.calc_global_pos(model, links, motion, 420) self.assertEqual(4, len(pos_dic.keys())) # SIZING_ROOT_BONE print(pos_dic["SIZING_ROOT_BONE"]) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].x(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].y(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].z(), 0, delta=0.1) # 全ての親 print(pos_dic["全ての親"]) self.assertAlmostEqual(pos_dic["全ての親"].x(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["全ての親"].y(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["全ての親"].z(), 0, delta=0.1) # センター print(pos_dic["センター"]) self.assertAlmostEqual(pos_dic["センター"].x(), 3.2, delta=0.1) self.assertAlmostEqual(pos_dic["センター"].y(), 8.4, delta=0.1) self.assertAlmostEqual(pos_dic["センター"].z(), 2.7, delta=0.1) # グルーブ print(pos_dic["グルーブ"]) self.assertAlmostEqual(pos_dic["グルーブ"].x(), 3.2, delta=0.1) self.assertAlmostEqual(pos_dic["グルーブ"].y(), 8.4, delta=0.1) self.assertAlmostEqual(pos_dic["グルーブ"].z(), 2.7, delta=0.1) # -------------- links = model.create_link_2_top_one("左足IK") # --------- pos_dic = MServiceUtils.calc_global_pos(model, links, motion, 420) self.assertEqual(4, len(pos_dic.keys())) # SIZING_ROOT_BONE print(pos_dic["SIZING_ROOT_BONE"]) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].x(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].y(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].z(), 0, delta=0.1) # 全ての親 print(pos_dic["全ての親"]) self.assertAlmostEqual(pos_dic["全ての親"].x(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["全ての親"].y(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["全ての親"].z(), 0, delta=0.1) # 左足IK親 print(pos_dic["左足IK親"]) self.assertAlmostEqual(pos_dic["左足IK親"].x(), 1.0, delta=0.1) self.assertAlmostEqual(pos_dic["左足IK親"].y(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["左足IK親"].z(), 0.7, delta=0.1) # 右足IK親 print(pos_dic["左足IK"]) self.assertAlmostEqual(pos_dic["左足IK"].x(), 3.5, delta=0.1) self.assertAlmostEqual(pos_dic["左足IK"].y(), 3.9, delta=0.1) self.assertAlmostEqual(pos_dic["左足IK"].z(), 2.1, delta=0.1) # -------------- links = model.create_link_2_top_one("右手首") # --------- pos_dic = MServiceUtils.calc_global_pos(model, links, motion, 420) # self.assertEqual(17, len(pos_dic.keys())) # SIZING_ROOT_BONE print(pos_dic["SIZING_ROOT_BONE"]) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].x(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].y(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["SIZING_ROOT_BONE"].z(), 0, delta=0.1) # 全ての親 print(pos_dic["全ての親"]) self.assertAlmostEqual(pos_dic["全ての親"].x(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["全ての親"].y(), 0, delta=0.1) self.assertAlmostEqual(pos_dic["全ての親"].z(), 0, delta=0.1) # センター print(pos_dic["センター"]) self.assertAlmostEqual(pos_dic["センター"].x(), 3.2, delta=0.1) self.assertAlmostEqual(pos_dic["センター"].y(), 8.4, delta=0.1) self.assertAlmostEqual(pos_dic["センター"].z(), 2.7, delta=0.1) # グルーブ print(pos_dic["グルーブ"]) self.assertAlmostEqual(pos_dic["グルーブ"].x(), 3.2, delta=0.1) self.assertAlmostEqual(pos_dic["グルーブ"].y(), 8.4, delta=0.1) self.assertAlmostEqual(pos_dic["グルーブ"].z(), 2.7, delta=0.1) # 腰 self.assertAlmostEqual(pos_dic["腰"].x(), 3.2, delta=0.1) self.assertAlmostEqual(pos_dic["腰"].y(), 12.1, delta=0.1) self.assertAlmostEqual(pos_dic["腰"].z(), 3.0, delta=0.1) # 上半身 self.assertAlmostEqual(pos_dic["上半身"].x(), 3.2, delta=0.1) self.assertAlmostEqual(pos_dic["上半身"].y(), 13.0, delta=0.1) self.assertAlmostEqual(pos_dic["上半身"].z(), 2.2, delta=0.1) # 上半身2 self.assertAlmostEqual(pos_dic["上半身2"].x(), 3.25, delta=0.1) self.assertAlmostEqual(pos_dic["上半身2"].y(), 14.0, delta=0.1) self.assertAlmostEqual(pos_dic["上半身2"].z(), 2.25, delta=0.1) # 右肩P self.assertAlmostEqual(pos_dic["右肩P"].x(), 3.03, delta=0.1) self.assertAlmostEqual(pos_dic["右肩P"].y(), 16.26, delta=0.1) self.assertAlmostEqual(pos_dic["右肩P"].z(), 2.28, delta=0.1) # 右肩 self.assertAlmostEqual(pos_dic["右肩"].x(), 3.03, delta=0.1) self.assertAlmostEqual(pos_dic["右肩"].y(), 16.26, delta=0.1) self.assertAlmostEqual(pos_dic["右肩"].z(), 2.28, delta=0.1) # # 右肩C # self.assertAlmostEqual(pos_dic["右肩C"].x(), 3.03, delta=0.1) # self.assertAlmostEqual(pos_dic["右肩C"].y(), 16.26, delta=0.1) # self.assertAlmostEqual(pos_dic["右肩C"].z(), 2.28, delta=0.1) # 右腕 self.assertAlmostEqual(pos_dic["右腕"].x(), 2.15, delta=0.1) self.assertAlmostEqual(pos_dic["右腕"].y(), 16.32, delta=0.1) self.assertAlmostEqual(pos_dic["右腕"].z(), 2.39, delta=0.1) # 右腕捩 self.assertAlmostEqual(pos_dic["右腕捩"].x(), 0.66, delta=0.1) self.assertAlmostEqual(pos_dic["右腕捩"].y(), 15.64, delta=0.1) self.assertAlmostEqual(pos_dic["右腕捩"].z(), 2.19, delta=0.1) # 右ひじ self.assertAlmostEqual(pos_dic["右ひじ"].x(), -0.31, delta=0.1) self.assertAlmostEqual(pos_dic["右ひじ"].y(), 15.17, delta=0.1) self.assertAlmostEqual(pos_dic["右ひじ"].z(), 2.03, delta=0.1) # 右手捩 self.assertAlmostEqual(pos_dic["右手捩"].x(), 0.21, delta=0.1) self.assertAlmostEqual(pos_dic["右手捩"].y(), 14.36, delta=0.1) self.assertAlmostEqual(pos_dic["右手捩"].z(), 0.95, delta=0.1) # 右手首 self.assertAlmostEqual(pos_dic["右手首"].x(), 0.56, delta=0.1) self.assertAlmostEqual(pos_dic["右手首"].y(), 13.83, delta=0.1) self.assertAlmostEqual(pos_dic["右手首"].z(), 0.23, delta=0.1)
def test_split_bf_by_fno01(self): original_motion = VmdReader(u"test/data/補間曲線テスト01.vmd").read_data() model = PmxReader( "D:/MMD/MikuMikuDance_v926x64/UserFile/Model/ダミーボーン頂点追加2.pmx" ).read_data() target_bone_name = "ボーン01" links = BoneLinks() links.append(model.bones["SIZING_ROOT_BONE"]) links.append(model.bones["ボーン01"]) for pidx in range(10): try: params = np.random.randint(0, 127, (1, 4)) # params = [[116, 24, 22, 82]] for fill_fno in range( original_motion.get_bone_fnos(target_bone_name)[0] + 1, original_motion.get_bone_fnos(target_bone_name)[-1]): motion = original_motion.copy() # bfの補間曲線を再設定する next_bf = motion.bones[target_bone_name][ motion.get_bone_fnos(target_bone_name)[-1]] motion.reset_interpolation_parts(target_bone_name, next_bf, [None, MVector2D(20, 20), MVector2D(107, 107), None], \ MBezierUtils.R_x1_idxs, MBezierUtils.R_y1_idxs, MBezierUtils.R_x2_idxs, MBezierUtils.R_y2_idxs) motion.reset_interpolation_parts(target_bone_name, next_bf, [None, MVector2D(params[0][0], params[0][1]), MVector2D(params[0][2], params[0][3]), None], \ MBezierUtils.MX_x1_idxs, MBezierUtils.MX_y1_idxs, MBezierUtils.MX_x2_idxs, MBezierUtils.MX_y2_idxs) motion.reset_interpolation_parts(target_bone_name, next_bf, [None, MVector2D(20, 20), MVector2D(107, 107), None], \ MBezierUtils.MY_x1_idxs, MBezierUtils.MY_y1_idxs, MBezierUtils.MY_x2_idxs, MBezierUtils.MY_y2_idxs) motion.reset_interpolation_parts(target_bone_name, next_bf, [None, MVector2D(20, 20), MVector2D(107, 107), None], \ MBezierUtils.MZ_x1_idxs, MBezierUtils.MZ_y1_idxs, MBezierUtils.MZ_x2_idxs, MBezierUtils.MZ_y2_idxs) # 補間曲線を再設定したモーションを再保持 org_motion = motion.copy() # 間のキーフレをテスト prev_bf = motion.bones[target_bone_name][ motion.get_bone_fnos(target_bone_name)[0]] next_bf = motion.bones[target_bone_name][ motion.get_bone_fnos(target_bone_name)[-1]] result = motion.split_bf_by_fno(target_bone_name, prev_bf, next_bf, fill_fno) # 分割に成功した場合、誤差小。失敗してる場合は誤差大 delta = 0.3 if result else 1 print("-----------------------------") for now_fno in motion.get_bone_fnos(target_bone_name): # 有効なキーフレをテスト now_bf = motion.calc_bf(target_bone_name, now_fno) org_pos_dic = MServiceUtils.calc_global_pos( model, links, org_motion, now_fno) now_pos_dic = MServiceUtils.calc_global_pos( model, links, motion, now_fno) print( "fill_fno: %s, now_fno: %s key: %s (%s) ------------" % (fill_fno, now_bf.fno, now_bf.key, pidx)) print("params: %s" % params) print("position: %s" % now_bf.position) print("rotation: %s" % now_bf.rotation.toEulerAngles4MMD()) print("int move x: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MX_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MX_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MX_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MX_y2_idxs[3]])) print("int move y: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MY_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MY_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MY_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MY_y2_idxs[3]])) print("int move z: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MZ_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MZ_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MZ_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MZ_y2_idxs[3]])) print("int rot: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.R_x1_idxs[3]], now_bf.interpolation[MBezierUtils.R_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.R_x2_idxs[3]], now_bf.interpolation[MBezierUtils.R_y2_idxs[3]])) self.assertAlmostEqual( org_pos_dic[target_bone_name].x(), now_pos_dic[target_bone_name].x(), delta=0.2) self.assertAlmostEqual( org_pos_dic[target_bone_name].y(), now_pos_dic[target_bone_name].y(), delta=0.2) self.assertAlmostEqual( org_pos_dic[target_bone_name].z(), now_pos_dic[target_bone_name].z(), delta=0.2) print("-----------------------------") for fno in range( motion.get_bone_fnos(target_bone_name)[-1]): # org_bf = org_motion.calc_bf(target_bone_name, fno) now_bf = motion.calc_bf(target_bone_name, fno) org_pos_dic = MServiceUtils.calc_global_pos( model, links, org_motion, fno) now_pos_dic = MServiceUtils.calc_global_pos( model, links, motion, fno) print( "** fill_fno: %s, fno: %s key: %s (%s) ------------" % (fill_fno, now_bf.fno, now_bf.key, pidx)) print("** params: %s" % params) print("** position: %s" % now_bf.position) print("** rotation: %s" % now_bf.rotation.toEulerAngles4MMD()) print("** int move x: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MX_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MX_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MX_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MX_y2_idxs[3]])) print("** int move y: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MY_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MY_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MY_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MY_y2_idxs[3]])) print("** int move z: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.MZ_x1_idxs[3]], now_bf.interpolation[MBezierUtils.MZ_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.MZ_x2_idxs[3]], now_bf.interpolation[MBezierUtils.MZ_y2_idxs[3]])) print("** int rot: %s, %s, %s, %s" % (now_bf.interpolation[MBezierUtils.R_x1_idxs[3]], now_bf.interpolation[MBezierUtils.R_y1_idxs[3]], \ now_bf.interpolation[MBezierUtils.R_x2_idxs[3]], now_bf.interpolation[MBezierUtils.R_y2_idxs[3]])) self.assertAlmostEqual( org_pos_dic[target_bone_name].x(), now_pos_dic[target_bone_name].x(), delta=(delta * 2)) self.assertAlmostEqual( org_pos_dic[target_bone_name].y(), now_pos_dic[target_bone_name].y(), delta=(delta * 3)) self.assertAlmostEqual( org_pos_dic[target_bone_name].z(), now_pos_dic[target_bone_name].z(), delta=(delta * 4)) now = datetime.now() data_set = MOptionsDataSet( motion, model, model, "E:/WebDownload/test_split_bf_by_fno01_{0:%Y%m%d_%H%M%S%f}.vmd" .format(now), False, False) VmdWriter(data_set).write() print(data_set.output_vmd_path) data_set = MOptionsDataSet( org_motion, model, model, "E:/WebDownload/test_split_bf_by_fno01_{0:%Y%m%d_%H%M%S%f}_orignal.vmd" .format(now), False, False) VmdWriter(data_set).write() print(data_set.output_vmd_path) except Exception as e: # エラーになったらデータを出力する now = datetime.now() data_set = MOptionsDataSet( motion, model, model, "E:/WebDownload/test_split_bf_by_fno01_{0:%Y%m%d_%H%M%S%f}.vmd" .format(now), False, False) VmdWriter(data_set).write() print(data_set.output_vmd_path) data_set = MOptionsDataSet( org_motion, model, model, "E:/WebDownload/test_split_bf_by_fno01_{0:%Y%m%d_%H%M%S%f}_orignal.vmd" .format(now), False, False) VmdWriter(data_set).write() print(data_set.output_vmd_path) raise e