def splitBezier(self): # ベジェ曲線の分割 t, x, y, bresult, aresult, before_bz, after_bz = \ MBezierUtils.split_bezier_mmd(self.base_bezier.start_x.GetValue(), self.base_bezier.start_y.GetValue(), \ self.base_bezier.end_x.GetValue(), self.base_bezier.end_y.GetValue(), \ self.frame_start_ctrl.GetValue(), int(self.slice_slider_ctrl.GetValue()), self.frame_end_ctrl.GetValue()) if bresult: # 前半のキー self.before_bezier.panel.iserror = False self.before_bezier.start_x.SetValue(int(before_bz[1].x())) self.before_bezier.start_y.SetValue(int(before_bz[1].y())) self.before_bezier.end_x.SetValue(int(before_bz[2].x())) self.before_bezier.end_y.SetValue(int(before_bz[2].y())) else: self.before_bezier.panel.iserror = True if aresult: # 後半のキー self.after_bezier.panel.iserror = False self.after_bezier.start_x.SetValue(int(after_bz[1].x())) self.after_bezier.start_y.SetValue(int(after_bz[1].y())) self.after_bezier.end_x.SetValue(int(after_bz[2].x())) self.after_bezier.end_y.SetValue(int(after_bz[2].y())) else: self.after_bezier.panel.iserror = True
def test_split_bezier_mmd(self): x, y, t, is_fit_before_bz, is_fit_after_bz, before_bz, after_bz = MBezierUtils.split_bezier_mmd( 127, 0, 0, 127, 0, 8, 15) print("x: %s" % x) print("y: %s" % y) print("t: %s" % t) print("is_fit_before_bz: %s" % is_fit_before_bz) print("is_fit_after_bz: %s" % is_fit_after_bz) print("before_bz[0]: %s" % before_bz[0]) print("before_bz[1]: %s" % before_bz[1]) print("before_bz[2]: %s" % before_bz[2]) print("before_bz[3]: %s" % before_bz[3]) print("after_bz[0]: %s" % after_bz[0]) print("after_bz[1]: %s" % after_bz[1]) print("after_bz[2]: %s" % after_bz[2]) print("after_bz[3]: %s" % after_bz[3]) self.assertFalse(is_fit_before_bz) self.assertTrue(is_fit_after_bz)
def calc_bf(self, bone_name: str, fno: int, is_key=False, is_read=False, is_reset_interpolation=False): fill_bf = VmdBoneFrame(fno) if bone_name not in self.bones: self.bones[bone_name] = {fno: fill_bf} fill_bf.set_name(bone_name) return fill_bf # 条件に合致するフレーム番号を探す # is_key: 登録対象のキーを探す # is_read: データ読み込み時のキーを探す if fno in self.bones[bone_name] and (not is_key or (is_key and self.bones[bone_name][fno].key)) and (not is_read or (is_read and self.bones[bone_name][fno].read)): # 合致するキーが見つかった場合、それを返す return self.bones[bone_name][fno] else: # 合致するキーが見つからなかった場合 if is_key or is_read: # 既存キーのみ探している場合はNone return None # 番号より前のフレーム番号 before_fnos = [x for x in sorted(self.bones[bone_name].keys()) if (x < fno)] # 番号より後のフレーム番号 after_fnos = [x for x in sorted(self.bones[bone_name].keys()) if (x > fno)] if len(after_fnos) == 0 and len(before_fnos) == 0: fill_bf.set_name(bone_name) return fill_bf if len(after_fnos) == 0: # 番号より前があって、後のがない場合、前のをコピーして返す fill_bf = self.bones[bone_name][before_fnos[-1]].copy() fill_bf.fno = fno fill_bf.key = False fill_bf.read = False return fill_bf if len(before_fnos) == 0: # 番号より後があって、前がない場合、後のをコピーして返す fill_bf = self.bones[bone_name][after_fnos[0]].copy() fill_bf.fno = fno fill_bf.key = False fill_bf.read = False return fill_bf prev_bf = self.bones[bone_name][before_fnos[-1]] next_bf = self.bones[bone_name][after_fnos[0]] # 名前をコピー fill_bf.name = prev_bf.name fill_bf.bname = prev_bf.bname # 補間曲線を元に間を埋める fill_bf.rotation = self.calc_bf_rot(prev_bf, fill_bf, next_bf) fill_bf.position = self.calc_bf_pos(prev_bf, fill_bf, next_bf) if is_reset_interpolation: # 補間曲線再設定の場合、範囲外でも構わないので補間曲線を設定する # 回転の分割 r_x, r_y, r_t, r_bresult, r_aresult, r_before_bz, r_after_bz \ = MBezierUtils.split_bezier_mmd(next_bf.interpolation[MBezierUtils.R_x1_idxs[3]], next_bf.interpolation[MBezierUtils.R_y1_idxs[3]], \ next_bf.interpolation[MBezierUtils.R_x2_idxs[3]], next_bf.interpolation[MBezierUtils.R_y2_idxs[3]], \ prev_bf.fno, fill_bf.fno, next_bf.fno) # 移動Xの分割 x_x, x_y, x_t, x_bresult, x_aresult, x_before_bz, x_aftex_bz \ = MBezierUtils.split_bezier_mmd(next_bf.interpolation[MBezierUtils.MX_x1_idxs[3]], next_bf.interpolation[MBezierUtils.MX_y1_idxs[3]], \ next_bf.interpolation[MBezierUtils.MX_x2_idxs[3]], next_bf.interpolation[MBezierUtils.MX_y2_idxs[3]], \ prev_bf.fno, fill_bf.fno, next_bf.fno) # 移動Yの分割 y_x, y_y, y_t, y_bresult, y_aresult, y_before_bz, y_aftey_bz \ = MBezierUtils.split_bezier_mmd(next_bf.interpolation[MBezierUtils.MY_x1_idxs[3]], next_bf.interpolation[MBezierUtils.MY_y1_idxs[3]], \ next_bf.interpolation[MBezierUtils.MY_x2_idxs[3]], next_bf.interpolation[MBezierUtils.MY_y2_idxs[3]], \ prev_bf.fno, fill_bf.fno, next_bf.fno) # 移動Zの分割 z_x, z_y, z_t, z_bresult, z_aresult, z_before_bz, z_aftez_bz \ = MBezierUtils.split_bezier_mmd(next_bf.interpolation[MBezierUtils.MZ_x1_idxs[3]], next_bf.interpolation[MBezierUtils.MZ_y1_idxs[3]], \ next_bf.interpolation[MBezierUtils.MZ_x2_idxs[3]], next_bf.interpolation[MBezierUtils.MZ_y2_idxs[3]], \ prev_bf.fno, fill_bf.fno, next_bf.fno) # 強制設定 self.reset_interpolation(bone_name, prev_bf, fill_bf, next_bf, r_before_bz, r_after_bz, \ MBezierUtils.R_x1_idxs, MBezierUtils.R_y1_idxs, MBezierUtils.R_x2_idxs, MBezierUtils.R_y2_idxs) self.reset_interpolation(bone_name, prev_bf, fill_bf, next_bf, x_before_bz, x_aftex_bz, \ MBezierUtils.MX_x1_idxs, MBezierUtils.MX_y1_idxs, MBezierUtils.MX_x2_idxs, MBezierUtils.MX_y2_idxs) self.reset_interpolation(bone_name, prev_bf, fill_bf, next_bf, y_before_bz, y_aftey_bz, \ MBezierUtils.MY_x1_idxs, MBezierUtils.MY_y1_idxs, MBezierUtils.MY_x2_idxs, MBezierUtils.MY_y2_idxs) self.reset_interpolation(bone_name, prev_bf, fill_bf, next_bf, z_before_bz, z_aftez_bz, \ MBezierUtils.MZ_x1_idxs, MBezierUtils.MZ_y1_idxs, MBezierUtils.MZ_x2_idxs, MBezierUtils.MZ_y2_idxs) return fill_bf