black format
This commit is contained in:
@@ -1,20 +1,16 @@
|
||||
|
||||
|
||||
from . import material
|
||||
from . import picker
|
||||
from . import shape
|
||||
|
||||
|
||||
modules = (
|
||||
material,
|
||||
picker,
|
||||
shape
|
||||
)
|
||||
modules = (material, picker, shape)
|
||||
|
||||
|
||||
def register():
|
||||
for mod in modules:
|
||||
mod.register()
|
||||
|
||||
|
||||
def unregister():
|
||||
for mod in reversed(modules):
|
||||
mod.unregister()
|
||||
mod.unregister()
|
||||
|
||||
+37
-38
@@ -1,4 +1,3 @@
|
||||
|
||||
import bpy
|
||||
from bpy_extras import view3d_utils
|
||||
|
||||
@@ -6,56 +5,55 @@ from bpy_extras import view3d_utils
|
||||
class RP_OT_add_material(bpy.types.Operator):
|
||||
bl_label = "Add Ui Material"
|
||||
bl_idname = "rigpicker.add_mat"
|
||||
#bl_options = {'REGISTER', 'UNDO'}
|
||||
# bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self,context):
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
|
||||
mat = bpy.data.materials.new('UI')
|
||||
mat = bpy.data.materials.new("UI")
|
||||
mat.use_nodes = True
|
||||
|
||||
for node in mat.node_tree.nodes:
|
||||
if node.type == 'OUTPUT_MATERIAL':
|
||||
if node.type == "OUTPUT_MATERIAL":
|
||||
mat_output = node
|
||||
else:
|
||||
mat.node_tree.nodes.remove(node)
|
||||
|
||||
emission = mat.node_tree.nodes.new('ShaderNodeEmission')
|
||||
mat.node_tree.links.new(emission.outputs[0],mat_output.inputs[0])
|
||||
|
||||
emission = mat.node_tree.nodes.new("ShaderNodeEmission")
|
||||
mat.node_tree.links.new(emission.outputs[0], mat_output.inputs[0])
|
||||
|
||||
if not context.object.data.materials:
|
||||
context.object.data.materials.append(mat)
|
||||
else:
|
||||
context.object.material_slots[0].material = mat
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_remove_material(bpy.types.Operator):
|
||||
bl_label = "Remove Ui Material"
|
||||
bl_idname = "rigpicker.remove_mat"
|
||||
#bl_options = {'REGISTER', 'UNDO'}
|
||||
# bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self,context):
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
#print(self.shape_type)
|
||||
# print(self.shape_type)
|
||||
for mat in context.object.data.materials:
|
||||
bpy.data.materials.remove(mat)
|
||||
context.area.tag_redraw()
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_eyedropper_material(bpy.types.Operator):
|
||||
"""Tooltip"""
|
||||
|
||||
bl_idname = "rigpicker.eyedropper_mat"
|
||||
bl_label = "Eye Dropper mat"
|
||||
#bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
#first_mouse_x = IntProperty()
|
||||
#first_value = FloatProperty()
|
||||
# bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
# first_mouse_x = IntProperty()
|
||||
# first_value = FloatProperty()
|
||||
|
||||
def modal(self, context, event):
|
||||
context.area.tag_redraw()
|
||||
@@ -66,7 +64,7 @@ class RP_OT_eyedropper_material(bpy.types.Operator):
|
||||
region = context.region
|
||||
rv3d = context.region_data
|
||||
|
||||
if event.type == 'LEFTMOUSE' and event.value == 'RELEASE':
|
||||
if event.type == "LEFTMOUSE" and event.value == "RELEASE":
|
||||
self.mouse = event.mouse_region_x, event.mouse_region_y
|
||||
|
||||
dg = context.evaluated_depsgraph_get()
|
||||
@@ -76,47 +74,48 @@ class RP_OT_eyedropper_material(bpy.types.Operator):
|
||||
|
||||
raycast = scene.ray_cast(dg, ray_origin, view_vector)
|
||||
|
||||
if raycast[0]==True:
|
||||
if raycast[0] == True:
|
||||
ob = raycast[4]
|
||||
|
||||
if ob.data.materials:
|
||||
mat = ob.data.materials[0]
|
||||
for shape in [o for o in context.selected_objects if o.type in ('MESH','CURVE','FONT')]:
|
||||
for shape in [
|
||||
o
|
||||
for o in context.selected_objects
|
||||
if o.type in ("MESH", "CURVE", "FONT")
|
||||
]:
|
||||
if not shape.data.materials:
|
||||
shape.data.materials.append(mat)
|
||||
else:
|
||||
shape.material_slots[0].material = mat
|
||||
|
||||
|
||||
#context.space_data.draw_handler_remove(self._handle, 'WINDOW')
|
||||
# context.space_data.draw_handler_remove(self._handle, 'WINDOW')
|
||||
|
||||
context.window.cursor_modal_restore()
|
||||
|
||||
for ob in self.temp_ob:
|
||||
bpy.data.objects.remove(ob)
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
# return {'FINISHED'}
|
||||
|
||||
#return {'FINISHED'}
|
||||
|
||||
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||
#context.object.location.x = self.first_value
|
||||
elif event.type in {"RIGHTMOUSE", "ESC"}:
|
||||
# context.object.location.x = self.first_value
|
||||
context.window.cursor_modal_restore()
|
||||
|
||||
for ob in self.temp_ob:
|
||||
bpy.data.objects.remove(ob)
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
return {"CANCELLED"}
|
||||
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
scene = context.scene
|
||||
#self.local_cursor = tuple(context.space_data.cursor.location)
|
||||
#self.cursor = tuple(context.scene.cursor.location)
|
||||
# self.local_cursor = tuple(context.space_data.cursor.location)
|
||||
# self.cursor = tuple(context.scene.cursor.location)
|
||||
|
||||
curves =[o for o in context.visible_objects if o.type in ('CURVE', 'FONT')]
|
||||
curves = [o for o in context.visible_objects if o.type in ("CURVE", "FONT")]
|
||||
|
||||
self.temp_ob = []
|
||||
|
||||
@@ -124,17 +123,17 @@ class RP_OT_eyedropper_material(bpy.types.Operator):
|
||||
|
||||
for c in curves:
|
||||
mesh = bpy.data.meshes.new_from_object(c.evaluated_get(dg))
|
||||
copy = bpy.data.objects.new(c.name+'_tmp', mesh)
|
||||
copy = bpy.data.objects.new(c.name + "_tmp", mesh)
|
||||
copy.matrix_world = c.matrix_world
|
||||
for mat in c.data.materials:
|
||||
copy.data.materials.append(mat)
|
||||
scene.collection.objects.link(copy)
|
||||
self.temp_ob.append(copy)
|
||||
#args = (self,context)
|
||||
#self._handle = context.space_data.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
|
||||
# args = (self,context)
|
||||
# self._handle = context.space_data.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
|
||||
context.window_manager.modal_handler_add(self)
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
|
||||
classes = (
|
||||
@@ -143,4 +142,4 @@ classes = (
|
||||
RP_OT_eyedropper_material,
|
||||
)
|
||||
|
||||
register, unregister = bpy.utils.register_classes_factory(classes)
|
||||
register, unregister = bpy.utils.register_classes_factory(classes)
|
||||
|
||||
+257
-206
@@ -6,10 +6,11 @@ from ..core.addon_utils import get_picker_collection
|
||||
from ..core.bl_utils import get_view_3d_override, split_path, eval_attr
|
||||
from ..core.geometry_utils import bounding_rect
|
||||
from ..core.picker import get_picker_path, pack_picker, unpack_picker, load_picker_data
|
||||
#from .func_bgl import draw_callback_px
|
||||
#from .func_bgl import select_bone
|
||||
#from core.picker import *
|
||||
#from .utils import is_over_region
|
||||
|
||||
# from .func_bgl import draw_callback_px
|
||||
# from .func_bgl import select_bone
|
||||
# from core.picker import *
|
||||
# from .utils import is_over_region
|
||||
import gpu
|
||||
from mathutils import Vector, Euler, Matrix
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
@@ -18,34 +19,36 @@ import json
|
||||
import os
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def is_picker_space(space_data=None):
|
||||
if not space_data:
|
||||
space_data = bpy.context.space_data
|
||||
if space_data and (space_data.type == 'NODE_EDITOR' and space_data.tree_type == 'RigPickerTree'):
|
||||
if space_data and (
|
||||
space_data.type == "NODE_EDITOR" and space_data.tree_type == "RigPickerTree"
|
||||
):
|
||||
return True
|
||||
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class RP_OT_box_select(Operator):
|
||||
"""Box Select bones in the picker view"""
|
||||
|
||||
bl_idname = "node.rp_box_select"
|
||||
bl_label = "Picker Box Select"
|
||||
|
||||
mode: EnumProperty(items=[(i, i.title(), '') for i in ('SET', 'EXTEND', 'SUBSTRACT')])
|
||||
mode: EnumProperty(
|
||||
items=[(i, i.title(), "") for i in ("SET", "EXTEND", "SUBSTRACT")]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if not is_picker_space(context.space_data):
|
||||
return
|
||||
|
||||
|
||||
ob = context.object
|
||||
return ob and ob in PICKERS
|
||||
|
||||
'''
|
||||
"""
|
||||
def mode_from_event(self, event):
|
||||
if event.alt:
|
||||
return 'SUBSTRACT'
|
||||
@@ -53,17 +56,17 @@ class RP_OT_box_select(Operator):
|
||||
return 'EXTEND'
|
||||
else:
|
||||
return 'SET'
|
||||
'''
|
||||
"""
|
||||
|
||||
def draw_callback(self):
|
||||
#print('draw callback border')
|
||||
# print('draw callback border')
|
||||
if not self.draw_border:
|
||||
return
|
||||
|
||||
gpu.state.blend_set('ALPHA')
|
||||
gpu.state.blend_set("ALPHA")
|
||||
|
||||
# print('DRAW BORDER')
|
||||
|
||||
#print('DRAW BORDER')
|
||||
|
||||
self.color_shader.bind()
|
||||
self.color_shader.uniform_float("color", self.bg_color)
|
||||
self.bg_batch.draw(self.color_shader)
|
||||
@@ -75,93 +78,102 @@ class RP_OT_box_select(Operator):
|
||||
self.dash_shader.uniform_float("viewMatrix", matrix)
|
||||
self.dash_shader.uniform_float("dashSize", 5)
|
||||
self.dash_shader.uniform_float("gapSize", 4)
|
||||
|
||||
|
||||
self.contour_batch.draw(self.dash_shader)
|
||||
|
||||
gpu.state.blend_set('NONE')
|
||||
gpu.state.blend_set("NONE")
|
||||
|
||||
def invoke(self, context, event):
|
||||
#print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}')
|
||||
# print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}')
|
||||
|
||||
if context.object.mode != 'POSE':
|
||||
if context.object.mode != "POSE":
|
||||
bpy.ops.object.posemode_toggle()
|
||||
|
||||
self.timer = None
|
||||
#self.mode = self.mode_from_event(event)
|
||||
#self.invoke_event = event.copy()
|
||||
# self.mode = self.mode_from_event(event)
|
||||
# self.invoke_event = event.copy()
|
||||
self.region = context.region
|
||||
self.draw_border = False
|
||||
|
||||
self.picker = PICKERS[context.object]
|
||||
|
||||
self.start_mouse = event.mouse_region_x, event.mouse_region_y
|
||||
#self.shader = line_strip_shader
|
||||
# self.shader = line_strip_shader
|
||||
self.border_color = [1, 1, 1, 1]
|
||||
self.bg_color = [1, 1, 1, 0.05]
|
||||
|
||||
#args = (self, context)
|
||||
self.color_shader = gpu.shader.from_builtin('UNIFORM_COLOR')
|
||||
self.dash_shader = SHADERS['dashed_line']
|
||||
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL')
|
||||
|
||||
# args = (self, context)
|
||||
self.color_shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
||||
self.dash_shader = SHADERS["dashed_line"]
|
||||
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(
|
||||
self.draw_callback, (), "WINDOW", "POST_PIXEL"
|
||||
)
|
||||
|
||||
context.window_manager.modal_handler_add(self)
|
||||
|
||||
self.picker.press_event(self.mode)
|
||||
self.region.tag_redraw()
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def modal(self, context, event):
|
||||
|
||||
self.mouse = event.mouse_region_x, event.mouse_region_y
|
||||
|
||||
self.border = bounding_rect((self.start_mouse, self.mouse))
|
||||
|
||||
self.bg_batch = batch_for_shader(self.color_shader, 'TRI_FAN', {"pos": self.border})
|
||||
self.contour_batch = batch_for_shader(self.dash_shader, 'LINE_LOOP', {"pos": self.border})
|
||||
self.bg_batch = batch_for_shader(
|
||||
self.color_shader, "TRI_FAN", {"pos": self.border}
|
||||
)
|
||||
self.contour_batch = batch_for_shader(
|
||||
self.dash_shader, "LINE_LOOP", {"pos": self.border}
|
||||
)
|
||||
|
||||
self.draw_border = True
|
||||
|
||||
self.region.tag_redraw()
|
||||
|
||||
if event.value == 'RELEASE':
|
||||
if event.value == "RELEASE":
|
||||
return self.release_event(context)
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def release_event(self, context):
|
||||
|
||||
if get_picker_collection():
|
||||
self.picker.assign_bone_event()
|
||||
|
||||
elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]):
|
||||
elif (
|
||||
self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]
|
||||
):
|
||||
self.picker.border_select(self.border, self.mode)
|
||||
else:
|
||||
self.picker.move_event(self.mouse)
|
||||
self.picker.release_event(self.mode)
|
||||
|
||||
|
||||
bpy.ops.ed.undo_push(message="Box Select")
|
||||
|
||||
|
||||
return self.exit(context)
|
||||
|
||||
def exit(self, context):
|
||||
bpy.types.SpaceNodeEditor.draw_handler_remove(self._handle, 'WINDOW')
|
||||
bpy.types.SpaceNodeEditor.draw_handler_remove(self._handle, "WINDOW")
|
||||
context.region.tag_redraw()
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_picker_transform(Operator):
|
||||
"""Transform Bones in the picker view"""
|
||||
|
||||
bl_idname = "node.picker_transform"
|
||||
bl_label = "Transform Bone in Picker View"
|
||||
|
||||
mode : EnumProperty(items=[(m, m.title(), '') for m in ('ROTATE', 'SCALE')])
|
||||
|
||||
mode: EnumProperty(items=[(m, m.title(), "") for m in ("ROTATE", "SCALE")])
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.selected_pose_bones and is_picker_space(context.space_data)
|
||||
|
||||
'''
|
||||
"""
|
||||
def draw_callback(self):
|
||||
gpu.state.blend_set('ALPHA')
|
||||
gpu.state.line_width_set(2)
|
||||
@@ -179,18 +191,20 @@ class RP_OT_picker_transform(Operator):
|
||||
|
||||
gpu.state.line_width_set(1)
|
||||
gpu.state.blend_set('NONE')
|
||||
'''
|
||||
"""
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.override = get_view_3d_override()
|
||||
|
||||
self.view_center = Vector((int(context.region.width / 2), int(context.region.height / 2)))
|
||||
self.view_center = Vector(
|
||||
(int(context.region.width / 2), int(context.region.height / 2))
|
||||
)
|
||||
self.mouse_start = Vector((event.mouse_region_x, event.mouse_region_y))
|
||||
self.mouse = Vector((0, 0))
|
||||
|
||||
transform_type = context.scene.tool_settings.transform_pivot_point
|
||||
self.center = context.active_pose_bone.matrix.to_translation()
|
||||
if transform_type == 'MEDIAN_POINT':
|
||||
if transform_type == "MEDIAN_POINT":
|
||||
origins = [b.matrix.to_translation() for b in context.selected_pose_bones]
|
||||
self.center = sum(origins, Vector()) / len(context.selected_pose_bones)
|
||||
# self.bone_data = {}
|
||||
@@ -198,38 +212,36 @@ class RP_OT_picker_transform(Operator):
|
||||
# self.bone_data[bone] = bone.matrix.copy()
|
||||
self.bone_data = {b: b.matrix.copy() for b in context.selected_pose_bones}
|
||||
|
||||
space = self.override['area'].spaces.active
|
||||
space = self.override["area"].spaces.active
|
||||
|
||||
view_matrix = space.region_3d.view_matrix
|
||||
if space.region_3d.view_perspective == 'CAMERA':
|
||||
if space.region_3d.view_perspective == "CAMERA":
|
||||
view_matrix = context.scene.camera.matrix_world
|
||||
|
||||
context.window.cursor_modal_set('MOVE_X')
|
||||
context.window.cursor_modal_set("MOVE_X")
|
||||
self.view_vector = Vector((0, 0, 1))
|
||||
if self.mode == 'ROTATE':
|
||||
if self.mode == "ROTATE":
|
||||
self.view_vector.rotate(view_matrix)
|
||||
|
||||
|
||||
elif self.mode == 'SCALE':
|
||||
elif self.mode == "SCALE":
|
||||
self.view_vector = Vector((0, 0, 0))
|
||||
|
||||
|
||||
self.transform_type = "VIEW"
|
||||
self.transform_types = ["VIEW", 'GLOBAL', 'LOCAL']
|
||||
if context.scene.transform_orientation_slots[0].type == 'LOCAL':
|
||||
self.transform_types = ["VIEW", 'LOCAL', 'GLOBAL']
|
||||
self.transform_types = ["VIEW", "GLOBAL", "LOCAL"]
|
||||
if context.scene.transform_orientation_slots[0].type == "LOCAL":
|
||||
self.transform_types = ["VIEW", "LOCAL", "GLOBAL"]
|
||||
|
||||
self.transform_orientation = context.scene.transform_orientation_slots[0].type
|
||||
|
||||
#self.dash_shader = SHADERS['dashed_line']
|
||||
|
||||
# self.dash_shader = SHADERS['dashed_line']
|
||||
|
||||
#self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL')
|
||||
# self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL')
|
||||
context.window_manager.modal_handler_add(self)
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def change_transform_type(self):
|
||||
indices = {0: 1, 1:2, 2:1}
|
||||
indices = {0: 1, 1: 2, 2: 1}
|
||||
index = self.transform_types.index(self.transform_type)
|
||||
new_index = indices[index]
|
||||
self.transform_type = self.transform_types[new_index]
|
||||
@@ -237,73 +249,74 @@ class RP_OT_picker_transform(Operator):
|
||||
def release_event(self, context):
|
||||
scn = bpy.context.scene
|
||||
|
||||
# Insert keyframe
|
||||
#bpy.ops.ed.undo_push(message="Transform")
|
||||
# Insert keyframe
|
||||
# bpy.ops.ed.undo_push(message="Transform")
|
||||
if scn.tool_settings.use_keyframe_insert_auto:
|
||||
try:
|
||||
bpy.ops.animtoolbox.insert_keyframe()
|
||||
except Exception:
|
||||
self.report({"WARNING"}, 'You need animtoolbox addon for inserting keyframe')
|
||||
self.report(
|
||||
{"WARNING"}, "You need animtoolbox addon for inserting keyframe"
|
||||
)
|
||||
|
||||
self.exit(context)
|
||||
|
||||
def exit(self, context):
|
||||
#bpy.types.SpaceNodeEditor.draw_handler_remove(self._handle, 'WINDOW')
|
||||
# bpy.types.SpaceNodeEditor.draw_handler_remove(self._handle, 'WINDOW')
|
||||
context.window.cursor_modal_restore()
|
||||
#context.region.tag_redraw()
|
||||
|
||||
# context.region.tag_redraw()
|
||||
|
||||
def modal(self, context, event):
|
||||
scn = context.scene
|
||||
self.mouse = Vector((event.mouse_region_x, event.mouse_region_y))
|
||||
|
||||
if self.mode == 'ROTATE':
|
||||
if self.mode == "ROTATE":
|
||||
delta = (event.mouse_region_x - self.mouse_start[0]) / 100
|
||||
elif self.mode == 'SCALE':
|
||||
delta = 1 + (event.mouse_region_x - self.mouse_start[0]) / 100
|
||||
#delta = (self.mouse - self.view_center).length / (self.mouse_start - self.view_center).length
|
||||
|
||||
elif self.mode == "SCALE":
|
||||
delta = 1 + (event.mouse_region_x - self.mouse_start[0]) / 100
|
||||
# delta = (self.mouse - self.view_center).length / (self.mouse_start - self.view_center).length
|
||||
|
||||
transform_type = self.transform_type
|
||||
#self.batch = batch_for_shader(self.dash_shader, 'LINE_STRIP', {"pos": [self.mouse_start, self.mouse]})
|
||||
#context.area.tag_redraw()
|
||||
|
||||
#print(event.type, event.value)
|
||||
if self.mode == 'ROTATE' and event.type == "R" and event.value == 'PRESS':
|
||||
# self.batch = batch_for_shader(self.dash_shader, 'LINE_STRIP', {"pos": [self.mouse_start, self.mouse]})
|
||||
# context.area.tag_redraw()
|
||||
|
||||
# print(event.type, event.value)
|
||||
if self.mode == "ROTATE" and event.type == "R" and event.value == "PRESS":
|
||||
with context.temp_override(**self.override):
|
||||
self.exit(context)
|
||||
bpy.ops.transform.trackball('INVOKE_DEFAULT')
|
||||
return {'FINISHED'}
|
||||
bpy.ops.transform.trackball("INVOKE_DEFAULT")
|
||||
return {"FINISHED"}
|
||||
|
||||
if event.type == "LEFTMOUSE" and event.value == 'RELEASE':
|
||||
if event.type == "LEFTMOUSE" and event.value == "RELEASE":
|
||||
self.release_event(context)
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
if event.type in {"RIGHTMOUSE", "ESC"}:
|
||||
for bone, matrix in self.bone_data.items():
|
||||
bone.matrix = matrix
|
||||
self.exit(context)
|
||||
return {'CANCELLED'}
|
||||
return {"CANCELLED"}
|
||||
|
||||
elif event.type == "X" and event.value == 'PRESS':
|
||||
elif event.type == "X" and event.value == "PRESS":
|
||||
self.change_transform_type()
|
||||
self.view_vector = Vector((1, 0, 0))
|
||||
#transform_type = self.transform_orientation
|
||||
# transform_type = self.transform_orientation
|
||||
|
||||
elif event.type == "Y" and event.value == 'PRESS':
|
||||
elif event.type == "Y" and event.value == "PRESS":
|
||||
self.change_transform_type()
|
||||
self.view_vector = Vector((0, 1, 0))
|
||||
#transform_type = self.transform_orientation
|
||||
# transform_type = self.transform_orientation
|
||||
|
||||
elif event.type == "Z" and event.value == 'PRESS':
|
||||
elif event.type == "Z" and event.value == "PRESS":
|
||||
self.change_transform_type()
|
||||
self.view_vector = Vector((0, 0, 1))
|
||||
#transform_type = self.transform_orientation
|
||||
# transform_type = self.transform_orientation
|
||||
|
||||
elif event.type == "MOUSEMOVE":
|
||||
|
||||
if self.mode == 'ROTATE':
|
||||
|
||||
if self.mode == "ROTATE":
|
||||
transform_matrix = Matrix.Rotation(delta, 4, self.view_vector)
|
||||
elif self.mode == 'SCALE':
|
||||
elif self.mode == "SCALE":
|
||||
if self.view_vector.length:
|
||||
transform_matrix = Matrix.Scale(delta, 4, self.view_vector)
|
||||
else:
|
||||
@@ -314,14 +327,14 @@ class RP_OT_picker_transform(Operator):
|
||||
if scn.tool_settings.transform_pivot_point == "INDIVIDUAL_ORIGINS":
|
||||
center = matrix.to_translation()
|
||||
|
||||
if self.mode == 'ROTATE':
|
||||
if transform_type == 'LOCAL':
|
||||
if self.mode == "ROTATE":
|
||||
if transform_type == "LOCAL":
|
||||
view_vector = self.view_vector.copy()
|
||||
view_vector.rotate(matrix)
|
||||
transform_matrix = Matrix.Rotation(delta, 4, view_vector)
|
||||
|
||||
elif self.mode == 'SCALE':
|
||||
if transform_type == 'LOCAL':
|
||||
elif self.mode == "SCALE":
|
||||
if transform_type == "LOCAL":
|
||||
view_vector = self.view_vector.copy()
|
||||
view_vector.rotate(matrix)
|
||||
transform_matrix = Matrix.Scale(delta, 4, view_vector)
|
||||
@@ -335,40 +348,40 @@ class RP_OT_picker_transform(Operator):
|
||||
|
||||
bone.matrix = mat
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
|
||||
class RP_OT_toogle_property(Operator):
|
||||
"""Invert a bone custom property"""
|
||||
|
||||
bl_idname = "rigpicker.toogle_property"
|
||||
bl_label = 'Toogle Property'
|
||||
bl_label = "Toogle Property"
|
||||
|
||||
data_path : StringProperty()
|
||||
data_path: StringProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return is_picker_space(context.space_data)
|
||||
|
||||
def execute(self,context):
|
||||
def execute(self, context):
|
||||
ob = context.object
|
||||
|
||||
|
||||
try:
|
||||
value = ob.path_resolve(self.data_path)
|
||||
except Exception:
|
||||
return {'CANCELLED'}
|
||||
return {"CANCELLED"}
|
||||
|
||||
data = ob
|
||||
prop_name = self.data_path
|
||||
#if '.' in self.data_path:
|
||||
# if '.' in self.data_path:
|
||||
# data, prop = prop_name.rsplit('.', 1)
|
||||
|
||||
value = type(value)(not value)
|
||||
exec(f'{repr(ob)}.{self.data_path} = {value}')
|
||||
|
||||
#setattr(data, prop_name, value)
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.object.mode_set(mode='POSE')
|
||||
value = type(value)(not value)
|
||||
exec(f"{repr(ob)}.{self.data_path} = {value}")
|
||||
|
||||
# setattr(data, prop_name, value)
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
bpy.ops.object.mode_set(mode="POSE")
|
||||
|
||||
if context.scene.tool_settings.use_keyframe_insert_auto:
|
||||
bone_name, _ = split_path(self.data_path)
|
||||
@@ -376,42 +389,42 @@ class RP_OT_toogle_property(Operator):
|
||||
|
||||
context.area.tag_redraw()
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_reload_picker(Operator):
|
||||
"""Reload the picker shapes"""
|
||||
|
||||
bl_idname = "rigpicker.reload_picker"
|
||||
bl_label = 'Reload Picker'
|
||||
bl_label = "Reload Picker"
|
||||
|
||||
#@classmethod
|
||||
#def poll(cls, context):
|
||||
# @classmethod
|
||||
# def poll(cls, context):
|
||||
# if not is_picker_space(context):
|
||||
# return
|
||||
|
||||
def execute(self, context):
|
||||
if context.object.type == 'ARMATURE':
|
||||
if context.object.type == "ARMATURE":
|
||||
rig = context.object
|
||||
else:
|
||||
collection = get_picker_collection(context.object)
|
||||
rig = collection.rig_picker.rig
|
||||
|
||||
#print('Reload', rig)
|
||||
# print('Reload', rig)
|
||||
load_picker_data(rig)
|
||||
|
||||
for area in context.screen.areas:
|
||||
if is_picker_space(area.spaces.active):
|
||||
area.tag_redraw()
|
||||
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_toogle_bone_layer(Operator):
|
||||
"""Toogle bone layer visibility when double clicking on a bone"""
|
||||
|
||||
bl_idname = "rigpicker.toogle_bone_layer"
|
||||
bl_label = 'Toogle Bone Layer'
|
||||
bl_label = "Toogle Bone Layer"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -421,7 +434,7 @@ class RP_OT_toogle_bone_layer(Operator):
|
||||
ob = context.object
|
||||
picker = PICKERS.get(ob)
|
||||
|
||||
if picker.hover_shape and picker.hover_shape.type == 'bone':
|
||||
if picker.hover_shape and picker.hover_shape.type == "bone":
|
||||
return True
|
||||
|
||||
def execute(self, context):
|
||||
@@ -442,62 +455,64 @@ class RP_OT_toogle_bone_layer(Operator):
|
||||
|
||||
class RP_OT_context_menu_picker(Operator):
|
||||
"""Display Menu with the custom properties of the hovered bone if any or the active bone"""
|
||||
|
||||
bl_idname = "node.context_menu_picker"
|
||||
bl_label = 'Context Menu Picker'
|
||||
bl_label = "Context Menu Picker"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return is_picker_space(context.space_data)
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.wm.call_menu(name='RP_MT_context_menu')
|
||||
bpy.ops.wm.call_menu(name="RP_MT_context_menu")
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_pack_picker(Operator):
|
||||
"""Pack Unpack the picker on the rig"""
|
||||
|
||||
bl_idname = "rigpicker.pack_picker"
|
||||
bl_label = 'Pack Picker'
|
||||
bl_label = "Pack Picker"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
return (ob and ob.type == 'ARMATURE' and ob.data.rig_picker.sources)
|
||||
return ob and ob.type == "ARMATURE" and ob.data.rig_picker.sources
|
||||
|
||||
def execute(self, context):
|
||||
print('Pack Pickers...')
|
||||
|
||||
print("Pack Pickers...")
|
||||
|
||||
rig = context.object
|
||||
|
||||
if 'pickers' in rig.data.rig_picker.keys():
|
||||
if "pickers" in rig.data.rig_picker.keys():
|
||||
unpack_picker(rig)
|
||||
self.report({"INFO"}, f'The picker is unpacked')
|
||||
self.report({"INFO"}, f"The picker is unpacked")
|
||||
return {"FINISHED"}
|
||||
|
||||
pack_picker(rig)
|
||||
|
||||
if not rig.data.rig_picker['pickers']:
|
||||
self.report({"ERROR"}, f'No picker have been packed')
|
||||
return {"CANCELLED"}
|
||||
if not rig.data.rig_picker["pickers"]:
|
||||
self.report({"ERROR"}, f"No picker have been packed")
|
||||
return {"CANCELLED"}
|
||||
|
||||
elif len(rig.data.rig_picker['pickers']) < len(rig.data.rig_picker.sources):
|
||||
self.report({"WARNING"}, f'No all pickers have been packed')
|
||||
return {"FINISHED"}
|
||||
elif len(rig.data.rig_picker["pickers"]) < len(rig.data.rig_picker.sources):
|
||||
self.report({"WARNING"}, f"No all pickers have been packed")
|
||||
return {"FINISHED"}
|
||||
|
||||
self.report({"INFO"}, f'The picker is packed')
|
||||
self.report({"INFO"}, f"The picker is packed")
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_call_operator(Operator):
|
||||
bl_idname = "rigpicker.call_operator"
|
||||
bl_label = 'Call operator'
|
||||
bl_label = "Call operator"
|
||||
|
||||
operator : StringProperty()
|
||||
arguments : StringProperty()
|
||||
operator: StringProperty()
|
||||
arguments: StringProperty()
|
||||
invoke: BoolProperty()
|
||||
view_3d : BoolProperty()
|
||||
view_3d: BoolProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -509,30 +524,30 @@ class RP_OT_call_operator(Operator):
|
||||
op = eval_attr(bpy.ops, properties.operator).get_rna_type()
|
||||
return op.description
|
||||
except AttributeError:
|
||||
return 'Call operator'
|
||||
return "Call operator"
|
||||
|
||||
def execute(self, context):
|
||||
#context.area.tag_redraw()
|
||||
def execute(self, context):
|
||||
# context.area.tag_redraw()
|
||||
|
||||
override = {}
|
||||
if self.view_3d:
|
||||
override = get_view_3d_override()
|
||||
|
||||
|
||||
arguments = json.loads(self.arguments or "{}")
|
||||
|
||||
with context.temp_override(**override):
|
||||
try:
|
||||
ops = eval_attr(bpy.ops, self.operator)
|
||||
if self.invoke:
|
||||
ops('INVOKE_DEFAULT', **arguments)
|
||||
ops("INVOKE_DEFAULT", **arguments)
|
||||
else:
|
||||
ops(**arguments)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
self.report({"ERROR"}, f'The operator {self.operator} cannot be called')
|
||||
self.report({"ERROR"}, f"The operator {self.operator} cannot be called")
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
context.area.tag_redraw()
|
||||
|
||||
return {"FINISHED"}
|
||||
@@ -545,72 +560,78 @@ class RP_MT_context_menu(Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.operator_context = 'INVOKE_DEFAULT'
|
||||
#col.use_property_split = True
|
||||
col.operator_context = "INVOKE_DEFAULT"
|
||||
# col.use_property_split = True
|
||||
|
||||
ob = context.object
|
||||
picker = PICKERS.get(ob)
|
||||
|
||||
if picker.hover_shape and picker.hover_shape.type == 'bone':
|
||||
if picker.hover_shape and picker.hover_shape.type == "bone":
|
||||
bone = picker.hover_shape.bone
|
||||
else:
|
||||
bone = context.active_pose_bone
|
||||
|
||||
# Draw Space Switch Operator
|
||||
if getattr(ob.data, 'space_switch'):
|
||||
if getattr(ob.data, "space_switch"):
|
||||
space_switch = ob.data.space_switch
|
||||
|
||||
data_paths = [f'pose.bones["{bone.name}"]["{k}"]' for k in bone.keys()]
|
||||
space_bone = next((s for s in space_switch.bones if s.data_path in data_paths), None)
|
||||
space_bone = next(
|
||||
(s for s in space_switch.bones if s.data_path in data_paths), None
|
||||
)
|
||||
if space_bone:
|
||||
|
||||
index = list(space_switch.bones).index(space_bone)
|
||||
value = ob.path_resolve(space_bone.data_path)
|
||||
space = next((s.name for s in space_bone.spaces if s.value == value), None)
|
||||
space = next(
|
||||
(s.name for s in space_bone.spaces if s.value == value), None
|
||||
)
|
||||
|
||||
op = col.operator("spaceswitch.change_space", text=f'({space})', icon='PINNED')
|
||||
op.index=index
|
||||
op = col.operator(
|
||||
"spaceswitch.change_space", text=f"({space})", icon="PINNED"
|
||||
)
|
||||
op.index = index
|
||||
col.separator()
|
||||
|
||||
if bone:
|
||||
if bone:
|
||||
for key in bone.keys():
|
||||
col.prop(bone,f'["{key}"]', slider=True)
|
||||
col.prop(bone, f'["{key}"]', slider=True)
|
||||
|
||||
#layout.operator("rigpicker.show_bone_layer", text="Show Bone Layer", ).type = 'ACTIVE'
|
||||
#layout.operator("rigidbody.objects_add", text="B Add Passive").type = 'PASSIVE'
|
||||
# layout.operator("rigpicker.show_bone_layer", text="Show Bone Layer", ).type = 'ACTIVE'
|
||||
# layout.operator("rigidbody.objects_add", text="B Add Passive").type = 'PASSIVE'
|
||||
|
||||
|
||||
class RP_OT_add_picker_collection(Operator):
|
||||
bl_idname = "rigpicker.add_picker_collection"
|
||||
bl_label = "Add a Picker Collection"
|
||||
bl_description = "Add a Picker Collection"
|
||||
bl_options = {'UNDO', 'REGISTER'}
|
||||
bl_options = {"UNDO", "REGISTER"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
return (ob and ob.type == 'ARMATURE')
|
||||
return ob and ob.type == "ARMATURE"
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
ob = context.object
|
||||
|
||||
name = ob.name
|
||||
if name.endswith('_rig'):
|
||||
if name.endswith("_rig"):
|
||||
name = name[:-4]
|
||||
|
||||
canvas_name = f'canevas_{name}'
|
||||
canvas_name = f"canevas_{name}"
|
||||
canvas_points = [(-0.5, 0.5, 0), (0.5, 0.5, 0), (0.5, -0.5, 0), (-0.5, -0.5, 0)]
|
||||
canvas_faces = [(0, 1, 2, 3)]
|
||||
|
||||
|
||||
canvas_mesh = bpy.data.meshes.new(canvas_name)
|
||||
canvas_mesh.from_pydata(canvas_points, [], canvas_faces)
|
||||
canvas_mesh.update(calc_edges=True)
|
||||
|
||||
canvas_ob = bpy.data.objects.new(canvas_name, canvas_mesh)
|
||||
canvas_ob.rig_picker.shape_type = 'DISPLAY'
|
||||
canvas_ob.rig_picker.shape_type = "DISPLAY"
|
||||
|
||||
col = bpy.data.collections.new(f'Picker {name}')
|
||||
col = bpy.data.collections.new(f"Picker {name}")
|
||||
col.rig_picker.enabled = True
|
||||
col.rig_picker.rig = ob
|
||||
col.rig_picker.canvas = canvas_ob
|
||||
@@ -621,44 +642,44 @@ class RP_OT_add_picker_collection(Operator):
|
||||
|
||||
self.report({"INFO"}, f"New Picker Collection {col.name} Created")
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_add_picker_source(Operator):
|
||||
bl_idname = "rigpicker.add_picker_source"
|
||||
bl_label = "Add a Picker source"
|
||||
bl_description = "Add a Picker source"
|
||||
bl_options = {'UNDO', 'REGISTER'}
|
||||
bl_options = {"UNDO", "REGISTER"}
|
||||
|
||||
def execute(self, context):
|
||||
arm = context.object.data
|
||||
arm.rig_picker.sources.add()
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_remove_picker_source(Operator):
|
||||
bl_idname = "rigpicker.remove_picker_source"
|
||||
bl_label = "Delete a Picker source"
|
||||
bl_description = "Delete a Picker source"
|
||||
bl_options = {'UNDO', 'REGISTER'}
|
||||
bl_options = {"UNDO", "REGISTER"}
|
||||
|
||||
index : IntProperty(default=-1)
|
||||
index: IntProperty(default=-1)
|
||||
|
||||
def execute(self, context):
|
||||
arm = context.object.data
|
||||
arm.rig_picker.sources.remove(self.index)
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_fit_picker(Operator):
|
||||
bl_idname = "rigpicker.fit_picker"
|
||||
bl_label = "Fit Picker"
|
||||
bl_description = "Fit Picker in 2d view"
|
||||
bl_options = {'UNDO', 'REGISTER'}
|
||||
bl_options = {"UNDO", "REGISTER"}
|
||||
|
||||
index : IntProperty()
|
||||
index: IntProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -675,17 +696,22 @@ class RP_OT_fit_picker(Operator):
|
||||
view2d = context.region.view2d
|
||||
|
||||
if self.index == -1:
|
||||
#print('Picker Group')
|
||||
# print('Picker Group')
|
||||
picker = picker_group
|
||||
|
||||
view_rect = [view2d.view_to_region(*co, clip=False) for co in picker.rect]
|
||||
bpy.ops.view2d.zoom_border(
|
||||
xmin=round(view_rect[3][0]), xmax=round(view_rect[1][0]),
|
||||
ymin=round(view_rect[3][1]), ymax=round(view_rect[1][1]),
|
||||
wait_for_input=False, zoom_out=False
|
||||
xmin=round(view_rect[3][0]),
|
||||
xmax=round(view_rect[1][0]),
|
||||
ymin=round(view_rect[3][1]),
|
||||
ymax=round(view_rect[1][1]),
|
||||
wait_for_input=False,
|
||||
zoom_out=False,
|
||||
)
|
||||
|
||||
region_center = Vector((context.region.width * 0.5, context.region.height * 0.5))
|
||||
region_center = Vector(
|
||||
(context.region.width * 0.5, context.region.height * 0.5)
|
||||
)
|
||||
view_center = view2d.region_to_view(*region_center)
|
||||
|
||||
view_offset = Vector(view_center) + (picker.center - Vector(view_center))
|
||||
@@ -695,21 +721,27 @@ class RP_OT_fit_picker(Operator):
|
||||
|
||||
bpy.ops.view2d.pan(deltax=round(delta[0]), deltay=round(delta[1]))
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
keymaps = []
|
||||
|
||||
|
||||
def register_keymaps():
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
km = wm.keyconfigs.addon.keymaps.new(name="Node Editor", space_type="NODE_EDITOR")
|
||||
|
||||
for i in range(10):
|
||||
kmi = km.keymap_items.new("rigpicker.fit_picker", type=f"NUMPAD_{i}", value="PRESS")
|
||||
kmi = km.keymap_items.new(
|
||||
"rigpicker.fit_picker", type=f"NUMPAD_{i}", value="PRESS"
|
||||
)
|
||||
kmi.properties.index = i - 1
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("rigpicker.call_operator", type="NUMPAD_PERIOD", value="PRESS")
|
||||
kmi = km.keymap_items.new(
|
||||
"rigpicker.call_operator", type="NUMPAD_PERIOD", value="PRESS"
|
||||
)
|
||||
kmi.properties.operator = "view3d.view_selected"
|
||||
kmi.properties.view_3d = True
|
||||
keymaps.append((km, kmi))
|
||||
@@ -719,12 +751,16 @@ def register_keymaps():
|
||||
kmi.properties.arguments = '{"action": "SELECT"}'
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("rigpicker.call_operator", type="A", value="PRESS", alt=True)
|
||||
kmi = km.keymap_items.new(
|
||||
"rigpicker.call_operator", type="A", value="PRESS", alt=True
|
||||
)
|
||||
kmi.properties.operator = "pose.select_all"
|
||||
kmi.properties.arguments = '{"action": "DESELECT"}'
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("rigpicker.toogle_bone_layer", type="LEFTMOUSE", value="DOUBLE_CLICK")
|
||||
kmi = km.keymap_items.new(
|
||||
"rigpicker.toogle_bone_layer", type="LEFTMOUSE", value="DOUBLE_CLICK"
|
||||
)
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("rigpicker.call_operator", type="X", value="PRESS")
|
||||
@@ -735,55 +771,69 @@ def register_keymaps():
|
||||
kmi.properties.operator = "animtoolbox.insert_keyframe"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("anim.keyframe_delete_v3d", type="K", value="PRESS", alt=True)
|
||||
kmi = km.keymap_items.new(
|
||||
"anim.keyframe_delete_v3d", type="K", value="PRESS", alt=True
|
||||
)
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("rigpicker.call_operator", type="G", value="PRESS")
|
||||
kmi.properties.operator = 'transform.translate'
|
||||
kmi.properties.operator = "transform.translate"
|
||||
kmi.properties.view_3d = True
|
||||
kmi.properties.invoke = True
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("rigpicker.call_operator", type="G", value="PRESS", alt=True)
|
||||
kmi.properties.operator = 'pose.loc_clear'
|
||||
kmi = km.keymap_items.new(
|
||||
"rigpicker.call_operator", type="G", value="PRESS", alt=True
|
||||
)
|
||||
kmi.properties.operator = "pose.loc_clear"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("node.picker_transform", type="R", value="PRESS")
|
||||
kmi.properties.mode = 'ROTATE'
|
||||
kmi.properties.mode = "ROTATE"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("rigpicker.call_operator", type="R", value="PRESS", alt=True)
|
||||
kmi.properties.operator = 'pose.rot_clear'
|
||||
kmi = km.keymap_items.new(
|
||||
"rigpicker.call_operator", type="R", value="PRESS", alt=True
|
||||
)
|
||||
kmi.properties.operator = "pose.rot_clear"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("node.picker_transform", type="S", value="PRESS")
|
||||
kmi.properties.mode = 'SCALE'
|
||||
kmi.properties.mode = "SCALE"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("rigpicker.call_operator", type="S", value="PRESS", alt=True)
|
||||
kmi.properties.operator = 'pose.scale_clear'
|
||||
kmi = km.keymap_items.new(
|
||||
"rigpicker.call_operator", type="S", value="PRESS", alt=True
|
||||
)
|
||||
kmi.properties.operator = "pose.scale_clear"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("node.context_menu_picker", type="RIGHTMOUSE", value="PRESS")
|
||||
kmi = km.keymap_items.new(
|
||||
"node.context_menu_picker", type="RIGHTMOUSE", value="PRESS"
|
||||
)
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS")
|
||||
kmi.properties.mode = 'SET'
|
||||
kmi.properties.mode = "SET"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", shift=True)
|
||||
kmi.properties.mode = 'EXTEND'
|
||||
kmi = km.keymap_items.new(
|
||||
"node.rp_box_select", type="LEFTMOUSE", value="PRESS", shift=True
|
||||
)
|
||||
kmi.properties.mode = "EXTEND"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
#kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", ctrl=True)
|
||||
kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", alt=True)
|
||||
kmi.properties.mode = 'SUBSTRACT'
|
||||
# kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", ctrl=True)
|
||||
kmi = km.keymap_items.new(
|
||||
"node.rp_box_select", type="LEFTMOUSE", value="PRESS", alt=True
|
||||
)
|
||||
kmi.properties.mode = "SUBSTRACT"
|
||||
keymaps.append((km, kmi))
|
||||
|
||||
#km = wm.keyconfigs.addon.keymaps.new(name="View2D")
|
||||
#kmi = km.keymap_items.new("rigpicker.call_operator", type="MIDDLEMOUSE", value="PRESS")
|
||||
#kmi.properties.operator = "bpy.ops.view2d.pan('INVOKE_DEFAULT')"
|
||||
#keymaps.append((km, kmi))
|
||||
# km = wm.keyconfigs.addon.keymaps.new(name="View2D")
|
||||
# kmi = km.keymap_items.new("rigpicker.call_operator", type="MIDDLEMOUSE", value="PRESS")
|
||||
# kmi.properties.operator = "bpy.ops.view2d.pan('INVOKE_DEFAULT')"
|
||||
# keymaps.append((km, kmi))
|
||||
|
||||
|
||||
def unregister_keymaps():
|
||||
@@ -791,6 +841,7 @@ def unregister_keymaps():
|
||||
km.keymap_items.remove(kmi)
|
||||
keymaps.clear()
|
||||
|
||||
|
||||
classes = (
|
||||
RP_OT_box_select,
|
||||
RP_OT_toogle_property,
|
||||
@@ -804,19 +855,19 @@ classes = (
|
||||
RP_OT_add_picker_source,
|
||||
RP_OT_remove_picker_source,
|
||||
RP_OT_fit_picker,
|
||||
RP_OT_add_picker_collection
|
||||
#RP_OT_ui_draw
|
||||
RP_OT_add_picker_collection,
|
||||
# RP_OT_ui_draw
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
|
||||
register_keymaps()
|
||||
|
||||
|
||||
def unregister():
|
||||
unregister_keymaps()
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
bpy.utils.unregister_class(cls)
|
||||
|
||||
+91
-69
@@ -1,4 +1,3 @@
|
||||
|
||||
import json
|
||||
from os.path import abspath
|
||||
from pathlib import Path
|
||||
@@ -13,23 +12,23 @@ from ..core.bl_utils import link_mat_to_object, flip_name
|
||||
|
||||
|
||||
class RP_OT_create_shape(Operator):
|
||||
bl_label = 'Create UI shape'
|
||||
bl_idname = 'rigpicker.create_shape'
|
||||
#bl_options = {'REGISTER', 'UNDO'}
|
||||
bl_label = "Create UI shape"
|
||||
bl_idname = "rigpicker.create_shape"
|
||||
# bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.object and context.object.mode == 'POSE')
|
||||
|
||||
return context.object and context.object.mode == "POSE"
|
||||
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
for col in bpy.data.collections:
|
||||
if col.rig_picker.enabled:
|
||||
self.layout.prop(col.rig_picker, 'link_shape', text=col.name)
|
||||
self.layout.prop(col.rig_picker, "link_shape", text=col.name)
|
||||
|
||||
def execute(self,context):
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
vl = context.view_layer
|
||||
|
||||
@@ -42,13 +41,15 @@ class RP_OT_create_shape(Operator):
|
||||
|
||||
ob.rig_picker.name = name
|
||||
|
||||
verts=[(0,0,0)]
|
||||
verts = [(0, 0, 0)]
|
||||
edges = []
|
||||
faces =[]
|
||||
faces = []
|
||||
|
||||
mesh.from_pydata(verts, edges, faces)
|
||||
|
||||
picker_selected_cols = [col for col in bpy.data.collections if col.rig_picker.link_shape]
|
||||
picker_selected_cols = [
|
||||
col for col in bpy.data.collections if col.rig_picker.link_shape
|
||||
]
|
||||
|
||||
for col in picker_selected_cols or [scn.collection]:
|
||||
col.objects.link(ob)
|
||||
@@ -64,36 +65,36 @@ class RP_OT_create_shape(Operator):
|
||||
|
||||
offset += 0.05
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_name_from_bone(Operator):
|
||||
bl_label = 'Name Shape from selected bones'
|
||||
bl_idname = 'rigpicker.name_from_bone'
|
||||
bl_description = 'Rename all shapes from related bones name'
|
||||
#bl_options = {'REGISTER', 'UNDO'}
|
||||
bl_label = "Name Shape from selected bones"
|
||||
bl_idname = "rigpicker.name_from_bone"
|
||||
bl_description = "Rename all shapes from related bones name"
|
||||
# bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self,context):
|
||||
def execute(self, context):
|
||||
|
||||
col = get_picker_collection(context.object)
|
||||
|
||||
for ob in col.all_objects:
|
||||
if ob.rig_picker.shape_type == 'BONE':
|
||||
if ob.rig_picker.shape_type == "BONE":
|
||||
ob.name = ob.rig_picker.name
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_mirror_shape(Operator):
|
||||
bl_label = 'Mirror UI shape'
|
||||
bl_idname = 'rigpicker.mirror_shape'
|
||||
#bl_options = g
|
||||
bl_label = "Mirror UI shape"
|
||||
bl_idname = "rigpicker.mirror_shape"
|
||||
# bl_options = g
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.object and context.object.type in ('MESH', 'CURVE', 'TEXT'))
|
||||
return context.object and context.object.type in ("MESH", "CURVE", "TEXT")
|
||||
|
||||
def execute(self,context):
|
||||
def execute(self, context):
|
||||
collection = get_picker_collection(context.object)
|
||||
objects = context.selected_objects
|
||||
|
||||
@@ -103,9 +104,13 @@ class RP_OT_mirror_shape(Operator):
|
||||
continue
|
||||
|
||||
for mod in ob.modifiers:
|
||||
if (mod.type == 'NODES' and mod.node_group and mod.node_group.name == 'Symmetrize' and
|
||||
mod.get('Socket_2') in objects):
|
||||
|
||||
if (
|
||||
mod.type == "NODES"
|
||||
and mod.node_group
|
||||
and mod.node_group.name == "Symmetrize"
|
||||
and mod.get("Socket_2") in objects
|
||||
):
|
||||
|
||||
bpy.data.objects.remove(ob)
|
||||
|
||||
if collection.rig_picker.symmetry:
|
||||
@@ -116,14 +121,14 @@ class RP_OT_mirror_shape(Operator):
|
||||
for ob in objects:
|
||||
flipped_name = flip_name(ob.name)
|
||||
if flipped_name == ob.name:
|
||||
suffix = '.L'
|
||||
flipped_suffix = '.R'
|
||||
suffix = ".L"
|
||||
flipped_suffix = ".R"
|
||||
# Determine side of the object
|
||||
if ob.matrix_world.to_translation()[0] < x_axis:
|
||||
suffix, flipped_suffix = flipped_suffix, suffix
|
||||
|
||||
flipped_name = f'{ob.name}{flipped_suffix}'
|
||||
ob.name = f'{ob.name}{suffix}'
|
||||
|
||||
flipped_name = f"{ob.name}{flipped_suffix}"
|
||||
ob.name = f"{ob.name}{suffix}"
|
||||
|
||||
flipped_object = ob.copy()
|
||||
flipped_object.name = flipped_name
|
||||
@@ -133,20 +138,20 @@ class RP_OT_mirror_shape(Operator):
|
||||
flipped_object.modifiers.remove(mod)
|
||||
|
||||
# Add symmetrize modifier TODO add it into a resource
|
||||
mod = flipped_object.modifiers.new(name='Symmetrize', type='NODES')
|
||||
mod.node_group = bpy.data.node_groups['Symmetrize']
|
||||
mod['Socket_2'] = ob
|
||||
mod['Socket_3'] = collection.rig_picker.symmetry
|
||||
mod = flipped_object.modifiers.new(name="Symmetrize", type="NODES")
|
||||
mod.node_group = bpy.data.node_groups["Symmetrize"]
|
||||
mod["Socket_2"] = ob
|
||||
mod["Socket_3"] = collection.rig_picker.symmetry
|
||||
|
||||
for col in ob.users_collection:
|
||||
col.objects.link(flipped_object)
|
||||
|
||||
if ob.rig_picker.shape_type == 'BONE':
|
||||
if ob.rig_picker.shape_type == "BONE":
|
||||
flipped_object.rig_picker.name = flip_name(ob.rig_picker.name)
|
||||
|
||||
elif ob.rig_picker.shape_type == 'FUNCTION':
|
||||
elif ob.rig_picker.shape_type == "FUNCTION":
|
||||
args = {}
|
||||
for key,value in eval(ob.rig_picker.arguments).items():
|
||||
for key, value in eval(ob.rig_picker.arguments).items():
|
||||
if type(value) == list:
|
||||
mirrored_value = []
|
||||
for item in value:
|
||||
@@ -158,32 +163,37 @@ class RP_OT_mirror_shape(Operator):
|
||||
|
||||
flipped_object.rig_picker.arguments = str(args)
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RP_OT_select_shape_type(Operator):
|
||||
bl_label = 'Select Shape by Type'
|
||||
bl_idname = 'rigpicker.select_shape_type'
|
||||
#bl_options = {'REGISTER', 'UNDO'}
|
||||
bl_label = "Select Shape by Type"
|
||||
bl_idname = "rigpicker.select_shape_type"
|
||||
# bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
shape_type = bpy.props.EnumProperty(items =[(i.upper(), i, '') for i in ('Bone', 'Display', 'Function')])
|
||||
shape_type = bpy.props.EnumProperty(
|
||||
items=[(i.upper(), i, "") for i in ("Bone", "Display", "Function")]
|
||||
)
|
||||
|
||||
def draw(self,context):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column()
|
||||
col.prop(self,'shape_type', expand=True)
|
||||
col.prop(self, "shape_type", expand=True)
|
||||
|
||||
def execute(self,context):
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
#print(self.shape_type)
|
||||
# print(self.shape_type)
|
||||
canvas = context.scene.rig_picker.canvas
|
||||
if canvas:
|
||||
for ob in [o for o in bpy.data.objects if o.layers==canvas.layers]:
|
||||
if ob.type in ['MESH', 'CURVE', 'FONT'] and ob.rig_picker.shape_type == self.shape_type:
|
||||
for ob in [o for o in bpy.data.objects if o.layers == canvas.layers]:
|
||||
if (
|
||||
ob.type in ["MESH", "CURVE", "FONT"]
|
||||
and ob.rig_picker.shape_type == self.shape_type
|
||||
):
|
||||
ob.select = True
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
@@ -191,10 +201,10 @@ class RP_OT_select_shape_type(Operator):
|
||||
|
||||
|
||||
class RP_OT_save_picker(Operator):
|
||||
bl_label = 'Store UI Data'
|
||||
bl_idname = 'rigpicker.save_picker'
|
||||
bl_label = "Store UI Data"
|
||||
bl_idname = "rigpicker.save_picker"
|
||||
|
||||
index : IntProperty(default=-1)
|
||||
index: IntProperty(default=-1)
|
||||
|
||||
def execute(self, context):
|
||||
scn = context.scene
|
||||
@@ -205,39 +215,51 @@ class RP_OT_save_picker(Operator):
|
||||
else:
|
||||
source = context.active_object.data.rig_picker.sources[self.index].source
|
||||
source = Path(bpy.path.abspath(source, library=ob.data.library)).resolve()
|
||||
collection = next((c for c in set(scn.collection.children_recursive) if c.rig_picker.enabled
|
||||
and Path(bpy.path.abspath(c.rig_picker.destination)).resolve() == source), None)
|
||||
|
||||
collection = next(
|
||||
(
|
||||
c
|
||||
for c in set(scn.collection.children_recursive)
|
||||
if c.rig_picker.enabled
|
||||
and Path(bpy.path.abspath(c.rig_picker.destination)).resolve()
|
||||
== source
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
if not collection:
|
||||
self.report({"ERROR"}, 'No Picker found')
|
||||
return {'CANCELLED'}
|
||||
self.report({"ERROR"}, "No Picker found")
|
||||
return {"CANCELLED"}
|
||||
|
||||
canvas = collection.rig_picker.canvas
|
||||
#rig = collection.rig_picker.rig
|
||||
shapes = [o for o in collection.all_objects if o != canvas and o.type in ('MESH', 'CURVE', 'FONT')]
|
||||
# rig = collection.rig_picker.rig
|
||||
shapes = [
|
||||
o
|
||||
for o in collection.all_objects
|
||||
if o != canvas and o.type in ("MESH", "CURVE", "FONT")
|
||||
]
|
||||
|
||||
if not canvas:
|
||||
self.report({'ERROR'}, 'Choose a Canvas')
|
||||
return {'CANCELLED'}
|
||||
|
||||
self.report({"ERROR"}, "Choose a Canvas")
|
||||
return {"CANCELLED"}
|
||||
|
||||
picker_data = get_picker_data(collection)
|
||||
|
||||
picker_path = Path(bpy.path.abspath(collection.rig_picker.destination))
|
||||
|
||||
print(f'Save Picker to {picker_path}')
|
||||
print(f"Save Picker to {picker_path}")
|
||||
picker_path.write_text(json.dumps(picker_data))
|
||||
|
||||
bpy.ops.rigpicker.reload_picker()
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
classes = (
|
||||
RP_OT_create_shape,
|
||||
RP_OT_name_from_bone,
|
||||
RP_OT_mirror_shape,
|
||||
RP_OT_select_shape_type,
|
||||
RP_OT_save_picker
|
||||
RP_OT_save_picker,
|
||||
)
|
||||
|
||||
register, unregister = bpy.utils.register_classes_factory(classes)
|
||||
register, unregister = bpy.utils.register_classes_factory(classes)
|
||||
|
||||
Reference in New Issue
Block a user