diff --git a/CHANGELOG.md b/CHANGELOG.md index ff75af8..d4684e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +1.3.2: + +- change: disable manip cam name drawing +- code: add initial support for main cam frame draw within camera view 1.3.1: diff --git a/OP_helpers.py b/OP_helpers.py index 03a014b..6b926dc 100644 --- a/OP_helpers.py +++ b/OP_helpers.py @@ -187,7 +187,7 @@ class GPTB_OT_draw_cam(bpy.types.Operator): if not drawcam: created=True drawcam = bpy.data.objects.new(dcam_name, context.scene.camera.data) - drawcam.show_name = True + # drawcam.show_name = True set_collection(drawcam, 'manip_cams') if dcam_name == 'draw_cam': diff --git a/__init__.py b/__init__.py index b85d949..1f4dabb 100644 --- a/__init__.py +++ b/__init__.py @@ -15,7 +15,7 @@ bl_info = { "name": "GP toolbox", "description": "Set of tools for Grease Pencil in animation production", "author": "Samuel Bernou", -"version": (1, 3, 1), +"version": (1, 3, 2), "blender": (2, 91, 0), "location": "sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "warning": "", @@ -47,6 +47,7 @@ from . import OP_copy_paste from . import OP_realign from . import OP_depth_move from . import OP_key_duplicate_send +from . import handler_draw_cam from . import keymaps from .OP_pseudo_tint import GPT_OT_auto_tint_gp_layers @@ -448,6 +449,7 @@ def register(): OP_realign.register() OP_depth_move.register() OP_key_duplicate_send.register() + handler_draw_cam.register() UI_tools.register() keymaps.register() bpy.types.Scene.gptoolprops = bpy.props.PointerProperty(type = GP_PG_ToolsSettings) @@ -469,6 +471,7 @@ def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls) UI_tools.unregister() + handler_draw_cam.unregister() OP_key_duplicate_send.unregister() OP_depth_move.unregister() OP_realign.unregister() diff --git a/handler_draw_cam.py b/handler_draw_cam.py new file mode 100644 index 0000000..7aa42a2 --- /dev/null +++ b/handler_draw_cam.py @@ -0,0 +1,139 @@ +import bpy +import gpu +import bgl +# import blf +from gpu_extras.batch import batch_for_shader +from bpy_extras.view3d_utils import location_3d_to_region_2d + +from bpy.app.handlers import persistent + +def view3d_camera_border(context, cam): + ## based on https://blender.stackexchange.com/questions/6377/coordinates-of-corners-of-camera-view-border + # cam = context.scene.camera + frame = cam.data.view_frame(scene=context.scene) + # to world-space + frame = [cam.matrix_world @ v for v in frame] + # to pixelspace + region, rv3d = context.region, context.space_data.region_3d + frame_px = [location_3d_to_region_2d(region, rv3d, v) for v in frame] + return frame_px + +def draw_cam_frame_callback(self, context): + if context.region_data.view_perspective != 'CAMERA': + return + if context.scene.camera.name != 'draw_cam': + return + + main_cam = context.scene.camera.parent + if not main_cam: + return + # if context.area != self._draw_area: + # return + + # green -> (0.06, 0.4, 0.040, 0.6) + # orange -> (0.45, 0.18, 0.03, 1.0) + osd_color = (0.06, 0.4, 0.040, 0.4) + + frame_point = view3d_camera_border(context, main_cam) + self.shader_2d = gpu.shader.from_builtin('2D_UNIFORM_COLOR') + self.screen_framing = batch_for_shader( + self.shader_2d, 'LINE_LOOP', {"pos": frame_point}) + + bgl.glLineWidth(1) + self.shader_2d.bind() + self.shader_2d.uniform_float("color", osd_color) + self.screen_framing.draw(self.shader_2d) + + # Reset + # bgl.glLineWidth(1) + + # # Display Text + # if self.use_osd_text: + # font_id = 0 + # dpi = context.preferences.system.dpi + # # Display current frame text + # blf.color(font_id, *osd_color) # unpack color in argument + # blf.position(font_id, context.region.width/3, 15, 0) # context.region.height- + # blf.size(font_id, 16, dpi) + # blf.draw(font_id, f'Draw cam') + + +## As a modal for tests +class GPTB_OT_cam_frame_draw(bpy.types.Operator): + bl_idname = "gp.draw_cam_frame" + bl_label = "Draw Cam Frame" + bl_description = "Draw the camera frame using a modal" + bl_options = {"REGISTER"} # , "INTERNAL" + + # @classmethod + # def poll(cls, context): + # return True + + def invoke(self, context, event): + ## screen color frame + # r = bpy.context.region + # w = r.width + # h = r.height + + # self.shader_2d = gpu.shader.from_builtin('2D_UNIFORM_COLOR') + # self.screen_framing = batch_for_shader( + # self.shader_2d, 'LINE_LOOP', {"pos": [(0,0), (0,h), (w,h), (w,0)]}) + + ## OpenGL handler + self._draw_area = context.area + args = (self, context) + self._handle = bpy.types.SpaceView3D.draw_handler_add( + draw_cam_frame_callback, args, "WINDOW", "POST_PIXEL") + + context.window_manager.modal_handler_add(self) + return {'RUNNING_MODAL'} + + + def exit(self, context): + bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') + context.area.tag_redraw() + + def modal(self, context, event): + if event.type in {'ESC'}: + self.exit(context) + return {"CANCELLED"} + return {'PASS_THROUGH'} + # return {'RUNNING_MODAL'} + + +class DrawClass: + def __init__(self, context): + # print("INIT") + self._handle = bpy.types.SpaceView3D.draw_handler_add( + draw_cam_frame_callback, args, "WINDOW", "POST_PIXEL") + + def remove_handle(self): + bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') + + +### --- REGISTER --- + +def register(): + if not bpy.app.background: + bpy.utils.register_class(GPTB_OT_cam_frame_draw) + + # ha = DrawClass() + + # _handle = bpy.types.SpaceView3D.draw_handler_add( + # draw_cam_frame_callback, args, "WINDOW", "POST_PIXEL") + +def unregister(): + if not bpy.app.background: + bpy.utils.unregister_class(GPTB_OT_cam_frame_draw) + + # ha.remove_handle() + + # bpy.types.SpaceView3D.draw_handler_remove(_handle, 'WINDOW') + + + # if 'draw_cam_frame_callback' in [hand.__name__ for hand in bpy.app.handlers.save_pre]: + # bpy.app.handlers.save_pre.remove(remap_relative) + + +if __name__ == "__main__": + register() \ No newline at end of file