def round_bezier_mmd(target: MVector2D): t2 = MVector2D() # XとYをそれぞれ整数(0-127)に丸める t2.setX(round_integer(target.x() * INTERPOLATION_MMD_MAX)) t2.setY(round_integer(target.y() * INTERPOLATION_MMD_MAX)) return t2
def test_scale_bezier(self): s1, s2, s3, s4 = MBezierUtils.scale_bezier(MVector2D(0.2, 0.7), MVector2D(0.3, -0.5), MVector2D(0.4, 1.2), MVector2D(1.2, 2)) print("s1: %s" % s1) print("s2: %s" % s2) print("s3: %s" % s3) print("s4: %s" % s4)
def convert_catmullrom_2_bezier(xs: list, ys: list): bz_x = [] bz_y = [] for x0, x1, x2, x3, y0, y1, y2, y3 in zip(xs[:-3], xs[1:-2], xs[2:-1], xs[3:], ys[:-3], ys[1:-2], ys[2:-1], ys[3:]): p0 = None if not x0 and not y0 else MVector2D(x0, y0) p1 = MVector2D(x1, y1) p2 = MVector2D(x2, y2) p3 = None if not x3 and not y3 else MVector2D(x3, y3) B = None C = None if not p0 and not p3: # 両方ない場合、無視 continue if not p0 and p3: bz_x.append(p1.x()) bz_y.append(p1.y()) # p0が空の場合、始点 B = (p1 * (1 / 2)) - p2 + (p3 * (1 / 2)) C = (p1 * (-3 / 2)) + (p2 * 2) - (p3 * (1 / 2)) if p0 and not p3: # p3が空の場合、終点 B = (p0 * (1 / 2)) - p1 + (p2 * (1 / 2)) C = (p0 * (-1 / 2)) + (p2 * (1 / 2)) if p0 and p3: # それ以外は通過点 B = p0 - (p1 * (5 / 2)) + (p2 * (4 / 2)) - (p3 * (1 / 2)) C = (p0 * (-1 / 2)) + (p2 * (1 / 2)) if not B or not C: logger.warning("p0: %s, p1: %s, p2: %s, p3: %s", p0, p1, p2, p3) # ベジェ曲線の制御点 s1 = (C + (p1 * 3)) / 3 s2 = (B - (p1 * 3) + (s1 * 6)) / 3 bz_x.append(s1.x()) bz_x.append(s2.x()) bz_y.append(s1.y()) bz_y.append(s2.y()) bz_x.append(xs[-2]) bz_y.append(ys[-2]) return bz_x, bz_y
def get_split_fill_fno(self, target_bone_name: str, prev_bf: VmdBoneFrame, next_bf: VmdBoneFrame, \ x1_idxs: list, y1_idxs: list, x2_idxs: list, y2_idxs: list): next_x1v = next_bf.interpolation[x1_idxs[3]] next_y1v = next_bf.interpolation[y1_idxs[3]] next_x2v = next_bf.interpolation[x2_idxs[3]] next_y2v = next_bf.interpolation[y2_idxs[3]] if not MBezierUtils.is_fit_bezier_mmd([MVector2D(), MVector2D(next_x1v, next_y1v), MVector2D(next_x2v, next_y2v), MVector2D()]): # ベジェ曲線がMMDの範囲内に収まっていない場合、中点で分割 new_fill_fno, _, _ = MBezierUtils.evaluate_by_t(next_x1v, next_y1v, next_x2v, next_y2v, prev_bf.fno, next_bf.fno, 0.5) if prev_bf.fno < new_fill_fno < next_bf.fno: return new_fill_fno # 範囲内でない場合 return -1
def split_bezier(x1v: int, y1v: int, x2v: int, y2v: int, start: int, now: int, end: int): # 補間曲線の進んだ時間分を求める x, y, t = evaluate(x1v, y1v, x2v, y2v, start, now, end) A = MVector2D(0.0, 0.0) B = MVector2D(x1v / INTERPOLATION_MMD_MAX, y1v / INTERPOLATION_MMD_MAX) C = MVector2D(x2v / INTERPOLATION_MMD_MAX, y2v / INTERPOLATION_MMD_MAX) D = MVector2D(1.0, 1.0) E = A * (1 - t) + B * t F = B * (1 - t) + C * t G = C * (1 - t) + D * t H = E * (1 - t) + F * t I = F * (1 - t) + G * t # noqa J = H * (1 - t) + I * t # 新たな4つのベジェ曲線の制御点は、A側がAEHJ、C側がJIGDとなる。 # スケーリング beforeBz = scale_bezier(A, E, H, J) afterBz = scale_bezier(J, I, G, D) return x, y, t, beforeBz, afterBz
def join_value_2_bezier(fno: int, bone_name: str, values: list, offset=0, diff_limit=0.01): if np.isclose(np.max(np.array(values)), np.min(np.array(values)), atol=1e-3) or len(values) <= 2: # すべてがだいたい同じ値(最小と最大が同じ値)か次数が1の場合、線形補間 return LINEAR_MMD_INTERPOLATION try: # Xは次数(フレーム数)分移動 xs = np.arange(0, len(values)) # YはXの移動分を許容範囲とする ys = values + xs[-1] # カトマル曲線をベジェ曲線に変換する bz_x, bz_y = convert_catmullrom_2_bezier( np.concatenate([[None], xs, [None]]), np.concatenate([[None], ys, [None]])) logger.test("bz_x: %s", bz_x) logger.test("bz_y: %s", bz_y) if len(bz_x) == 0: # 始点と終点が指定されていて、カトマル曲線が描けなかった場合、線形補間 return LINEAR_MMD_INTERPOLATION # 次数 degree = len(bz_x) - 1 logger.test("degree: %s", degree) # すべての制御点を加味したベジェ曲線 full_curve = bezier.Curve(np.asfortranarray([bz_x, bz_y]), degree=degree) if degree < 3: # 3次未満の場合、3次まで次数を増やす joined_curve = full_curve.elevate() for _ in range(1, 3 - degree): joined_curve = joined_curve.elevate() elif degree == 3: # 3次の場合、そのままベジェ曲線をMMD用に補間 joined_curve = full_curve elif degree > 3: # 3次より多い場合、次数を減らす reduced_curve_list = [] bz_x = full_curve.nodes[0] bz_y = full_curve.nodes[1] logger.test("START bz_x: %s, bz_y: %s", bz_x, bz_y) # 3次になるまでベジェ曲線を繋いで減らしていく while len(bz_x) > 4: reduced_curve_list = [] for n in range(0, degree + 1, 5): reduce_bz_x = bz_x[n:n + 5] reduce_bz_y = bz_y[n:n + 5] logger.test("n: %s, reduce_bz_x: %s, reduce_bz_y: %s", n, reduce_bz_x, reduce_bz_y) reduced_curve = bezier.Curve(np.asfortranarray( [reduce_bz_x, reduce_bz_y]), degree=(len(reduce_bz_x) - 1)) # 次数がある場合、減らす if (len(reduce_bz_x) - 1) > 1: reduced_curve = reduced_curve.reduce_() logger.test("n: %s, nodes: %s", n, reduced_curve.nodes) # リストに追加 reduced_curve_list.append(reduced_curve) bz_x = [] bz_y = [] for reduced_curve in reduced_curve_list: bz_x = np.append(bz_x, reduced_curve.nodes[0]) bz_y = np.append(bz_y, reduced_curve.nodes[1]) logger.test("NEXT bz_x: %s, bz_y: %s", bz_x, bz_y) logger.test("FINISH bz_x: %s, bz_y: %s", bz_x, bz_y) # bz_x = [full_curve.nodes[0][0]] + list(bz_x) + [full_curve.nodes[0][-1]] # bz_y = [full_curve.nodes[0][0]] + list(bz_y) + [full_curve.nodes[0][-1]] joined_curve = bezier.Curve(np.asfortranarray([bz_x, bz_y]), degree=(len(bz_x) - 1)) logger.test("joined_curve: %s", joined_curve.nodes) # 全体のキーフレ bezier_x = np.arange(0, len(values))[1:-1] # 元の2つのベジェ曲線との交点を取得する full_ys = intersect_by_x(full_curve, bezier_x) logger.test("f: %s, %s, full_ys: %s", fno, bone_name, full_ys) # 次数を減らしたベジェ曲線との交点を取得する reduced_ys = intersect_by_x(joined_curve, bezier_x) logger.test("f: %s, %s, reduced_ys: %s", fno, bone_name, reduced_ys) # 交点の差を取得する diff_ys = np.array(full_ys) - np.array(reduced_ys) # 差が大きい箇所をピックアップする diff_large = np.where( np.abs(diff_ys) > (diff_limit * (offset + 1)), 1, 0) # 差が一定未満である場合、ベジェ曲線をMMD補間曲線に合わせる nodes = joined_curve.nodes # MMD用補間曲線に変換 joined_bz = scale_bezier(MVector2D(nodes[0, 0], nodes[1, 0]), MVector2D(nodes[0, 1], nodes[1, 1]), \ MVector2D(nodes[0, 2], nodes[1, 2]), MVector2D(nodes[0, 3], nodes[1, 3])) logger.debug("f: %s, %s, values: %s, nodes: %s, full_ys: %s, reduced_ys: %s, diff_ys: %s, diff_limit: %s, diff_large: %s, joined_bz: %s, %s, fit: %s", \ fno, bone_name, values, joined_curve.nodes, full_ys, reduced_ys, diff_ys, diff_limit, np.count_nonzero(diff_large) > 0, joined_bz[1], joined_bz[2], \ is_fit_bezier_mmd(joined_bz, offset)) if np.count_nonzero(diff_large) > 0: # 差が大きい箇所がある場合、分割不可 return None if not is_fit_bezier_mmd(joined_bz, offset): # 補間曲線がMMD補間曲線内に収まらない場合、NG return None # オフセット込みの場合、MMD用補間曲線枠内に収める fit_bezier_mmd(joined_bz) # すべてクリアした場合、補間曲線採用 return joined_bz except Exception as e: # エラーレベルは落として表に出さない logger.debug("ベジェ曲線生成失敗", e) return None
# -*- coding: utf-8 -*- # from module.MMath import MRect, MVector2D, MVector3D, MVector4D, MQuaternion, MMatrix4x4 # noqa from utils.MLogger import MLogger # noqa import numpy as np import bezier logger = MLogger(__name__, level=1) # MMDでの補間曲線の最大値 INTERPOLATION_MMD_MAX = 127 # MMDの線形補間 LINEAR_MMD_INTERPOLATION = [ MVector2D(0, 0), MVector2D(20, 20), MVector2D(107, 107), MVector2D(127, 127) ] # 回転補間曲線のインデックス R_x1_idxs = [3, 18, 33, 48] R_y1_idxs = [7, 22, 37, 52] R_x2_idxs = [11, 26, 41, 56] R_y2_idxs = [15, 30, 45, 60] # X移動補間曲線のインデックス MX_x1_idxs = [0, 0, 0, 0] MX_y1_idxs = [19, 34, 49, 4] MX_x2_idxs = [23, 38, 53, 8] MX_y2_idxs = [27, 42, 57, 12]
def test_scale_bezier_point(self): v = MBezierUtils.scale_bezier_point(MVector2D(1, 2), MVector2D(3, 4), MVector2D()) print("v: %s" % v) self.assertAlmostEqual(v.x(), 0, delta=0.1) self.assertAlmostEqual(v.y(), 0, delta=0.1)
def test_round_bezier_mmd(self): v = MBezierUtils.round_bezier_mmd(MVector2D(0.56, 0)) print("v: %s" % v) self.assertAlmostEqual(v.x(), 71, delta=0.1) self.assertAlmostEqual(v.y(), 0, delta=0.1)
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 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