From 69ffafda2b252f49191693555b77a23092af7038 Mon Sep 17 00:00:00 2001 From: Daksitha Date: Wed, 20 Jan 2021 11:48:32 +0100 Subject: [PATCH 1/5] Ramge editor --- CAfP/__init__.py | 288 +++++++++++++++--- CAfP/__pycache__/__init__.cpython-37.pyc | Bin 6855 -> 11524 bytes CAfP/__pycache__/bone_motion.cpython-37.pyc | Bin 5753 -> 5753 bytes CAfP/__pycache__/file_op.cpython-37.pyc | Bin 5952 -> 5958 bytes CAfP/__pycache__/global_config.cpython-37.pyc | Bin 259 -> 259 bytes CAfP/bone_motion.py | 2 - CAfP/file_op.py | 93 +++--- CAfP/global_config.py | 1 + 8 files changed, 298 insertions(+), 86 deletions(-) diff --git a/CAfP/__init__.py b/CAfP/__init__.py index 6fa60f4..0998537 100644 --- a/CAfP/__init__.py +++ b/CAfP/__init__.py @@ -25,6 +25,7 @@ import bpy from bpy.utils import unregister_class from bpy.utils import register_class +import os #from . damping_tools import DampAnimation #from . offset_tools import AngularOffsetAnimation @@ -32,9 +33,9 @@ from . time_warping import CreateTimeWarpingCurve from . time_warping import TimeWarper -from . file_op import LoadPoseBone from . file_op import ExportPoseBone - +from . file_op import LoadPoseBone + import CAfP.global_config as global_config ################## bone properties ################### @@ -137,6 +138,15 @@ def update_bone_animation(self, context): ) +#range selected flag +bpy.types.PoseBone.is_range_selected = bpy.props.BoolProperty( + name = "isRangeSelected", + description="check whethere the range to be edited is selected", + default=False, + + ) + + ################# NLA Opporation variable ################## nla_strip_list = [] def get_nla_strips_list(scene, context): @@ -160,7 +170,6 @@ def get_nla_strips_list(scene, context): # if obj.animation_data is not None: # nla_strip = obj.animation_data.nla_tracks # if len(nla_strip): - def update_timewarping(self,context): @@ -198,6 +207,185 @@ def update_timewarping(self,context): description="initial location of timewarping control curve", ) +def export_bone_parameters_toJson(param_json, bone): + + #param_json['anim_start'] = bone.anim_start + param_json['anim_ignore_from_start'] = bone.anim_ignore_from_start + param_json['anim_ignore_from_end'] = bone.anim_ignore_from_end + + x_scale = round(bone.damping_x_scale,3) + y_scale = round(bone.damping_y_scale,3) + z_scale = round(bone.damping_z_scale,3) + + param_json['damping_x_scale'] = x_scale + param_json['damping_y_scale'] = y_scale + param_json['damping_z_scale'] = z_scale + + + x_offset = round(bone.angular_offset_x,3) + y_offset =round( bone.angular_offset_y,3) + z_offset = round(bone.angular_offset_z,3) + + + param_json['angular_offset_x'] = x_offset + param_json['angular_offset_y'] = y_offset + param_json['angular_offset_z'] = z_offset + + return param_json + + +def isInCurrDirectory(file_name): + filepath = bpy.data.filepath + directory = os.path.dirname(filepath) + _, _, filenames = next(os.walk(directory)) + for files_ in filenames: + if files_ == file_name: + print('file {} already in the direcotry'.format(files_)) + return True + return False + + +class SELECTRange(bpy.types.Operator): + """ + Select the keyframe range to edit in the current animation. + """ + bl_label = 'Select the keyframe range to edit' + bl_idname = 'cafp.select_posebone_range' + + + @classmethod + def poll(cls, context): + + if not (context.mode == 'POSE'): + return False + + obj = context.active_object # type: bpy.types.Object + active_bone = bpy.context.active_pose_bone # type: bpy.types.PoseBone + if obj is not None: + if obj.type == 'ARMATURE': + anim_data = obj.animation_data + if anim_data is not None: + act = anim_data.action + if act is not None: + if active_bone is not None: + return True + + return False + + def execute(self,context): + import json + obj = bpy.context.active_object + active_bone = bpy.context.active_pose_bone # type: bpy.types.PoseBone + try: + #save a file in the current directory + path =bpy.path.abspath("//CAfP_Temp_BProperties.json") + #print(path) + out_data = {} + out_data['armature_name'] = '{}'.format(obj.name) + if not isInCurrDirectory('CAfP_Temp_BProperties.json'): + with open(path, 'w') as out_file: + json.dump(obj=out_data, fp=out_file, indent=2) + self.report({'INFO'}, 'Create a CAfP temp_bone.json at {}'.format(path)) + + active_bone.is_range_selected = True + except OSError as err: + self.report('WARNING','Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) + active_bone.is_range_selected = False + except IOError as err: + active_bone.is_range_selected = False + if path != "": + self.report({'WARNING'},"{},while creating {}. Please save the blend file".format(err,bpy.path.basename(path))) + except json.JSONDecodeError: + active_bone.is_range_selected = False + self.report({'WARNING'},"Errors in json file: {}".format(bpy.path.basename(path))) + + + return {'FINISHED'} + +class GoBackToRangeSelector(bpy.types.Operator): + """ + Save the current changes for this range and go back to range panel. + """ + bl_label = 'Go back to range selector panel' + bl_idname = 'cafp.back_to_range_selection' + + @classmethod + def poll(cls, context): + + if not (context.mode == 'POSE'): + return False + + obj = context.active_object # type: bpy.types.Object + active_bone = bpy.context.active_pose_bone # type: bpy.types.PoseBone + if obj is not None: + if obj.type == 'ARMATURE': + anim_data = obj.animation_data + if anim_data is not None: + act = anim_data.action + if act is not None: + if active_bone is not None: + return True + + def execute(self,context): + import json + import time + + + obj = bpy.context.active_object + #save a file in the current directory + + active_bone = bpy.context.active_pose_bone + + try: + + time1 = time.time() + path =bpy.path.abspath("//CAfP_Temp_BProperties.json") + out_data = {} + with open(path, 'r') as j_file: + + j_database = json.loads(j_file.read()) + print(' j_database: {}'.format(j_database)) + + if 'name' in j_database: + if j_database['name'] == obj.name: + self.report({'WARNING'},"Json database and Armature names are not matching") + + param_json= {} + param_json = export_bone_parameters_toJson(param_json, active_bone) + if active_bone.name in j_database: + j_database['{}'.format(active_bone.name)].append(param_json) + else: + j_database['{}'.format(active_bone.name)] =[] + j_database['{}'.format(active_bone.name)].append(param_json) + + out_data = j_database + + with open(path, 'w') as output: + json.dump(obj=out_data, fp=output, indent=2) + + #set the flag to change the ui + + active_bone.is_range_selected = False + + self.report({'INFO'},"CAfP_Temp_BProperties {} added in {} secs".format\ + (active_bone.name, time.time()-time1)) + except OSError as err: + self.report('WARNING','Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) + except IOError as err: + if path != "": + self.report({'WARNING'},"{},while creating {}. Please save the blend file".format(err,bpy.path.basename(path))) + except json.JSONDecodeError as err: + self.report({'WARNING'},"Errors {}in json file: {}".format(err, bpy.path.basename(path))) + + + return {'FINISHED'} + + + + + + + ############################## main panel ########################################### isArmWithAnim = False isArmWithNLA = False @@ -254,7 +442,8 @@ def draw(self, context): isArmWithNLA = False - #Assume posemode only active for armature types + + if isArmWithAnim: if context.mode == 'POSE': @@ -280,41 +469,59 @@ def draw(self, context): layout.row() #layout.row().label(text="Active Bone: {}".format(bone_name), icon= 'BONE_DATA') - #Range - settings_row = layout.row(align=True) - settings_box = settings_row.box() - settings_box.label(text="Keyframe Range to Change", icon='SETTINGS') - #damping - damp_row = layout.row(align=True) - damping_box = damp_row.box() - damping_box.label(text = "Animation Amplitude Modifier:",icon='FORCE_HARMONIC') - - #offset - offset_row = layout.row() - offset_box = offset_row.box() - offset_box.label(text = "Animation Angular Offset:",icon = 'ORIENTATION_GIMBAL') - - if active_bone is not None: - - set_col = settings_box.column(align=True) - set_col.prop(active_bone, "anim_start", expand=True) - set_col.prop(active_bone, "anim_ignore_from_start", expand=True) - set_col.prop(active_bone, "anim_ignore_from_end", expand=True) - - col = damping_box.column(align=True) - col.prop(active_bone, "damping_x_scale",toggle=True, expand=True) - col.prop(active_bone, "damping_y_scale",toggle=True, expand=True) - col.prop(active_bone, "damping_z_scale",toggle=True, expand=True) - - col2 = offset_box.column(align=True) - col2.prop(active_bone, "angular_offset_x",toggle=True, expand=True) - col2.prop(active_bone, "angular_offset_y",toggle=True, expand=True) - col2.prop(active_bone, "angular_offset_z",toggle=True, expand=True) - else: - infor_damp = damping_box.row() - info_off = offset_box.row() - info_off.label(text= "select a bone") - infor_damp.label(text= "select a bone") + if active_bone.is_range_selected: + + #damping + damp_row = layout.row(align=True) + damping_box = damp_row.box() + damping_box.label(text = "Animation Amplitude Modifier:",icon='FORCE_HARMONIC') + + #offset + offset_row = layout.row() + offset_box = offset_row.box() + offset_box.label(text = "Animation Angular Offset:",icon = 'ORIENTATION_GIMBAL') + + #go back to range selector + + + if active_bone is not None: + + + col = damping_box.column(align=True) + col.prop(active_bone, "damping_x_scale",toggle=True, expand=True) + col.prop(active_bone, "damping_y_scale",toggle=True, expand=True) + col.prop(active_bone, "damping_z_scale",toggle=True, expand=True) + + col2 = offset_box.column(align=True) + col2.prop(active_bone, "angular_offset_x",toggle=True, expand=True) + col2.prop(active_bone, "angular_offset_y",toggle=True, expand=True) + col2.prop(active_bone, "angular_offset_z",toggle=True, expand=True) + + col2.operator('cafp.back_to_range_selection', text= 'back to range selector') + + else: + infor_damp = damping_box.row() + info_off = offset_box.row() + info_off.label(text= "select a bone") + infor_damp.label(text= "select a bone") + else: + #Range + settings_row = layout.row(align=True) + settings_box = settings_row.box() + settings_box.label(text="Keyframe Range for Change", icon='SETTINGS') + if active_bone is not None: + set_col = settings_box.column(align=True) + bn_name = set_col.row() + bn_name.label(text='Active Bone: {}'.format(active_bone.basename)) + #set_col.prop(active_bone, "anim_start", expand=True) + set_col.prop(active_bone, "anim_ignore_from_start", expand=True) + set_col.prop(active_bone, "anim_ignore_from_end", expand=True) + + set_col.operator('cafp.select_posebone_range', text= 'Next') + else: + infor_ = settings_box.row() + infor_.label(text= "select a bone") + #expoert and import exp_rw = layout.row(align=True) @@ -374,7 +581,8 @@ def draw(self, context): -classes = (VIEW3D_PT_cafpmainpanle,BoneAnimatorOffDamp,CreateTimeWarpingCurve,TimeWarper,ExportPoseBone,LoadPoseBone) +classes = (VIEW3D_PT_cafpmainpanle,BoneAnimatorOffDamp,CreateTimeWarpingCurve,TimeWarper,ExportPoseBone,\ + LoadPoseBone,SELECTRange,GoBackToRangeSelector) def register(): for clas in classes: diff --git a/CAfP/__pycache__/__init__.cpython-37.pyc b/CAfP/__pycache__/__init__.cpython-37.pyc index 957d640352499f609659df2179c40fe7cf7defda..75b6bd02b5188042c3fd5b280d0f1810681b1609 100644 GIT binary patch literal 11524 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 XCX-EDfBc4YFvoSe(#PzzUGMw{E*!@; delta 1971 zcmaJ?O>7%Q6rR~#@1NJ}zu5UBC4uzE5DNXFYD-nx5DJCuxf3YB#an*^QD^ zYXZ0`AXK0oKpa{r5oeGf2Z|7)CnPQ)I8bSi9FTgcI3OfAAl_RiZK)8p=9_Py-+MFr zX1?cdH{RH255{69fzMkXD5w8ebJ^~o?_XYj;GoS^rd^=<=yQbW%(y_9Q6v?s5-XZb zC2xb(WKpn2Th^wWkAux(F|ft%*bk*k#UiLceCC6$W5)pfl-SyX&dAxpF&vxpZdsJ_g|S%cr6`_z{gHL+Xk zT+kbuuQYUDUo@DyMEN_wOr|k?Nop8g)Hj-x8D}N18%*yc;Hj;6UI(`7X@aM@;(6US zLr=}ud>tZ3=KB2zGdszmwnT==$+iEeZ#4O9J4?_T`ddNZ&pX*i$u! z6)JA6T40Xn1hL7f+PE`Sn5b1t<;ftr|KO3s$A$|-dx!Um*Yw9W1oC)&K9Fm5H&7;= zQa!N7Yt^DtEl)dMjpt&4;ufb$yhD7UUuhqJmE6q$M6#$wRj9ZnsggKlJQz{%S-fIo zX&^o_uJt_uUc3V!NBINDV+b}tpfK*tz9dG>eHzDXH@JA2n5; zSYBhlOym2(BhcKLac{m}j3!y

dg53J1I9Bj+z~3q58VG*mxQk$sg(y9h7^m>jYQFl86< z@OOgxxgK&o}B^A7e?Dx&&GqC5#*;$H*9|+Tp@!Shx)rWSLNB z*+YR2;wn^~>0)4_1PZR_a8G<woVuim*){qBAh}f00a?Uo2h~f&@hfLfxr-o2qgqOUOt5IEP@UYs7}3Jgvh;U z=|dPqv%+Sk>p2?)0Fn3Iqd>3Cc&%=rpt$p9-Qmu3*d+4WT)~}iriyuOewCbGA^KdQ zRw}tgFR#zvVdqzv=t_02l oFSGsPmuxDEZHVK0@>xjQF1p*}9oSNI+WKO5PDrMeJ<&Gy50{a*`Tzg` diff --git a/CAfP/__pycache__/global_config.cpython-37.pyc b/CAfP/__pycache__/global_config.cpython-37.pyc index 476f59e90ef2ecb278b6eb27193d12becdbe4cd0..9f4e86524f9b8bcdf90cd99bc2bfeb54fe4c0c5c 100644 GIT binary patch delta 21 bcmZo>YG&ef;^pOH0D?>R*%I6*@_qvVE?ot1 delta 21 acmZo>YG&ef;^pOH00Pr&mIT*{yx#yOH3VA# diff --git a/CAfP/bone_motion.py b/CAfP/bone_motion.py index 78c9a2c..fe9cad9 100644 --- a/CAfP/bone_motion.py +++ b/CAfP/bone_motion.py @@ -199,8 +199,6 @@ def poll(cls, context): def execute(self, context): - - # Active Armature obj = context.active_object # type: bpy.types.Object if obj.type != 'ARMATURE': diff --git a/CAfP/file_op.py b/CAfP/file_op.py index 63ef03c..ef8fe82 100644 --- a/CAfP/file_op.py +++ b/CAfP/file_op.py @@ -18,6 +18,26 @@ def simple_path(input_path, use_basename=True, max_len=50): return input_path +def load_json_data(self, json_path, description=None): + + try: + time1 = time.time() + with open(json_path, "r") as j_file: + j_database = json.load(j_file) + if not description: + self.report({'INFO'},"Json database {} loaded in {} secs".format\ + (simple_path(json_path), time.time()-time1)) + else: + self.report({'INFO'},"{} loaded from {} in {} secs".format\ + (description, simple_path(json_path), time.time()-time1)) + return j_database + except IOError: + if simple_path(json_path) != "": + self.report({'WARNING'},"File not found: {}".format(simple_path(json_path))) + except json.JSONDecodeError: + self.report({'WARNING'},"Errors in json file: {}".format(simple_path(json_path))) + return None + class LoadPoseBone(bpy.types.Operator, ImportHelper): """ Load cafp posebone properties from a JSON. @@ -48,7 +68,7 @@ def execute(self, context): return {'FINISHED'} #-------------------- scene_poseB = context.visible_pose_bones - im_poseBones = self.load_json_data(self.filepath) + im_poseBones = load_json_data(self, self.filepath) #Setting the IMPORT_DATA flag #global_config.IMPORT_DATA = True @@ -90,25 +110,33 @@ def draw(self, context): self.layout.label(text=message) bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) - def load_json_data(self, json_path, description=None): - - try: - time1 = time.time() - with open(json_path, "r") as j_file: - j_database = json.load(j_file) - if not description: - self.report({'INFO'},"Json database {} loaded in {} secs".format\ - (simple_path(json_path), time.time()-time1)) - else: - self.report({'INFO'},"{} loaded from {} in {} secs".format\ - (description, simple_path(json_path), time.time()-time1)) - return j_database - except IOError: - if simple_path(json_path) != "": - self.report({'WARNING'},"File not found: {}".format(simple_path(json_path))) - except json.JSONDecodeError: - self.report({'WARNING'},"Errors in json file: {}".format(simple_path(json_path))) - return None +#################### Export function ################## +def export_bone_parameters_toJson(param_json, bone): + + #param_json['anim_start'] = bone.anim_start + param_json['anim_ignore_from_start'] = bone.anim_ignore_from_start + param_json['anim_ignore_from_end'] = bone.anim_ignore_from_end + + x_scale = round(bone.damping_x_scale,3) + y_scale = round(bone.damping_y_scale,3) + z_scale = round(bone.damping_z_scale,3) + + param_json['damping_x_scale'] = x_scale + param_json['damping_y_scale'] = y_scale + param_json['damping_z_scale'] = z_scale + + + x_offset = round(bone.angular_offset_x,3) + y_offset =round( bone.angular_offset_y,3) + z_offset = round(bone.angular_offset_z,3) + + + param_json['angular_offset_x'] = x_offset + param_json['angular_offset_y'] = y_offset + param_json['angular_offset_z'] = z_offset + + return param_json + class ExportPoseBone(bpy.types.Operator): "Export all posebone angular offset and amplitude parameter to a json file" @@ -147,30 +175,7 @@ def execute(self, context): for bone in poseBones: # type: bpy.types.PoseBone param_json = {} #range - - param_json['anim_start'] = bone.anim_start - param_json['anim_ignore_from_start'] = bone.anim_ignore_from_start - param_json['anim_ignore_from_end'] = bone.anim_ignore_from_end - - x_scale = round(bone.damping_x_scale,3) - y_scale = round(bone.damping_y_scale,3) - z_scale = round(bone.damping_z_scale,3) - - param_json['damping_x_scale'] = x_scale - param_json['damping_y_scale'] = y_scale - param_json['damping_z_scale'] = z_scale - - - x_offset = round(bone.angular_offset_x,3) - y_offset =round( bone.angular_offset_y,3) - z_offset = round(bone.angular_offset_z,3) - - - param_json['angular_offset_x'] = x_offset - param_json['angular_offset_y'] = y_offset - param_json['angular_offset_z'] = z_offset - - + param_json = export_bone_parameters_toJson(param_json, bone) if len(param_json) != 0: self.report({'INFO'},"Exporting Posebone {0}".format(bone.basename)) diff --git a/CAfP/global_config.py b/CAfP/global_config.py index f170b49..8f3aad5 100644 --- a/CAfP/global_config.py +++ b/CAfP/global_config.py @@ -1,3 +1,4 @@ gui_status = "ACTIVE_SESSION" gui_err_msg = "" IMPORT_DATA= False + From 6d20c3198f16a55868b008979737e3098afccb92 Mon Sep 17 00:00:00 2001 From: Daksitha Date: Mon, 25 Jan 2021 12:52:04 +0100 Subject: [PATCH 2/5] refine range function Now can select more than one ranget to change the animation and save data in a json file --- CAfP/__init__.py | 311 ++++++++----- CAfP/__pycache__/__init__.cpython-37.pyc | Bin 11524 -> 12688 bytes CAfP/__pycache__/file_op.cpython-37.pyc | Bin 5958 -> 6272 bytes CAfP/__pycache__/global_config.cpython-37.pyc | Bin 259 -> 287 bytes CAfP/file_op.py | 20 +- CAfP/global_config.py | 1 + CAfP_AllPoseBoneParameters.json | 440 ++++++++++++++++++ 7 files changed, 640 insertions(+), 132 deletions(-) create mode 100644 CAfP_AllPoseBoneParameters.json diff --git a/CAfP/__init__.py b/CAfP/__init__.py index 0998537..ee0b558 100644 --- a/CAfP/__init__.py +++ b/CAfP/__init__.py @@ -16,7 +16,7 @@ "author" : "daksitha", "description" : "", "blender" : (2, 83, 0), - "version" : (0, 0, 1), + "version" : (0, 1, 0), "location" : "View3D", "warning" : "", "category" : "Animation" @@ -26,6 +26,8 @@ from bpy.utils import unregister_class from bpy.utils import register_class import os +import json +from bpy.app.handlers import save_post #from . damping_tools import DampAnimation #from . offset_tools import AngularOffsetAnimation @@ -38,6 +40,10 @@ import CAfP.global_config as global_config +from . import file_op +################# Globals ############# +BONE_PARAMETERS_FILE_NAME = "CAfP_AllPoseBoneParameters.json" + ################## bone properties ################### def update_bone_animation(self, context): #print("bone animator", self) @@ -207,42 +213,52 @@ def update_timewarping(self,context): description="initial location of timewarping control curve", ) -def export_bone_parameters_toJson(param_json, bone): - - #param_json['anim_start'] = bone.anim_start - param_json['anim_ignore_from_start'] = bone.anim_ignore_from_start - param_json['anim_ignore_from_end'] = bone.anim_ignore_from_end - - x_scale = round(bone.damping_x_scale,3) - y_scale = round(bone.damping_y_scale,3) - z_scale = round(bone.damping_z_scale,3) - - param_json['damping_x_scale'] = x_scale - param_json['damping_y_scale'] = y_scale - param_json['damping_z_scale'] = z_scale - - - x_offset = round(bone.angular_offset_x,3) - y_offset =round( bone.angular_offset_y,3) - z_offset = round(bone.angular_offset_z,3) - - - param_json['angular_offset_x'] = x_offset - param_json['angular_offset_y'] = y_offset - param_json['angular_offset_z'] = z_offset - - return param_json +def getAllPoseBoneParameters(self, activeArm:bpy.types.Armature): + out_data = {} + poseBones = activeArm.pose.bones + try: + #get parameters that are saved + path =bpy.path.abspath("//{}".format(BONE_PARAMETERS_FILE_NAME)) + #out_data['armature_name'] = '{}'.format(obj.name) + if file_op.isInCurrDirectory(BONE_PARAMETERS_FILE_NAME): + print("Extracting posebone parameters from {} ...".format(BONE_PARAMETERS_FILE_NAME)) + with open(path, 'r') as j_file: + + j_database = json.loads(j_file.read()) + #print(' j_database: {}'.format(j_database)) + + if 'name' in j_database: + if j_database['name'] == activeArm.name: + print("WARNING: {} is not saved for the current armature object ".format(BONE_PARAMETERS_FILE_NAME)) + + out_data = j_database + else: + # for bone in poseBones: # type: bpy.types.PoseBone + # param_json = {} + # #range + # param_json = file_op.export_bone_parameters_toJson(param_json, bone) -def isInCurrDirectory(file_name): - filepath = bpy.data.filepath - directory = os.path.dirname(filepath) - _, _, filenames = next(os.walk(directory)) - for files_ in filenames: - if files_ == file_name: - print('file {} already in the direcotry'.format(files_)) - return True - return False + # if len(param_json) != 0: + + # out_data['{0}'.format(bone.basename)] = [] + # out_data['{0}'.format(bone.basename)].append(param_json) + out_data['name'] = activeArm.name + with open(path, 'w') as out_file: + json.dump(obj=out_data, fp=out_file, indent=2) + print('Creating {0} at {1} ..'.format(BONE_PARAMETERS_FILE_NAME, file_op.simple_path(path))) + + except OSError as err: + self.report({"ERROR"}, "{} while creating CAfP_temp_bone.json. Please save the blend file".format(err)) + #print('Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) + + except IOError as err: + if bpy.data.is_saved: + self.report({"ERROR"}, "{},while creating {}. Maybe save the blend file".format(err,bpy.path.basename(path))) + except json.JSONDecodeError: + self.report({"ERROR"}, "Errors in json file: {}".format(bpy.path.basename(path))) + + return out_data class SELECTRange(bpy.types.Operator): @@ -274,34 +290,73 @@ def poll(cls, context): def execute(self,context): import json - obj = bpy.context.active_object + active_armature = bpy.context.active_object active_bone = bpy.context.active_pose_bone # type: bpy.types.PoseBone - try: - #save a file in the current directory - path =bpy.path.abspath("//CAfP_Temp_BProperties.json") - #print(path) - out_data = {} - out_data['armature_name'] = '{}'.format(obj.name) - if not isInCurrDirectory('CAfP_Temp_BProperties.json'): - with open(path, 'w') as out_file: - json.dump(obj=out_data, fp=out_file, indent=2) - self.report({'INFO'}, 'Create a CAfP temp_bone.json at {}'.format(path)) - - active_bone.is_range_selected = True - except OSError as err: - self.report('WARNING','Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) - active_bone.is_range_selected = False - except IOError as err: - active_bone.is_range_selected = False - if path != "": - self.report({'WARNING'},"{},while creating {}. Please save the blend file".format(err,bpy.path.basename(path))) - except json.JSONDecodeError: - active_bone.is_range_selected = False - self.report({'WARNING'},"Errors in json file: {}".format(bpy.path.basename(path))) + + if not len(global_config.BONE_PARAMETERS_JSON): + global_config.BONE_PARAMETERS_JSON = getAllPoseBoneParameters(self,active_armature) + + active_bone.is_range_selected = True + + # try: + # #save a file in the current directory + # path =bpy.path.abspath("//CAfP_Temp_BProperties.json") + # #print(path) + # out_data = {} + # out_data['armature_name'] = '{}'.format(obj.name) + # if not isInCurrDirectory('CAfP_Temp_BProperties.json'): + # with open(path, 'w') as out_file: + # json.dump(obj=out_data, fp=out_file, indent=2) + # self.report({'INFO'}, 'Create a CAfP temp_bone.json at {}'.format(path)) + + # active_bone.is_range_selected = True + # except OSError as err: + # self.report('WARNING','Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) + # active_bone.is_range_selected = False + # except IOError as err: + # active_bone.is_range_selected = False + # if path != "": + # self.report({'WARNING'},"{},while creating {}. Please save the blend file".format(err,bpy.path.basename(path))) + # except json.JSONDecodeError: + # active_bone.is_range_selected = False + # self.report({'WARNING'},"Errors in json file: {}".format(bpy.path.basename(path))) + + return {'FINISHED'} + +def appendBoneData(self, active_bone): + try: + + #time1 = time.time() + path =bpy.path.abspath(BONE_PARAMETERS_FILE_NAME) + param_json = {} + bone_dictionary = json.loads(global_config.BONE_PARAMETERS_JSON) + bone_name = active_bone.name + + if bone_name in bone_dictionary: + param_json = file_op.get_bone_parameters_forJson(param_json,active_bone) + bone_dictionary['{}'.format(bone_name)].append(param_json) + else: + bone_dictionary['{}'.format(bone_name)] = [] + bone_dictionary['{}'.format(bone_name)].append(param_json) + self.report({'INFO'},"{} parameters set".format(bone_name)) + + global_config.BONE_PARAMETERS_JSON = bone_dictionary + out_data = bone_dictionary + with open(path, 'w') as output: + json.dump(obj=out_data, fp=output, indent=2) + + except OSError as err: + self.report('WARNING','Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) + except IOError as err: + if bpy.data.is_saved: + self.report({'WARNING'},"{},while creating {}. Please save the blend file".format(err,bpy.path.basename(path))) + except json.JSONDecodeError as err: + self.report({'WARNING'},"Errors {}in json file: {}".format(err, bpy.path.basename(path))) + class GoBackToRangeSelector(bpy.types.Operator): """ Save the current changes for this range and go back to range panel. @@ -331,56 +386,51 @@ def execute(self,context): import time - obj = bpy.context.active_object + #obj = bpy.context.active_object #save a file in the current directory - active_bone = bpy.context.active_pose_bone + appendBoneData(self,active_bone) + active_bone.is_range_selected = False - try: - - time1 = time.time() - path =bpy.path.abspath("//CAfP_Temp_BProperties.json") - out_data = {} - with open(path, 'r') as j_file: - - j_database = json.loads(j_file.read()) - print(' j_database: {}'.format(j_database)) - - if 'name' in j_database: - if j_database['name'] == obj.name: - self.report({'WARNING'},"Json database and Armature names are not matching") - - param_json= {} - param_json = export_bone_parameters_toJson(param_json, active_bone) - if active_bone.name in j_database: - j_database['{}'.format(active_bone.name)].append(param_json) - else: - j_database['{}'.format(active_bone.name)] =[] - j_database['{}'.format(active_bone.name)].append(param_json) - - out_data = j_database - with open(path, 'w') as output: - json.dump(obj=out_data, fp=output, indent=2) + return {'FINISHED'} + +class ApplyBoneParameters(bpy.types.Operator): + """ + Cash/Save pose bone configurations for future use . + """ + bl_label = 'Save PoseBone configuration' + bl_idname = 'cafp.save_posebone_configuration' - #set the flag to change the ui - - active_bone.is_range_selected = False + @classmethod + def poll(cls, context): - self.report({'INFO'},"CAfP_Temp_BProperties {} added in {} secs".format\ - (active_bone.name, time.time()-time1)) - except OSError as err: - self.report('WARNING','Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) - except IOError as err: - if path != "": - self.report({'WARNING'},"{},while creating {}. Please save the blend file".format(err,bpy.path.basename(path))) - except json.JSONDecodeError as err: - self.report({'WARNING'},"Errors {}in json file: {}".format(err, bpy.path.basename(path))) + if not (context.mode == 'POSE'): + return False + obj = context.active_object # type: bpy.types.Object + active_bone = bpy.context.active_pose_bone # type: bpy.types.PoseBone + if obj is not None: + if obj.type == 'ARMATURE': + anim_data = obj.animation_data + if anim_data is not None: + act = anim_data.action + if act is not None: + if active_bone is not None: + return True - return {'FINISHED'} + def execute(self,context): + import json + import time + #obj = bpy.context.active_object + #save a file in the current directory + + active_bone = bpy.context.active_pose_bone + appendBoneData(self,active_bone) + + return {'FINISHED'} @@ -390,6 +440,8 @@ def execute(self,context): isArmWithAnim = False isArmWithNLA = False + + class VIEW3D_PT_cafpmainpanle(bpy.types.Panel): bl_label = "CAfP_Panel" bl_space_type = 'VIEW_3D' @@ -407,6 +459,7 @@ def draw(self, context): scene = context.scene box_info = self.layout.box() + if active_object is not None: if active_object.type == 'ARMATURE': @@ -464,28 +517,30 @@ def draw(self, context): if global_config.gui_status.startswith("ACTIVE"): active_bone = bpy.context.active_pose_bone - #TODO:Active still it has no bone selected - #bone_name = active_bone.basename layout.row() + #active_armature = context.active_object #layout.row().label(text="Active Bone: {}".format(bone_name), icon= 'BONE_DATA') - if active_bone.is_range_selected: - #damping - damp_row = layout.row(align=True) - damping_box = damp_row.box() - damping_box.label(text = "Animation Amplitude Modifier:",icon='FORCE_HARMONIC') + - #offset - offset_row = layout.row() - offset_box = offset_row.box() - offset_box.label(text = "Animation Angular Offset:",icon = 'ORIENTATION_GIMBAL') - #go back to range selector + + #go back to range selector - if active_bone is not None: + if active_bone is not None: + if active_bone.is_range_selected: + #damping + damp_row = layout.row(align=True) + damping_box = damp_row.box() + damping_box.label(text = "Animation Amplitude Modifier:",icon='FORCE_HARMONIC') + + #offset + offset_row = layout.row() + offset_box = offset_row.box() + offset_box.label(text = "Animation Angular Offset:",icon = 'ORIENTATION_GIMBAL') col = damping_box.column(align=True) col.prop(active_bone, "damping_x_scale",toggle=True, expand=True) @@ -497,19 +552,15 @@ def draw(self, context): col2.prop(active_bone, "angular_offset_y",toggle=True, expand=True) col2.prop(active_bone, "angular_offset_z",toggle=True, expand=True) - col2.operator('cafp.back_to_range_selection', text= 'back to range selector') - - else: - infor_damp = damping_box.row() - info_off = offset_box.row() - info_off.label(text= "select a bone") - infor_damp.label(text= "select a bone") - else: - #Range - settings_row = layout.row(align=True) - settings_box = settings_row.box() - settings_box.label(text="Keyframe Range for Change", icon='SETTINGS') - if active_bone is not None: + col3 = offset_box.row(align=True) + col3.operator('cafp.save_posebone_configuration', text= 'Save') + col3.operator('cafp.back_to_range_selection', text= 'Back') + else: + #Range + settings_row = layout.row(align=True) + settings_box = settings_row.box() + settings_box.label(text="Keyframe Range for Change", icon='SETTINGS') + set_col = settings_box.column(align=True) bn_name = set_col.row() bn_name.label(text='Active Bone: {}'.format(active_bone.basename)) @@ -518,10 +569,14 @@ def draw(self, context): set_col.prop(active_bone, "anim_ignore_from_end", expand=True) set_col.operator('cafp.select_posebone_range', text= 'Next') - else: - infor_ = settings_box.row() - infor_.label(text= "select a bone") + + else: + warning_ = layout.row(align=True) + warning_box = warning_.box() + warning_box.label(text="WARNING", icon='BONE_DATA') + warning_box.row().label(text="Select single bonea") + #expoert and import exp_rw = layout.row(align=True) @@ -582,7 +637,7 @@ def draw(self, context): classes = (VIEW3D_PT_cafpmainpanle,BoneAnimatorOffDamp,CreateTimeWarpingCurve,TimeWarper,ExportPoseBone,\ - LoadPoseBone,SELECTRange,GoBackToRangeSelector) + LoadPoseBone,SELECTRange,GoBackToRangeSelector,ApplyBoneParameters) def register(): for clas in classes: diff --git a/CAfP/__pycache__/__init__.cpython-37.pyc b/CAfP/__pycache__/__init__.cpython-37.pyc index 75b6bd02b5188042c3fd5b280d0f1810681b1609..f08f31658969f1845f0e3a19bc5ef5ed59424f56 100644 GIT binary patch literal 12688 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 delta 1097 zcmaKrOHUI~6vum^EyJ|aY3V?l09rvULjfNkDm9mS= ztZ3Ld@v=5YQo<`gBLm{Oywj9|3U$Iy!HX-15Ww|PZmi_RR$#Qot)447JSBDl$@a>u zVVrdVF@(UR{RJ?W_X6&T!Qff{dHn1bPVh;f3uRv=EL0`#YXzx`4yBp2mdBN8@?ZvI zvjEq}%~FB#YiL|Y+(6t!q!G6Oy5!15gB$tGl4TZL@0?j+Zp~`Onm3j~IQwF4Pe`j7 zGn=)T?MlvpTH90Df{3f_go|M{>0_||{AQ%SyrEtpq(^)SPYj&|Z+29#=1Hue4WR>c zFKIcKjAF+;zFiipvi!HNxo6!U|-)8CjG%ls=mWb8y9D<3R zx)Z%UC>sE9w55Demv|F8e-`daX35S_!#4OGjNTR#(Pkf>+Lp*iACXb99c_f$6VQ&4 zx1v)^9>0Xs#t`F(3B+Z@Bw`9NB38AI@KuzDm!MR+1X(bjiceZI$(FaZZgS*sGyk!L zpT$7KN~F@HmybXyv;w7y_YH~GN+0O)`-s1?v4gKdj`iyQulKhivA&c8c^_d|_&=72 zx5^76Si{lRt7f?m-(*UULX)p!i!H9tc8bh$rRgH$hHY|=*PP>p;@B&9VA)v8mHP4~ eEiJQt0;UxQNM!dHBta6cl7q6=FeWu>gTDZr;r6}& diff --git a/CAfP/__pycache__/global_config.cpython-37.pyc b/CAfP/__pycache__/global_config.cpython-37.pyc index 9f4e86524f9b8bcdf90cd99bc2bfeb54fe4c0c5c..4838a1fc4a140987d387b529a48691f7665de7fb 100644 GIT binary patch delta 119 zcmZo>n$N`R#LLUY00c(Ac@vT*@=6+r068fPQ4A@JQH&`}QB0W(QOqgK!3>%#xA+{L zLp;M=o Date: Tue, 26 Jan 2021 22:24:59 +0100 Subject: [PATCH 3/5] version 1 2 with new features Now the bone parameters are saved in a temp file and also import function apply all changes --- CAfP.zip | Bin 0 -> 27564 bytes CAfP/.vscode/.ropeproject/config.py | 114 +++++++++++ CAfP/.vscode/.ropeproject/objectdb | Bin 0 -> 6 bytes CAfP/CAfP_AllPoseBoneParameters.json | 5 + CAfP/__init__.py | 116 +++-------- CAfP/__pycache__/__init__.cpython-37.pyc | Bin 12688 -> 10434 bytes CAfP/__pycache__/bone_motion.cpython-37.pyc | Bin 5753 -> 9500 bytes CAfP/__pycache__/file_op.cpython-37.pyc | Bin 6272 -> 6140 bytes CAfP/__pycache__/global_config.cpython-37.pyc | Bin 287 -> 375 bytes CAfP/__pycache__/time_warping.cpython-37.pyc | Bin 3252 -> 3249 bytes CAfP/bone_motion.py | 192 ++++++++++++++++-- CAfP/file_op.py | 103 ++++------ CAfP/global_config.py | 5 +- 13 files changed, 375 insertions(+), 160 deletions(-) create mode 100644 CAfP.zip create mode 100644 CAfP/.vscode/.ropeproject/config.py create mode 100644 CAfP/.vscode/.ropeproject/objectdb create mode 100644 CAfP/CAfP_AllPoseBoneParameters.json diff --git a/CAfP.zip b/CAfP.zip new file mode 100644 index 0000000000000000000000000000000000000000..31ee0758ff4b1e5be4e5882c3ef713c71301eafe GIT binary patch literal 27564 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 f*ZZd*|CIk;Z%C-W{^<~YyzzfLh|A6RucQ9~Y import ` by default. + prefs['prefer_module_from_imports'] = False + + # If `True`, rope will transform a comma list of imports into + # multiple separate import statements when organizing + # imports. + prefs['split_imports'] = False + + # If `True`, rope will remove all top-level import statements and + # reinsert them at the top of the module when making changes. + prefs['pull_imports_to_top'] = True + + # If `True`, rope will sort imports alphabetically by module name instead + # of alphabetically by import statement, with from imports after normal + # imports. + prefs['sort_imports_alphabetically'] = False + + # Location of implementation of + # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general + # case, you don't have to change this value, unless you're an rope expert. + # Change this value to inject you own implementations of interfaces + # listed in module rope.base.oi.type_hinting.providers.interfaces + # For example, you can add you own providers for Django Models, or disable + # the search type-hinting in a class hierarchy, etc. + prefs['type_hinting_factory'] = ( + 'rope.base.oi.type_hinting.factory.default_type_hinting_factory') + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! diff --git a/CAfP/.vscode/.ropeproject/objectdb b/CAfP/.vscode/.ropeproject/objectdb new file mode 100644 index 0000000000000000000000000000000000000000..0a47446c0ad231c193bdd44ff327ba2ab28bf3d8 GIT binary patch literal 6 NcmZo*sx4&D0{{kv0iOT> literal 0 HcmV?d00001 diff --git a/CAfP/CAfP_AllPoseBoneParameters.json b/CAfP/CAfP_AllPoseBoneParameters.json new file mode 100644 index 0000000..3ca4395 --- /dev/null +++ b/CAfP/CAfP_AllPoseBoneParameters.json @@ -0,0 +1,5 @@ +{ + "mixamorig12:RightForeArm": [ + {} + ] +} \ No newline at end of file diff --git a/CAfP/__init__.py b/CAfP/__init__.py index ee0b558..0ccd94b 100644 --- a/CAfP/__init__.py +++ b/CAfP/__init__.py @@ -16,7 +16,7 @@ "author" : "daksitha", "description" : "", "blender" : (2, 83, 0), - "version" : (0, 1, 0), + "version" : (0, 1, 2), "location" : "View3D", "warning" : "", "category" : "Animation" @@ -41,9 +41,18 @@ import CAfP.global_config as global_config from . import file_op +from . import bone_motion + +from bpy.app.handlers import persistent ################# Globals ############# -BONE_PARAMETERS_FILE_NAME = "CAfP_AllPoseBoneParameters.json" +# @persistent +# def change_param_file_name(scene): +# blender_path =bpy.data.filepath +# blen_file_name = file_op.simple_path(blender_path) +# global_config.BONE_PARAMETERS_FILE_NAME = blen_file_name + +# bpy.app.handlers.save_post.append(change_param_file_name) ################## bone properties ################### def update_bone_animation(self, context): #print("bone animator", self) @@ -214,53 +223,8 @@ def update_timewarping(self,context): ) -def getAllPoseBoneParameters(self, activeArm:bpy.types.Armature): - out_data = {} - poseBones = activeArm.pose.bones - try: - #get parameters that are saved - path =bpy.path.abspath("//{}".format(BONE_PARAMETERS_FILE_NAME)) - #out_data['armature_name'] = '{}'.format(obj.name) - if file_op.isInCurrDirectory(BONE_PARAMETERS_FILE_NAME): - print("Extracting posebone parameters from {} ...".format(BONE_PARAMETERS_FILE_NAME)) - with open(path, 'r') as j_file: - - j_database = json.loads(j_file.read()) - #print(' j_database: {}'.format(j_database)) - - if 'name' in j_database: - if j_database['name'] == activeArm.name: - print("WARNING: {} is not saved for the current armature object ".format(BONE_PARAMETERS_FILE_NAME)) - - out_data = j_database - else: - # for bone in poseBones: # type: bpy.types.PoseBone - # param_json = {} - # #range - # param_json = file_op.export_bone_parameters_toJson(param_json, bone) - # if len(param_json) != 0: - - # out_data['{0}'.format(bone.basename)] = [] - # out_data['{0}'.format(bone.basename)].append(param_json) - out_data['name'] = activeArm.name - with open(path, 'w') as out_file: - json.dump(obj=out_data, fp=out_file, indent=2) - print('Creating {0} at {1} ..'.format(BONE_PARAMETERS_FILE_NAME, file_op.simple_path(path))) - - except OSError as err: - self.report({"ERROR"}, "{} while creating CAfP_temp_bone.json. Please save the blend file".format(err)) - #print('Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) - - except IOError as err: - if bpy.data.is_saved: - self.report({"ERROR"}, "{},while creating {}. Maybe save the blend file".format(err,bpy.path.basename(path))) - except json.JSONDecodeError: - self.report({"ERROR"}, "Errors in json file: {}".format(bpy.path.basename(path))) - - return out_data - class SELECTRange(bpy.types.Operator): """ Select the keyframe range to edit in the current animation. @@ -294,7 +258,8 @@ def execute(self,context): active_bone = bpy.context.active_pose_bone # type: bpy.types.PoseBone if not len(global_config.BONE_PARAMETERS_JSON): - global_config.BONE_PARAMETERS_JSON = getAllPoseBoneParameters(self,active_armature) + path_ =bpy.path.abspath("//{}".format(global_config.BONE_PARAMETERS_FILE_NAME)) + global_config.BONE_PARAMETERS_JSON = bone_motion.getAllPoseBoneParameters(self,active_armature,path_) active_bone.is_range_selected = True @@ -327,36 +292,6 @@ def execute(self,context): return {'FINISHED'} -def appendBoneData(self, active_bone): - try: - - #time1 = time.time() - path =bpy.path.abspath(BONE_PARAMETERS_FILE_NAME) - param_json = {} - bone_dictionary = json.loads(global_config.BONE_PARAMETERS_JSON) - bone_name = active_bone.name - - if bone_name in bone_dictionary: - param_json = file_op.get_bone_parameters_forJson(param_json,active_bone) - bone_dictionary['{}'.format(bone_name)].append(param_json) - else: - bone_dictionary['{}'.format(bone_name)] = [] - bone_dictionary['{}'.format(bone_name)].append(param_json) - self.report({'INFO'},"{} parameters set".format(bone_name)) - - global_config.BONE_PARAMETERS_JSON = bone_dictionary - out_data = bone_dictionary - with open(path, 'w') as output: - json.dump(obj=out_data, fp=output, indent=2) - - except OSError as err: - self.report('WARNING','Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) - except IOError as err: - if bpy.data.is_saved: - self.report({'WARNING'},"{},while creating {}. Please save the blend file".format(err,bpy.path.basename(path))) - except json.JSONDecodeError as err: - self.report({'WARNING'},"Errors {}in json file: {}".format(err, bpy.path.basename(path))) - class GoBackToRangeSelector(bpy.types.Operator): """ Save the current changes for this range and go back to range panel. @@ -385,11 +320,15 @@ def execute(self,context): import json import time + active_armature = bpy.context.active_object + path =bpy.path.abspath("//{}".format(global_config.BONE_PARAMETERS_FILE_NAME)) + if not len(global_config.BONE_PARAMETERS_JSON): + global_config.BONE_PARAMETERS_JSON = bone_motion.getAllPoseBoneParameters(self,active_armature,path) - #obj = bpy.context.active_object - #save a file in the current directory + active_bone = bpy.context.active_pose_bone - appendBoneData(self,active_bone) + #bone_motion.appendBoneData(self,active_bone, path) + active_bone.is_range_selected = False @@ -426,9 +365,16 @@ def execute(self,context): #obj = bpy.context.active_object #save a file in the current directory + path =bpy.path.abspath("//{}".format(global_config.BONE_PARAMETERS_FILE_NAME)) + active_armature = bpy.context.active_object + if not len(global_config.BONE_PARAMETERS_JSON): + global_config.BONE_PARAMETERS_JSON = bone_motion.getAllPoseBoneParameters(self,active_armature,path) active_bone = bpy.context.active_pose_bone - appendBoneData(self,active_bone) + param_json = {} + param_json,isDefaultValue = file_op.get_bone_parameters_forJson(param_json,active_bone) + + bone_motion.appendBoneData(self,active_bone, param_json,path) return {'FINISHED'} @@ -581,9 +527,9 @@ def draw(self, context): #expoert and import exp_rw = layout.row(align=True) exp_box = exp_rw.box() - exp_box.label(text="Export PoseBone changes", icon='EXPORT') - export_butt_rw = exp_box.row() - export_butt_rw.operator('cafp.export_posebone_data',text='Export') + exp_box.label(text="Load PoseBone Values", icon='EXPORT') + #export_butt_rw = exp_box.row() + #export_butt_rw.operator('cafp.export_posebone_data',text='Export') import_butt_rw = exp_box.row() import_butt_rw.operator('cafp.import_posebone_data',text='Import') diff --git a/CAfP/__pycache__/__init__.cpython-37.pyc b/CAfP/__pycache__/__init__.cpython-37.pyc index f08f31658969f1845f0e3a19bc5ef5ed59424f56..f519f2c78e15e573b650525161f7011bff9a6bc2 100644 GIT binary patch delta 4224 zcmcgvU2Gd!754miJht=WBu<;OO>C!W5~ulV(rwfK{4`0^rcRoq+cFJ1JMo>Qb{&uR z&ScXqwoJDbi$IZDuFyWv6$uio1c;X+UJxK5B#>Bvv=2y(!~>!aAoT?aUSLHz=h{t^ zkn(~=qkePlIp?1H^PPL|@uTF=uT_myRt7xq?|DA-cHi~KRSm*tkK4antR&$~-HKoH z3m&49`iyTStc5||NA^GTX!WL$-k07_8b~8KKn{{aq={6T^`v=S1xrJ^Q9n@jh>+-O zJPwvUVx;9iJ&HWYA@0&d4wF`x#1Ya)+F_86bzgaq=CVCbI`_0k%J!qAYfpQ$Z0{yL zVDDX*%5h_65!cs5`pB^zhL&=NeloB_f0*lA$#L=qIk7F!k!6q3MoyAJ*t2$WikyaT z2ltJWGiEzEyDst}JN2XG$mhs;h+J7TJIIA~Z`s&YHV% zc8rW~)Amhx$OO6c&_gcq$j2T?T0iI}$z{-8-qH0)s6ActqO5 za^3|+1(^oer`}%$OCq)pvu`Ugp@aQW851;C>ASYWmh!y^+CTYzAJf!C#+au@@(#tI zamkev(}^)xnKLtH(xD>zgSuFaapPXsYbVXDNh2)bZ)}a?FdSkaxpm8?qh~XQZaXxU zv-J!t@niN?e?&OPzULoq)dEgx#auHeEI%&NX6zl=3Q>x~LV^8lKLurJfdV}b^1YCe zbW-n{Q3xL8!J)g#t_CjGZ(A-#YDMT^-wzaC?n!U(9Q#S#mu7UDeOMFQ7e!AFe0_4x%4D8<*l%jiRw-aY;z!}XJpgN0Y>rZF_zd!&H~{RX6C0;jB`VUIMM=%^A*Zy|nNsC@5dO z&%A3UR~_>OXzUPxM^N!k3m#floLKYh`t{U52n3Dn2f zvx6-~Kgm6bL%)rFZ(im{9_d%pK!3_p@Hy2R zp}a4zY>EqF!BL z0ISmu;(g6urkp{Im7?juJEJdI^fKH%T9uK@nOQOdFV{uGG2;F`6NyiPXA{3V0z8tA zmzP$RvM-uT#%jiS)5xrvyN?~_SPJ>y2Lk3;t?CWK2a*huO$H2!?A=K0f6p`n;$Pb% z(+u|4$O1fqiD+9@EBI`2zro&*{<-p#ypXOS6?eo(68#}ti!tGor@@xL3q>(qLqt-y zE)<&bO&ijtr_h{lP6r59RLZ(2c=F8~HK2{;Bk5XRPgSEf+mQF9J={NDhY`wti$k`|Xhn-eK5ojn%ac2up0DO$QP_ZtE1Zr=PYR6@)DN zSNj>i>$@>Lo0v>Yu=5?Urtp+ykm!tMo0yPMo>8`|jNP1>o}Fjk>iAhiQ|CaOpS(Ke z)@&<6N-rGkVPA}|M);w?@(C&~>n`2-ZqVZ_+}RQ2XNEsD2{zF=c(xAQOPAWNR|l_G zS4mo#)s?I(=ctwAH?ylQ8n&4=;0C|Xe$?4gY~6Nn9%8Upvru6cdMXP??$zsb2E+Q$ zU{b320rZTOG#o9kn7pGet~w4B2K=z8#8}Dc)LPSmD5bK?aGLLG0c&Z=hLep3kc+$l z1}JZ=3>27Fre8xG&?>;qfo@PJfbXjoM)6??@X~yXSshoSsZhCPaS$!|QbI??ybF_9 z)1W@c@$sutD>;k8%>q*e!!1p5*7yMUT;+AMW5OA`)E)G{F z)L46j=lOSRxa&KD#GZG}hjzV33v8ylum3~b?&wa4VRI4SgRLt8ZX5U$WtlFruAWBr z>+bI3HQ)iIx}3}y_O=k%+f}K#jO9C>f`ZwWLFIvKi+%*1uN1!lEgAxd3-k%f(JkPe z1FPAW-Dh5PuM+4tvCmncK2u5wOgGmLzYKa-ofH(N7?a|(T+y=mW1xl53iou+Z6ixE zaC_5Q{v`84pblKM3M?gbths?X8paUy2>1X{ym{$<0Ie2(&h+dkDoYgx%+Ny*AhfU> zy+`#7iWWi+zzt4jof*h{lREFwcTi0cYyd4_WK%2fTfm?WT|+HCscyxHWo5Ry;2ENQ z2-JM-57E9a+@H)Kc0+|9S>SBqy5yXXpOfFym5~&T7@c=ylcCpx5 z^$bK{G>{Whar{C@54qTmD+RtKmBeuzCsj^fQh7@G7bIOt%9T7hPpQhAU!3oB&t3q6 zl;mPih@6C^kU-{meru{p;wEn2%Dt^Jw3{7Ji)0x3i z%w%aiGc5aEtD-TBY`QA#e%pa*2H~T7mGT)DUsZv6o`aQDQU+I_hf%?E^u~I~S zurkPo*zm_%WysTO!?mOAC>vp;>=--FPOx5Yh@HG|p=6{s>KsdIoMNXRQR8@0!)9k5 zQR9THagv>7=P;)8>JGA_CQvMA4!lC7MQhtFwi}LaNsf6#D zgnp4-+DAW|(4S+M_tDQu`g!&|dx5>!#pj7N&3%%+#J-3Xdy2ixUcvKeS$B+G@t$I@ z-Z$_zQhUbvLc;kq_BuHCdQY=A?x&No3rX3V?CL{h&&slKHo>m3$u_r(33ZB1cTq1% ze$TO)@9OM2d+TGfa{0Q(X4%^xYwT@V_WZq6O;2Rpt#IAvqKA3G3a>V)P-K_uUW0jDWIynDKoqO)ugHcXd)MWSYGX}UAb4v& z-;sTk$8=HJYH)9@8iXEqR_bmLfL45nk_+4qJg4agA}s{{Ies%b zO^fGD)a$Lnd6#1qFyLUk7Wj=7T1on&C;cYz3ra{rt)|zEz0?B@lC5DU^zxV~Qp?R9 zk@A~?Fjw5wrYJ090IpnQpN|>B47~cP$gcQ}(Ay6GSmS5F>Sylcl{@bQ==080vWs^n zn$0OUbnh(q?j|OB=bG98d&b{tFuCw8(w)oWFF$`r?NxBcWz25`cW7F79H-i-hK@6i zF%4}s(advbJdPR=w(%0pMo!V-=a7%Gx9woXt$Wc^n?CKly+SK&yYo&bR6BM{kZDz7|nr-L~?xQ;DrNw&SRjv0A@eYaY# z+wSVBw-Q1lw0A_#AsU)pYxvxAh>Pmx>5bK~==@v$U3=4Q?ARNtcIewxSxfary~qJY z1Ko|GC}h*KpVAcdL|-*npusJAb&Sem(Q_;7-pU3|1Kg9DaH>I_FMGDfs;FjTmmo;8 z$xK^B(^zTJb5caNkqNauoy0SSpza#6!L*GW4`ZX2>f~zXZYoU2se3xFQAy2Y`lwdR z?54I~h*MMAuiCpN_+&#XHfy~rd2Jt2QLyuTVqjFrCxZMwTc1MTVJiW+THth>;s5NiA*|`~$R3cUs4pUE>yv?3c9#?Y7pKp<0k;^EJgc z1HKn_vtduIFE-*V%QEXepgwryhzG`0icO5qppkU=KyH6%YT=QM{3klk=-Mt|e>4(n zd;KiGuCt!KbZk*8)rO(`BkQ*Ip4RvXtp;SP`J~kati)h#2z;)#+ZU+4T%lpr`yrfO z0H>bXQOWCTIy4n@RjdDAjGfk3wU*;R-^Oh%HlSgO<;c8v@x$HdndxoP1kw}$LV0B0 z?PeRqC{6w0u01|JE_9_7qE~KBER<)<*RR+pfGTbHp-mW!*{eR6#siYTJxGAdfeyEz zhm|I>g?^Wt_#j|E-oQf`fH;{dkYOW?6gs2t^TSKKwj0_XK1bb(^z_2Q+(I;gzV5CA zcG)Y0;;5d)UJ%KqL?se$job6kfB_5(#v_L!k*7^~Ey8>+9ANR`?znx^-GOB|tijP~ z&V3%()rL)API941kBtbE7E7dQxdN$+Kykx$k#&~?naN-+FnKY04SL&|pIDfYZpQ-}Cgn+*y-Q-Xo!t|kxg-Jb&bR7T`pb%4MN*S4K zYqKeOf+~;|(68)!Zcz?cWVlBFR%B=A6v32w->L?V+$UizV~r$S?|XZ3t~}+f_{@`4 z$8t(}PSe;de=AfbBS+J{CMSE7N-{NvmQ>_xvYgnd+LD^`I6tU)M_?BY#mWB!egOeV zO*df_45J?=p{N&(Vv0;e(J1xg^@3i~&l~;v`BXoQ#<<=O!@*b4W`!EI{>W5b#V@#k z#M5we*D40nD=B7Fpg$^U4_bnyKi2N)l`I|eaSXDU1$oGcp2g`K)00aQPDHbLJNZ-g zR(?rsq|^o!geK_YASBcN-UT2@vlJ8}u`%`0m+M&%Il^<7=lm)JyqT`qEgom zj#H!d;t{f=Z$mEL6=dM<(dw{8A&^}y1q4S=6ZQxCzLveG2jjqL8c>}PW}GZDV$;d7 z)VeOQnLM5@32SDyJiGYT^we0MFM(%gQPdi35bYHtqIa$CFS~UIc6YV9CI$~`1QJ2{ zF_SV-`|hZ(!D9dn9WX=Ph`wa)TDq0{)X@Q)ll8W}m95Y_N9$HZ1x>D)1<@)PnG?}K z_gW=&%a8)gaY!vVj>tO>_InGu#SsO^d4J2TCnZ_OVg3rp)^gpcyUSi(=(>Lm zNO#GXlC6Z%=h2rt65g^DEeUR&ca$-MeN*!80@tnK5CLX%m{7!~+wkg%q@TWiuvBd# zY@)0dose=)44ly4x6crg_Q(3aCFyj~NSFCK)^&zgkwV6K4bKB2&gF+(rvegczKLWk z!yA;hDItkgA7PVn?^Ck>bCll!z>XG-pzu*5934A!tM-d>58AgOWeAonQI=1@%0vg6 zJHLZmdJpgoFfk3_nSs``0P}LSJfLMy4Em_XSy9i8#@wR*r(#g57Th=x=T`T64B#OA;{irGc2sJ8m^+-T zx^%yk7Q#rpOvyYYq~CZ*$rdGZlt}P*(vzM>#~B_B}o z9wom*$*)o3AQ|g9U?}+4s7M+I3EA?Jza!yfPP*|(U-Pe^mdF6;HMc_UQIi9*OX}Mt z*&RnlnvslU7^wnubq1)cppO`XLm51enR&CMp9MA}gf^&ON<}9Rm*|ec;XBl0M9GJg z#FXq(@)0FprR4EOccY2637K?*^^1#S zM+m*yw77K0hOyt`($^ZulhNvyJPU21N@6mO%SQ7Fw%*?+vK1@@+YTt)$Myfc$@nAM z*TiP>*b@)b(HPRXOR{*Orf=qTOR`UbSVkuegjk7HOtKb1P5^N$}U zlD|xi|63T)0~*=^jZgG_8s7lnDt-Y)Sq^gtFcVSxG|RvZ0Jk6TuqBSZJ3D>r`6*|9 z$szT-=~f#6@8s!_uw$O^zQ|G~2k}qiomq~Nbez{u;DrGEB!0nP!_^gQHRbaJG{qs^ zz#$wI3j5&zt`6Qmj%CyU$Mhc{mj+PH$b0=v_hUR#U`%{dI7!6&ykZY{k?)Jrfva}SJP&$k&7^<{b8%^3D ziI3Edp@$K?8*KDGu8Jg-V-Hb|cTq}h4*hYz3NiT1LfJIhtAF%i;u|` z$K&HDA7>Yn7RTlIPQ)iL=S%E4)mN;jC*zZ#UdH7RIrpyqPsOJsx6|=yaHFduYUZaU zH#@e`4wpxgk;Ai}$nBZ<4C>=LiK-vwJ~8<>ldoex&nxWJ7SHx-o{i7$9fKq8H9Df< zNP3dJ4hu~j&bI5Ei_f8lH=!*n$vO^ z(p?3*q9DvFFl%&vLPjL*i6kD7oCV311;08X$9DO~ggQ!|eni!lUo|?LR7he9NdThN zu}$vBs8sfCVh%{Is!2ZwZgx;C!I8()x%v6%v^rz@EAahLSh%6EI~?x{w~y)kJ~X*7 z$!Qavf2Xms(eUp!Z1}f*enke-(2ER2*uhp)I^8o9lS{MjPUF@{8tb#xh)z=IT^<84 z{nj;zn?9?qRy}@26ldlZCa0aZFoC)9>|`|BRXw>$pe`6(5&d%uv(x3JiKW@OvU7d* z=Cz3%qA$5n;cPqd<^>i$6Z&gwFj*O#F5$K6RM}BgI)o@8l#)9Oj=HnpY{Rds`fgEn z9->5_en1f>oo^oR_Yx+#=c3UsdC5Hl>8F$DrAc}5Kv;{@OG^khEk=FG&eK7R;xJ-Z zx{lSQg08Cv*tXxNZ5w>37{S@cx!VzC$2TjHrO3&zWNKn*0^U-2S-=hubwU7&&UbEf zRNWG?JEu2wPeNp-Z_m#yEJdU8{Fa>X+irasiOHz8Nfm@}5UuGP@>G>sNsXSGsgj&U zDw;(TQlFCaPIiL2S43uJVS2hU9SzBDyW+iT+-i%E&0n-&|3|l%x-}#Nt!6MU!j5!Xd{QV^xG?ED7kG!er>Btw_3ujK;-3}m4JpN zdWa5X;A{qKBE|i?2!cu7;d4HOhRTa^0QZvzM`Tv~`qn1Gdrj^)l}AXra{fe)kQOP4 zzqb~t^|~|mM3x$;dfdm@^vU+vvDr-z1J%D!@QRjz%j(`Xav!NA&Vm7{b#; zZX&t^h*&DkqNk-)&`jhLr9cI(Jke8_0vB-T$KFg}|C<2rp$)86%HaWGmc+fRkY&R#B26 z6*>}zQblT8$Qu^Q5ak4Sq{#Qvf7i39m*8nrWtKjO z)+HmM=%utQp;F1C^;SZNtcWqUcox8q{wbDPFcts29-Vl^NoSlEpp00+0oNRPa(LTUo?eK4yrlhwIaCEFn z;U`a0^QdJ>ZE~7k#s{8(f9#WhV?b+y{mufT3D^y zqkoRWVL(?AH0&$?S3D2z`4mdFM?&;@PfvO`lHT*3-c!VwuC{uN|1(ij3v<_)?lt3;U81|n&NA1LQ@iAr&4YaFJB z)zLp6q((htp%A_!9VzvYD3CoMNg&0|hl$fsN@!s@dD!?U646hG-0^+BeC4;Molw5) zb5svE6zGm>?+mUbg!9OI96&Hl-$Wp+mPO>hORc^|$+xLh&upVznSY1Ke?ZB1sVpx| zwN$NqkEjobTDa!>^%j5S`hI~5Cn%vWLlmYPTbr#KBE2XttC14re@e-pQJo@P(rT== zYVp6NlE0x6tA%P+_|=+gDQ^l*N*6LGuLA!*C4WIJ((~j2ke{mBY5H{J)^+W3XS1!> zR1o!zK2!^ShQ!dj|1C&9$tKBa!IW}J(rVDZnX)pOeYFje>w^^YAxd^X>+#x45`d;-;E~g3j-FRI5 zNFu>9VA+s4tN>OFg~MVqVI=sNq>Zcck$6}!QntRJj*vey36nynCc_ajx zPX#|?Ds}>8Dx&hKFeL<8Kig0nX*&se(h-DatDi|h?hH1~vH3GtjbjUEuo;dmg1cww zj-0_pbW3Nj5#7-<*obb~AF;E$>Qj+=?7j{IuctjgAyMawXtzO`G7U2hY=(M(Fw&hV#>q*HS`fj>PvKjkMU zgy02mm6#NQ^Zt4N1=KJ4FWRYH1swi)+(VChTxg%?k{X4i%J|w8wfl)9WkC0-xc^(P z=xDv%S2|M`>#BMx%3QX>>14XGnk2IFq07mGMC+7osjt$q!9CSB%YG` zsg{9!;$2npiHkJmK;NdCzDPBF2Xzf6IJoRzJ{-jfzT%bbaeLy4;EnmRe}yFbShOb} zOF_l29FC*MRj*`Ec@u||zCw~Y64CZ5aMLjk6glo1aOYy27URC-zv^Er3jTMBLNM#k z`d3lE=D&70btFKCytb+E`K510@}`=kOf|_C^;2o@AMXqP$l){}QHtx)xGqOEovF%9 z|MFb7+dR-oAJ*I3x>Kt`hw5HO_jVk;)$yQWH66cxW`3@=W_H-N`6#H8hNYi`CxK@a zk2`~6TkwUC%Yo>N4dGDy6tiTCFaD*pr)&s+D^#RV;rdr|J&Sqn!@9QvoHTo#kx?Se zZueTP1Foc57O1bS`5T)bxDInSZEM%9Z-U(g%deG9;#cmHaYIrt{zX6c-9y;I|Y>#+KEy=^sh*d4GmJ3D)~|4O&x zI~S+i2zI z=I<`wTQoNoH#U}6SNcDgYc}M@#-ra0 zuI)IMZBloRcs;o0S@q^I;=6&~uYi#OA-z?1U0T$7TPLB$Yq~Vg=P=y+v>^1j^w7q^ z&M$3Bffz`>=u2hc9?t8YWD7WF;tJo*6`2*#F%J#rnkIYe&xj%| zx+3)XqM6Uxg@ewa{NYDNMczht{Qm1lF+fK#{tX+4xD&meZ9LJdaxRp&x(A^`+bB#$ zo7oMMSVkNQmcs|aM3>duUZ_+%=$Pxdj#;yI9TNb92Ntb+sMN5X!`ybWvt>c@op!Ch z9ctUXx`~DIdTy8@*kR0Ux!dG_bvw)pWt{D>Fjy9|+rfw2Fu~xiIiXbTFp^QIdL7dt z50KGngmS;$4RgR9pQ%s*w>x2qS$5rOyJ5Ob{5R`;CrtLbn443%9xATWtZ_BO$nRt1 z@G)|t!}M^wgz4c{3N^l=_&zfV7RjT>95WJ;k+GW17zvN7}y_R4hBHqNORh|H4q+x`^VtHG1xb9 zCr%dnpL*Rt{d#cv6};3~r-j32q`W!=0YJq^`MMbysO=xeM;tHK{@^7P>xRO4qjI0a z2fPI1m>hH3p1Ega2O!p*8R@q3Fj{>hLpIE@`MMiPT73|S>VvrM8yd%V$jvuWGTFQKo#Ax2J(iA*vA@YLG#hM%1GD89%!%BT`BDX+Kw!xxTAtVIg)Z%ze{^>2!_} z2WJue2*HTouy{HgGxwjt96W>RhZ^ZfQYTOx;~cJU)IHGt__D#DRDhIsmQ#qW@AZ$bzt4&>~?4yj-MbhP_g?%4$Vc(+(X^vg@qV0c1 z>4&4+4(SBMrCr!3hk13!{RPHwXG)+Ir(GuI&(xa8*3b(MQ#xXLjjGbF1gwGbR6N*3$Vyv4J`#P|mTn53a+vUvjTD@@G^MiB=C0jXX1Ooj|b>|!Jn@K>S`{Yav){&+6;h4$Yof;YOWAt?TZh>%_s`jbNr zM(~|%^c@;wqy4AZ4~36}_D?aY%t!raJnEV^));S0fX=Un<4ZIi_{qb3^mXF+45c?f zNo!1j7Q$H(4hUpH^CSt3g8Spqe7^X$^dV$O*_D;P^eBjIy0W~owA#PAxbHFAUT}rT zccpErcP;YGkbHqNhl5299K735WNZpsu75$tPUNOgCr6*VQh2ZKP{#{DM9Cf8z6@WD zP0)xroB+6pYxuxB_`upR{YAz)>_+rOv*E&NUN4RwjA9hr18Mof*B1zZf{@LmVU-B@uyvhM~9(~x0)KRUwCdme)dEdgVjn$O} zr`oX{-nEirZ&K&?sUXicR69M-B)`>2lPqX&!E&Ug?X&OzE=p_32%eUxK115oI{ry44GG?aoSrGHAf{}YsJnycx*iq-TupV27Ky**#G|C|&uAM>w6)sED7BL~&~ zFVSeogK|?@FVo1wfWa(BM(T`eUjU_4qsUde9@Dxwq%i(FP=KoE(dfj=64&+QATZjR zciBw>e@Mk!RQ!mFx2c$;VjV^Q0+idj(`{N+N9V5m4V`;cH-N{nM%6C@TyY*o&5r_L zF3>A!Asq=A$0qG`Y(lttV|VEbktSvz5PXk{`&4iPaW7IEbbuFdoOOQQiOv}%%JWm6 zgSxM|3l{TH;{QoDUU>2wtQC0k|v9^GuP9kYMDjF zPpH_WVv7o!3WtiJT4XhPC3VL>p<)NcKoc$zqD2L@8wC=IY1er^%3=pR$ThNccb%f? zMT$)gjrXw_vk>yvA<7f&Zrx*b5DJsftKFW*xM?UY{c-%Ko zID#SCf+5+W0l(HzY#Db|xM6UUC^Ja#JRbKJ3aEVC z)uz6sSzz%SMux##Rz5p|S>RycDW) z>v!hvez3lH7q@6i3+6V=#bFYhCU6`o-a*%)D>RxuQjXlPhDqv#+c{jlRh!7JgIC={*8OJ1r$k;&?bi;^>{mJJn+AIwm3W!b# zSx7FRFCZ!s5Q(HALQFEd3f(E$611-j-O1f~+}tQTxN7v2Mgp;~%QU5_sLQBv!{Sf)ll~O%1&<_{M#~sl&Y>Ph zJu{Tf1f)~&&-pV)+|!8H2NIy%hChRr>1b83=97n0_T-@qNl!zXV(@}@4y%bN8w~x67RFG^Box=niDQ_s93)gY9Yeg}whlFo-=6@30y2IO0*X<6fZmXs_AlX~$Jw zTw#4|*2v^t9wy?WLq^uFPMLjAADl;>AG`GY+{*mo?c0kB+=BA!g6IYz^}JLjPe(+F zi67u&{fon3jpCf=ULGt(#{WDxm`75Rr^Q>8oz-i-Hb3LYk>4=Vt@^&zqFm!rplFdZ6n!`pRpsA=Z)EX-gN!p(HU* z99JXo3A_V6POu!r@n3&z`Oezv`dxEj?(UpP;^p1?`4!xsa7`Q~g4CtumF12178fcr zIBVcMpn_XzZm+p9{zKr9lZu8>xWUI7r3ZDljz|uv>lo#-pVIK3Q9(hMQ9Q}T((So- zBTG)%9iGl(9}@HtbRC{S?6^)sJ_8?no?;$&!env1Q{@Hk~gy4W>T2t0xk^%kyFUO*7O?6UG&{ z7=W`T<*=I+Gvh5~ns%oOAidQz>o$+1Re()v%V~xhpiY-eE$&dNP0MwWoZ0Ev>@i7* zE|O08Xk0?%sIdnqkRB3TLXkbCKc-paEjUwX6ON0@8235DG)(+X4>^68U%l`PmuRoO zPW{PO4NK&Q&z`#Ji5y>nXCJ}@DK13fb6k0Zvg@&Eqtlj$zY(X8c%;ksYpAXwF-oo# mXYP6P3DujC^xh)A`DL8S*DgydM5`yy{7e{AM@zr2zVUwu2L3Jp delta 1387 zcmZvb&u<$=6vuaV*WUH6*KV8GaeiVeNyC~P%B3nLM3_XN5Mmb+D7Xf*$xIwO_S&7@ zNO8JLfJ6u`Kr{y~l}IEcdT4tf7k)_e!U1tYJs@>Y2ysFD0~B#!-Xm_(%_KdXT5$u z=L!1;POTxF-j}?rmpc#-M8s72t?k?1c;hTq`UP2#gmv*_iQe|kpHfn%l=La3@05}` zQoyV8t1a>Z4Ogq`xQ{0>di0G&B1zQ8QjvxE4DR0*+>|GIkM4-G!Vba%JECuT=6?D> z@bm6DJm~iAXFM6QJwW{1V_X|L)?&xnB-e)7oya1(&roy%jW9F%K|aEd+(dzfH(IT3 z)wWuMLL2_XGnXqbJA^uwS!>;?yK5GE5UrvNdqVk0{0$xcpsb?D19`6aY-!6ZbUMv$ z-L7TbcGhY(v+Jb0O1Ud1yGq-w>K2RV|b$vBZAP{WS_0=l1>>3I5 zR^6UIPAFiv;_r=z2_TvPHxMu|mfJR|T6VoLj{KJ?- zMp@ph;!aua0$DMc&VXXspa8cxsmeW+nU@?HgHR`x1wA$5R>NQ&+U^kQ)`{~e`!+d_ zN{0^y?xD#*YA-i}7^G6gmTS?l>i>9=JMCukOM!hi^mJ0^0btGW<)jho8J<_}x>`eb z?lLl5Id3n+ANtp3*^_65*Qb2V(;9I<>KdN5gDR4*_^Kac?+lOSuYY}2uzUH15V6QF zgvKv|faNuQg|H4Z<3+jz^`zN1k6g<2!1f#fahS?cs{d|KZ}uX)oEscU(pSLjDj*NY z0Y(7V*!5g~`&HP!2AJR|>vIcNN-r%{XA4V(KwY*R63%4_3~ny!WR59cB$hrP{<}(*>K7C+{U@U&W`31DvBbFuLNgS zV(*T=U3vrDtN>2h67FD>=oOAH_;O&1)Np=eq>Aw~;TJyka9AfWlkCN@F}5`}Kq79p zL!2O5SaIuZJCGcghSgH2J5Wn}TwppwKmQjxP^VgLywN1n5W<1Zs8Srk!{bXs+d{9} F^Ea7NP&@zt diff --git a/CAfP/__pycache__/file_op.cpython-37.pyc b/CAfP/__pycache__/file_op.cpython-37.pyc index 6cc43c10504a4162bfc368fe90aa12a0cb03ac47..f3a4dbab48d48606ce1a14a596b46a0d6a49b7e4 100644 GIT binary patch delta 1652 zcmaJ?O>7%Q6yDiCuh+Zl*fDWR;+Cd@%Fqy+G(`=O()^J0Cn14`q_UE_8_(LDtvK(9k@LN5ejS-d9Xt=ASqzHbid6-XD_-qA@Iyv4qKRODPtw>J%qihSY~-ho!~5!9R+hXt8PV!1@3}vr>20?0T`}Hpo7n+Is~abr+j#>eY?+juW=73os+ znkUU}@va?gnyqB zhG9O2;$``EDmN2{Cp2{FeGh=QIJ(QEDOH809EdeBkSQ4zZkGcIF3*jo0=nu;ff^`n zaYbyZ%^3eBwVZw6!{w>zRBekNb~QCWQ8VDWYJ4VrhBUaJ?tl6>{D8o^adDvtMN_K{ z>NI@Vfv?lYvvc^?Jjg0K7Yz{D7~e||zYsqx=wWW5=5F~#YWp@D!J!urUg1|ebG^8c zUx0bf00=S`QkHZ$@Um#}oz5C5@<*LLP_#tmB>9&2XHK86VIW&WC?QaUGJ=Cp;a=u! z$2!u(O1%?Rst)4&{HIKg)OR0chRE^5GCX1Pf94mvZjm|uplje%R4P2ltc~!W(U?QX z_3Zil|1a&xqHsOOS}^YiFc1G4G{{&6Gh(d8KgmuiYynjMF#BR(bhksr-`<1|j5fdN cFuXg_VPlvROh}qpey#htn65qBbuKgh7w3;^ga7~l delta 1784 zcmaJ?U2GIp6rMZ(J3G7WZp$tO`U4oqBG>>emD*_f6A^>75wK=#-A;F=?JWD(J5#zf zvqDlHOiZxNeLxc*sPS1N_0jm?gK2zGUdIQFFUpHNnW*8xbM9^hiE*3zo$sEXJ7?}W zXZooB#>wPZB4G&d`}t8~uH3hoyfJo8a7-t0Q*aWlP)ruvTw`6f+MT4+c2lrYU~P9& zU`;ix>yniQUE1jYT}M;*#SdL1JvTl)bH#V5KQm!p^}S%p-u{E6L8%q7dP=wt^Lk-oU+R#F|p@;e% z%~7@peGi!KsE)QJHex|6jI9$#zbb-0=4f34cxo-ryTEom4e&Hto_9lodupK;>cbE^ zRevT_oLHC8N~06fh&Rl@2-Pqin(Gn~mUpIweR2VhT!SjOzRZfRaQU$M)s6$f(7F6E1UwPM8zE0ppl zSXz@-ECn3qE0)gB%zI_aXfm{0Iv8uTTJx<~jn?p>6_;X}nvmofxOKO%61W#&;~xhQ z#A7Bgi7KkZly#C84WbfRHb7?*9d=xTB}4XV%rn0_Fa$w4LSF#!#KE#d?bS6lnz%rQ z*sa9TW88ibohA`p+jZX!#dPQ>z$&|+IHkUV+w&}&d_O*n^c**{hnc-fKhQz;U2^~R zXDRXm76pHJ*Agt=f*U|WQWQeLAtT5LFmXf(MBtJmt&0tjbD49AbA@v`6v0=9C<&wj zQUSk(*^H# z>$NHkcpv5YVQv7koe!$7LX*7Oxx~3hJ@6=OruJ-;wvWl! zDcD_pIVaK6K4G zuo{XdG}J(XD^;LwDzj44*)L)4g`(l8>*5EQh8Dz&Ce%q|JE`NO#C}hm*hgQ2(;zK; zb|fy;BGs!nZY6-e8cFwLN6?yRCXM;h5`xE;(}PF!)pVTA0x)S6a8-{ra4U6nv zy88fj=I5~dJ^(>hVRmH6fJu=>gBcyg?kP}5$px?E`fkZB1bN$WAgk8IZ+09c_t@>HJ92!mGa@{tw!+;A@pG;%f8PZ M(ag+weShcZ-?A*9Gynhq diff --git a/CAfP/__pycache__/global_config.cpython-37.pyc b/CAfP/__pycache__/global_config.cpython-37.pyc index 4838a1fc4a140987d387b529a48691f7665de7fb..10ce50d23d75f4e06e994149537535164c2d808e 100644 GIT binary patch delta 264 zcmbQw^qq;7|+R#U+U)rNy_nLG09`qWIk6^jiX+z5)J0A@MGbA&v?0Za$9gw|J0* z;%|vK`TM!X2RH^f`nra=1_j4^1p}>>L>G1Q^l^>%1FBicP{axJ2AKGj>}(YiS`2hZ UOiE&QapuI0DSRLwvoOLS06<1ei2wiq delta 154 zcmey)G@psriIdgBdhgZt*!f zhj@m$#s|9w2YdSa-C}U_(`1=gFXhPX=^Nl56cX>^7~*(K#L3^!H9o*G$kEp|#5E{5 w-YeMOZzV$!JJ4V-@hi>QDkiizwWv78B{91=vm_&NGAm;W7aLFk3nK^u08Kb10{{R3 diff --git a/CAfP/__pycache__/time_warping.cpython-37.pyc b/CAfP/__pycache__/time_warping.cpython-37.pyc index 3d876c0b8b65a86260f002a58c48939115e6b5c2..5f34743d93052d1dfb75f99542ad803aef3bfe77 100644 GIT binary patch delta 134 zcmdlYxlxkGiIej!8+(F3#NS#I&7-@z&&DY#$gc zCL8idY-Z-z%?xDj=XROQ!K2LW0MuM00wTcDN{&Eg5D*vh00|C87BJ*s=HV&=$!M|` TxlPXIkz#ZNnk7DYE{`|>1R5RS delta 157 zcmdlexkZx4iITDGgTAW%`9OIIhU7T5xk+|8OX*&yJ)a37M z9~jLi>+wiz;@Hg$WbNU0VX**eo&29$g-ry=C<4pcIslnLKwQiNBsdsZz>tHPhpPxA pqsdz23Z!namQ)s`7T@CVFGwv)EXgk_Vgia5IRMQUpFE348~~h4CUpP+ diff --git a/CAfP/bone_motion.py b/CAfP/bone_motion.py index fe9cad9..48914d1 100644 --- a/CAfP/bone_motion.py +++ b/CAfP/bone_motion.py @@ -5,8 +5,10 @@ from mathutils import Euler from mathutils import Vector import math +import json import CAfP.global_config as global_config +from . import file_op def bone_animator(self, act: bpy.types.Action, bone_name: str, damp_weights: Vector, angular_offset: Vector, tail_crop=0, head_crop=0, crop_start=0) -> None: @@ -96,9 +98,10 @@ def bone_animator(self, act: bpy.types.Action, bone_name: str, damp_weights: Vec else: self.report({'WARNING'}, "Unexpected keyframe crop. n_keyframes {0}, crop (start_kf:{1},head_crop_kf:{2},tail_crop_kf:{3} "\ .format(n_keyframes_w,crop_start,head_crop,tail_crop)) - minKeyframe = 0 - maxKeyframe = n_keyframes_w - self.report({'INFO'}, "Applying to all keyframes from {} till {}".format(minKeyframe,maxKeyframe) ) + # minKeyframe = 0 + # maxKeyframe = n_keyframes_w + # self.report({'INFO'}, "Applying to all keyframes from {} till {}".format(minKeyframe,maxKeyframe) ) + return for i in range(minKeyframe,maxKeyframe): @@ -175,6 +178,111 @@ def get_bone_properties(bone): edit_range = [s_crop,head_crop,tail_crop] return damping_weights,angular_offset,edit_range +def getAllPoseBoneParameters(self, activeArm:bpy.types.Armature, path): + out_data = {} + poseBones = activeArm.pose.bones + try: + #get parameters that are saved + + out_data["name"] = "{}".format(activeArm.name) + + if file_op.isInCurrDirectory(global_config.BONE_PARAMETERS_FILE_NAME): + self.report({"INFO"},"Extracting posebone parameters from {} ...".format(global_config.BONE_PARAMETERS_FILE_NAME)) + with open(path, 'r') as j_file: + + j_database = json.loads(j_file.read()) + + if "name" in j_database: + if j_database["name"] != activeArm.name: + self.report({"WARNING"}, " Armature name missmatch {} != {}".format(activeArm.name,j_database["name"])) + + out_data = j_database + else: + count = 0 + for bone in poseBones: # type: bpy.types.PoseBone + param_json = {} + #range + param_json,isDefaultValue = file_op.get_bone_parameters_forJson(param_json, bone) + if not isDefaultValue: + if param_json is not None: + out_data['{0}'.format(bone.basename)] = [] + out_data['{0}'.format(bone.basename)].append(param_json) + count+=count + else: + self.report({"ERROR"}, "getAllPoseBoneParameters Error: param_json {},isDefaultValue {} ".format(param_json,isDefaultValue)) + + self.report({"INFO"}, "There are {} number of bones with non default values".format(count)) + + + with open(path, 'w') as out_file: + json.dump(obj=out_data, fp=out_file, indent=2) + print('Creating {0} at {1} ..'.format(global_config.BONE_PARAMETERS_FILE_NAME, file_op.simple_path(path))) + + except OSError as err: + self.report({"ERROR"}, "getAllPoseBoneParameters Error: {} ".format(err)) + #print('Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) + + except IOError as err: + if bpy.data.is_saved: + self.report({"ERROR"}, "getAllPoseBoneParameters Error: {},while creating {}. Maybe save the blend file".format(err,bpy.path.basename(path))) + except json.JSONDecodeError: + self.report({"ERROR"}, "getAllPoseBoneParameters Error: in json file: {}".format(bpy.path.basename(path))) + + return out_data + + +def appendBoneData(self, active_bone,param_json, path): + try: + bone_dictionary = global_config.BONE_PARAMETERS_JSON + bone_name = active_bone.name + isRangeExist = False + #param_json = {} + #param_json,isDefaultValue = file_op.get_bone_parameters_forJson(param_json,active_bone) + + if bone_name in bone_dictionary: + bone_array = bone_dictionary["{}".format(bone_name)] #Json Array + + for item in bone_array: + if item["anim_ignore_from_start"] == param_json["anim_ignore_from_start"] and item["anim_ignore_from_end"] \ + == param_json["anim_ignore_from_end"]: + isRangeExsit = True + item["damping_x_scale"] = param_json["damping_x_scale"] + item["damping_y_scale"] = param_json["damping_y_scale"] + item["damping_z_scale"] = param_json["damping_z_scale"] + + item["angular_offset_x"] = param_json["angular_offset_x"] + item["angular_offset_y"] = param_json["angular_offset_y"] + item["angular_offset_z"] = param_json["angular_offset_z"] + + self.report({'INFO'},"{} Replace range: start:{} end:{}".\ + format(bone_name,item["anim_ignore_from_start"],item["anim_ignore_from_end"] )) + break + + + if not isRangeExist: + bone_array.append(param_json) + self.report({'INFO'},"{} new range start:{} end:{}".format(bone_name,param_json["anim_ignore_from_start"],param_json["anim_ignore_from_end"] )) + else: + bone_dictionary["{}".format(bone_name)] = [] + bone_dictionary["{}".format(bone_name)].append(param_json) + self.report({'INFO'},"New bone added: {} parameter file".format(bone_name)) + + global_config.BONE_PARAMETERS_JSON = bone_dictionary + out_data = bone_dictionary + with open(path, 'w') as output: + json.dump(obj=out_data, fp=output, indent=2) + + except OSError as err: + self.report('ERROR','appendBoneData Error {} while creating CAfP_temp_bone.json. Please save the blend file'.format(err)) + except IOError as err: + if bpy.data.is_saved: + self.report({'ERROR'},"appendBoneData Error {},while creating {}. Please save the blend file".format(err,bpy.path.basename(path))) + except json.JSONDecodeError as err: + self.report({'ERROR'},"appendBoneData Error {}in json file: {}".format(err, bpy.path.basename(path))) + + + + class BoneAnimatorOffDamp(bpy.types.Operator): """Rotational translate animation curves""" bl_idname = "cafp.boneanimator" @@ -200,9 +308,9 @@ def poll(cls, context): def execute(self, context): # Active Armature - obj = context.active_object # type: bpy.types.Object - if obj.type != 'ARMATURE': - self.report({'ERROR'},"Selected object {} is not ARMATURE type".format(obj)) + activeArmature = context.active_object # type: bpy.types.Object + if activeArmature.type != 'ARMATURE': + self.report({'ERROR'},"Selected object {} is not ARMATURE type".format(activeArmature)) return {'CANCELLED'} #active item @@ -213,9 +321,9 @@ def execute(self, context): #animation - action = obj.animation_data.action + action = activeArmature.animation_data.action - if active_bone is not None and not global_config.IMPORT_DATA: + if active_bone is not None and not global_config.IMPORT_DATA_FLAG: bone_name = active_bone.basename damping_weights,angular_offset,edit_range = get_bone_properties(active_bone) @@ -224,14 +332,68 @@ def execute(self, context): angular_offset= angular_offset,tail_crop=edit_range[2], head_crop=edit_range[1], crop_start=edit_range[0]) else: - self.report({'ERROR'},"Armature {0} has no animation data".format(obj)) + self.report({'ERROR'},"Armature {0} has no animation data".format(activeArmature)) return {'CANCELLED'} - elif global_config.IMPORT_DATA: - for bone_ in load_data_bones: - bone_name = bone_.basename - damping_weights,angular_offset,edit_range = get_bone_properties(bone_) - bone_animator(self, act=action,bone_name= bone_name,damp_weights= damping_weights,\ - angular_offset= angular_offset,tail_crop=edit_range[2], head_crop=edit_range[1], crop_start=edit_range[0]) + + elif global_config.IMPORT_DATA_FLAG: + global_config.IMPORT_DATA_FLAG=False + activeBones = activeArmature.pose.bones + impBones = global_config.IMPORT_DATA_ + + if impBones is not None: + self.report({'INFO'},"{} Calling import function on:".format(activeArmature.name)) + for imKey, imVal in impBones.items(): + for currBone in activeBones: + + curr_bn = currBone.basename + im_bn = imKey + #This manual operation is needed because Mixamo rig starts with strings which are + #different from one another. for example mixamorigxx:spine where xx is a number + if im_bn.startswith('mixamorig'): + split_im = im_bn.split(":",1) + if len(split_im)==2: + im_bn = split_im[1] + + if curr_bn.startswith('mixamorig'): + split_curr = curr_bn.split(":",1) + if len(split_curr) ==2: + curr_bn = split_curr[1] + + if curr_bn == im_bn: + for item in imVal: #consit of json object for each range + #setattr(currBone,im_props,prp_value) + if item is not None: + + x_dp = item["damping_x_scale"] + y_dp = item["damping_y_scale"] + z_dp = item["damping_z_scale"] + damping_weights = Vector((x_dp,y_dp,z_dp)) + + x_an = item["angular_offset_x"] + y_an = item["angular_offset_y"] + z_an = item["angular_offset_z"] + angular_offset = Vector((x_an,y_an,z_an)) + + s_crop = 0 + head_crop = item["anim_ignore_from_start"] + tail_crop = item["anim_ignore_from_end"] + self.report({'INFO'},"Importing {0} bone for range: head_crop:{1} tail_crop:{2} :".format(curr_bn,head_crop,tail_crop)) + #change the bone + bone_animator(self, act=action,bone_name= currBone.basename,damp_weights= damping_weights,\ + angular_offset= angular_offset,tail_crop=tail_crop, head_crop=head_crop, crop_start=s_crop) + #append the value to the file + path =bpy.path.abspath("//{}".format(global_config.BONE_PARAMETERS_FILE_NAME)) + appendBoneData(self,active_bone= currBone, param_json= item, path=path) + else: + self.report({'WARNING'},"{} imported empty property values".format(curr_bn)) + + else: + self.report({'ERROR'},"IMPORT_DATA_ is empty") + + + + + else: self.report({'ERROR'},"No active_bone") diff --git a/CAfP/file_op.py b/CAfP/file_op.py index 550d56f..8601976 100644 --- a/CAfP/file_op.py +++ b/CAfP/file_op.py @@ -48,6 +48,41 @@ def isInCurrDirectory(file_name): return True return False +def get_bone_parameters_forJson(param_json, bone): + + isDefaultValue = True + #param_json['anim_start'] = bone.anim_start + param_json["anim_ignore_from_start"] = bone.anim_ignore_from_start + param_json["anim_ignore_from_end"] = bone.anim_ignore_from_end + + x_scale = round(bone.damping_x_scale,3) + y_scale = round(bone.damping_y_scale,3) + z_scale = round(bone.damping_z_scale,3) + + scales = [x_scale,y_scale,z_scale] + for s in scales: + if s != 1.0: + isDefaultValue = False + + param_json["damping_x_scale"] = x_scale + param_json["damping_y_scale"] = y_scale + param_json["damping_z_scale"] = z_scale + + x_offset = round(bone.angular_offset_x,3) + y_offset =round( bone.angular_offset_y,3) + z_offset = round(bone.angular_offset_z,3) + + offsets = [x_offset,y_offset,z_offset] + for f in offsets: + if f != 0: + isDefaultValue = False + + param_json["angular_offset_x"] = x_offset + param_json["angular_offset_y"] = y_offset + param_json["angular_offset_z"] = z_offset + + return param_json,isDefaultValue + class LoadPoseBone(bpy.types.Operator, ImportHelper): @@ -79,40 +114,17 @@ def execute(self, context): self.ShowMessageBox(message = "May not a valid file !") return {'FINISHED'} #-------------------- - scene_poseB = context.visible_pose_bones + #scene_poseB = context.visible_pose_bones + scene_poseB = context.selected_pose_bones_from_active_object im_poseBones = load_json_data(self, self.filepath) - #Setting the IMPORT_DATA flag - #global_config.IMPORT_DATA = True + #Setting the IMPORT_DATA flag if im_poseBones is not None: - for im_name, im_val_json in im_poseBones.items(): - #print("key {0} value{1}".format(im_name,im_val_json)) - for curr_bone in scene_poseB: - curr_bn = curr_bone.basename - im_bn = im_name - - - #BUG: mixamorig start with a different character - if im_bn.startswith('mixamorig'): - split_im = im_bn.split(":",1) - if len(split_im)==2: - im_bn = split_im[1] - #im_rg_name = split_im[0] - if curr_bn.startswith('mixamorig'): - split_curr = curr_bn.split(":",1) - if len(split_curr) ==2: - curr_bn = split_curr[1] - #curr_rg_name = split_curr[0] - - - if curr_bn == im_bn: - for im_props, prp_value in im_val_json[0].items(): - setattr(curr_bone,im_props,prp_value) - - #print("Set {0}: {1} = {2}".format(curr_bone.basename,im_props,prp_value)) - #run the oporator to update the changes - #bpy.ops.cafp.boneanimator() - #global_config.IMPORT_DATA=False + global_config.IMPORT_DATA_FLAG = True + global_config.IMPORT_DATA_ = im_poseBones + #run the oporator to update the changes + bpy.ops.cafp.boneanimator() + return {'FINISHED'} @@ -123,33 +135,8 @@ def draw(self, context): bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) #################### Export function ################## -def get_bone_parameters_forJson(param_json, bone): - - #param_json['anim_start'] = bone.anim_start - param_json['anim_ignore_from_start'] = bone.anim_ignore_from_start - param_json['anim_ignore_from_end'] = bone.anim_ignore_from_end - - x_scale = round(bone.damping_x_scale,3) - y_scale = round(bone.damping_y_scale,3) - z_scale = round(bone.damping_z_scale,3) - - param_json['damping_x_scale'] = x_scale - param_json['damping_y_scale'] = y_scale - param_json['damping_z_scale'] = z_scale - - - x_offset = round(bone.angular_offset_x,3) - y_offset =round( bone.angular_offset_y,3) - z_offset = round(bone.angular_offset_z,3) - - - param_json['angular_offset_x'] = x_offset - param_json['angular_offset_y'] = y_offset - param_json['angular_offset_z'] = z_offset - - return param_json - +#not really needed this since we save parameters anyways class ExportPoseBone(bpy.types.Operator): "Export all posebone angular offset and amplitude parameter to a json file" @@ -187,7 +174,7 @@ def execute(self, context): for bone in poseBones: # type: bpy.types.PoseBone param_json = {} #range - param_json = get_bone_parameters_forJson(param_json, bone) + param_json,isDefaultValue = get_bone_parameters_forJson(param_json, bone) if len(param_json) != 0: self.report({'INFO'},"Exporting Posebone {0}".format(bone.basename)) diff --git a/CAfP/global_config.py b/CAfP/global_config.py index e3800aa..68b4303 100644 --- a/CAfP/global_config.py +++ b/CAfP/global_config.py @@ -1,5 +1,6 @@ gui_status = "ACTIVE_SESSION" gui_err_msg = "" -IMPORT_DATA= False +IMPORT_DATA_FLAG= False +IMPORT_DATA_ = {} BONE_PARAMETERS_JSON = {} - +BONE_PARAMETERS_FILE_NAME = "CAfP_AllPoseBoneParameters.json" From 936c46c02b6cb62edd36ad1ef4702e056ad75d75 Mon Sep 17 00:00:00 2001 From: Daksitha Date: Wed, 4 Aug 2021 10:50:12 +0200 Subject: [PATCH 4/5] adding gitignore I am removing video files in the git repo using gitignore --- .gitignore | 1 + CAfP/CAfP_AllPoseBoneParameters.json | 5 - CAfP_AllPoseBoneParameters.json | 440 --------------------------- 3 files changed, 1 insertion(+), 445 deletions(-) create mode 100644 .gitignore delete mode 100644 CAfP/CAfP_AllPoseBoneParameters.json delete mode 100644 CAfP_AllPoseBoneParameters.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a31eef3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +\Videos \ No newline at end of file diff --git a/CAfP/CAfP_AllPoseBoneParameters.json b/CAfP/CAfP_AllPoseBoneParameters.json deleted file mode 100644 index 3ca4395..0000000 --- a/CAfP/CAfP_AllPoseBoneParameters.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "mixamorig12:RightForeArm": [ - {} - ] -} \ No newline at end of file diff --git a/CAfP_AllPoseBoneParameters.json b/CAfP_AllPoseBoneParameters.json deleted file mode 100644 index e4dc9fc..0000000 --- a/CAfP_AllPoseBoneParameters.json +++ /dev/null @@ -1,440 +0,0 @@ -{ - "mixamorig:Hips": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:Spine": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:Spine1": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:Spine2": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:Neck": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:Head": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftShoulder": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftArm": [ - { - "anim_ignore_from_start": 20, - "anim_ignore_from_end": 80, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftForeArm": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftHand": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftHandThumb1": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftHandThumb2": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftHandThumb3": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftHandIndex1": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftHandIndex2": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftHandIndex3": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightShoulder": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightArm": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - }, - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 0.0, - "damping_y_scale": 0.5, - "damping_z_scale": 0.0, - "angular_offset_x": 70, - "angular_offset_y": -5, - "angular_offset_z": -20 - }, - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 20, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": -5, - "angular_offset_z": 0 - }, - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 123, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": -5, - "angular_offset_z": 0 - } - ], - "mixamorig:RightForeArm": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightHand": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightHandThumb1": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightHandThumb2": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightHandThumb3": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightHandIndex1": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightHandIndex2": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightHandIndex3": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftUpLeg": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftLeg": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftFoot": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:LeftToeBase": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightUpLeg": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightLeg": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightFoot": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ], - "mixamorig:RightToeBase": [ - { - "anim_ignore_from_start": 0, - "anim_ignore_from_end": 0, - "damping_x_scale": 1.0, - "damping_y_scale": 1.0, - "damping_z_scale": 1.0, - "angular_offset_x": 0, - "angular_offset_y": 0, - "angular_offset_z": 0 - } - ] -} \ No newline at end of file From d9226490ef295199338331544a81e7ccda74a58b Mon Sep 17 00:00:00 2001 From: Daksitha Date: Wed, 4 Aug 2021 10:52:51 +0200 Subject: [PATCH 5/5] Updating gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a31eef3..a9c3433 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -\Videos \ No newline at end of file +Videos/ \ No newline at end of file