Draw cam passepartout and UI changes
parent
2754ebf89b
commit
d8f71e3356
|
@ -1,5 +1,14 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
|
||||||
|
1.4.0
|
||||||
|
|
||||||
|
- feat: Passepartout displayed in main cam (permanent draw handler)
|
||||||
|
- UI: add Straight stroke operator button in Toolbox if GP tools official addon is on
|
||||||
|
- UI: placed Toolbox Playblast in a subpanel
|
||||||
|
- UI: removed Onion skin and Autolock layer checkbox (not often used)
|
||||||
|
- UI: sent rarely `cursor follow` to bottom of the panel
|
||||||
|
|
||||||
1.3.3
|
1.3.3
|
||||||
|
|
||||||
- feat: show main cam frame when in draw_cam
|
- feat: show main cam frame when in draw_cam
|
||||||
|
|
|
@ -153,10 +153,11 @@ class GPTB_OT_draw_cam(bpy.types.Operator):
|
||||||
# get main cam and error if not available
|
# get main cam and error if not available
|
||||||
if drawcam.name == 'draw_cam':
|
if drawcam.name == 'draw_cam':
|
||||||
maincam = drawcam.parent
|
maincam = drawcam.parent
|
||||||
|
maincam.data.show_passepartout = context.scene.gptoolprops.drawcam_passepartout
|
||||||
|
|
||||||
else:
|
else:
|
||||||
maincam = None
|
maincam = None
|
||||||
main_name = drawcam.get('maincam_name')# Custom prop with previous avtive cam.
|
main_name = drawcam.get('maincam_name')# Custom prop with previous active cam.
|
||||||
if main_name:
|
if main_name:
|
||||||
maincam = context.scene.objects.get(main_name)
|
maincam = context.scene.objects.get(main_name)
|
||||||
|
|
||||||
|
@ -187,14 +188,17 @@ class GPTB_OT_draw_cam(bpy.types.Operator):
|
||||||
if not drawcam:
|
if not drawcam:
|
||||||
created=True
|
created=True
|
||||||
drawcam = bpy.data.objects.new(dcam_name, context.scene.camera.data)
|
drawcam = bpy.data.objects.new(dcam_name, context.scene.camera.data)
|
||||||
# drawcam.show_name = True
|
|
||||||
set_collection(drawcam, 'manip_cams')
|
set_collection(drawcam, 'manip_cams')
|
||||||
|
|
||||||
if dcam_name == 'draw_cam':
|
if dcam_name == 'draw_cam':
|
||||||
drawcam.parent = maincam
|
drawcam.parent = maincam
|
||||||
if created:#set to main at creation time
|
if created: # set to main at creation time
|
||||||
drawcam.matrix_world = maincam.matrix_world
|
drawcam.matrix_world = maincam.matrix_world
|
||||||
drawcam.lock_location = (True,True,True)
|
drawcam.lock_location = (True,True,True)
|
||||||
|
# drawcam.hide_viewport = True
|
||||||
|
context.scene.gptoolprops.drawcam_passepartout = maincam.data.show_passepartout
|
||||||
|
maincam.data.show_passepartout = False
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if created:
|
if created:
|
||||||
|
@ -226,7 +230,7 @@ class GPTB_OT_draw_cam(bpy.types.Operator):
|
||||||
drawcam.hide_viewport = False
|
drawcam.hide_viewport = False
|
||||||
maincam.hide_viewport = True
|
maincam.hide_viewport = True
|
||||||
|
|
||||||
if created and drawcam.name == 'obj_cam':#Go in camera view
|
if created and drawcam.name == 'obj_cam': # Go in camera view
|
||||||
context.region_data.view_perspective = 'CAMERA'
|
context.region_data.view_perspective = 'CAMERA'
|
||||||
# ## make active
|
# ## make active
|
||||||
# bpy.context.view_layer.objects.active = ob
|
# bpy.context.view_layer.objects.active = ob
|
||||||
|
|
73
UI_tools.py
73
UI_tools.py
|
@ -81,10 +81,13 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel):
|
||||||
if context.scene.camera:
|
if context.scene.camera:
|
||||||
row = layout.row(align=True)# .split(factor=0.5)
|
row = layout.row(align=True)# .split(factor=0.5)
|
||||||
row.label(text='Passepartout')
|
row.label(text='Passepartout')
|
||||||
row.prop(context.scene.camera.data, 'show_passepartout',text='', icon ='OBJECT_HIDDEN' )
|
if context.scene.camera.name == 'draw_cam':
|
||||||
|
row.prop(context.scene.gptoolprops, 'drawcam_passepartout', text='', icon ='OBJECT_HIDDEN')
|
||||||
|
else:
|
||||||
|
row.prop(context.scene.camera.data, 'show_passepartout', text='', icon ='OBJECT_HIDDEN')
|
||||||
row.prop(context.scene.camera.data, 'passepartout_alpha', text='')
|
row.prop(context.scene.camera.data, 'passepartout_alpha', text='')
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator('view3d.zoom_camera_1_to_1', text = 'Zoom 1:1', icon = 'ZOOM_PREVIOUS')# FULLSCREEN_EXIT
|
row.operator('view3d.zoom_camera_1_to_1', text = 'Zoom 1:1', icon = 'ZOOM_PREVIOUS') # FULLSCREEN_EXIT
|
||||||
row.operator('view3d.view_center_camera', text = 'Zoom fit', icon = 'FULLSCREEN_ENTER')
|
row.operator('view3d.view_center_camera', text = 'Zoom fit', icon = 'FULLSCREEN_ENTER')
|
||||||
|
|
||||||
## background images/videos
|
## background images/videos
|
||||||
|
@ -112,23 +115,15 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel):
|
||||||
# row.label(icon='FILE_MOVIE')
|
# row.label(icon='FILE_MOVIE')
|
||||||
# icon = 'HIDE_OFF' if bg_img.show_background_image else 'HIDE_ON'
|
# icon = 'HIDE_OFF' if bg_img.show_background_image else 'HIDE_ON'
|
||||||
# row.prop(bg_img, 'show_background_image', text='', icon=icon)
|
# row.prop(bg_img, 'show_background_image', text='', icon=icon)
|
||||||
|
|
||||||
## playblast params
|
|
||||||
layout.separator()
|
|
||||||
layout.label(text = 'Playblast:')
|
|
||||||
row = layout.row(align=False)#split(factor=0.6)
|
|
||||||
row.label(text = f'{rd.resolution_x * context.scene.gptoolprops.resolution_percentage // 100} x {rd.resolution_y * context.scene.gptoolprops.resolution_percentage // 100}')
|
|
||||||
row.prop(context.scene.gptoolprops, 'resolution_percentage', text='')
|
|
||||||
# row.prop(rd, 'resolution_percentage', text='')#real percent scene percentage
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator('render.thread_playblast', text = 'Playblast', icon = 'RENDER_ANIMATION')# non blocking background render playblast
|
|
||||||
# row.operator('render.playblast_anim', text = 'Playblast', icon = 'RENDER_ANIMATION').use_view = False # old (but robust) blocking playblast
|
|
||||||
row.operator('render.playblast_anim', text = 'Viewport').use_view = True
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
layout.label(text='No camera !', icon = 'ERROR')
|
layout.label(text='No camera !', icon = 'ERROR')
|
||||||
|
|
||||||
|
## Straight line ops from official greasepencil_tools addon if enabled.
|
||||||
|
# if any(x in context.preferences.addons.keys() for x in ('greasepencil_tools', 'greasepencil-addon')): # check enabled addons
|
||||||
|
if hasattr(bpy.types, bpy.ops.gp.straight_stroke.idname()): # check if operator exists
|
||||||
|
layout.operator('gp.straight_stroke', icon ="CURVE_PATH")
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.label(text = 'Options:')
|
layout.label(text = 'Options:')
|
||||||
|
@ -136,18 +131,12 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel):
|
||||||
## Kf Jump filter
|
## Kf Jump filter
|
||||||
layout.prop(context.scene.gptoolprops, 'keyframe_type', text='Jump On') # Keyframe Jump
|
layout.prop(context.scene.gptoolprops, 'keyframe_type', text='Jump On') # Keyframe Jump
|
||||||
|
|
||||||
# row = layout.row(align=False)
|
|
||||||
## maybe remove cursor_follow icon that look like
|
|
||||||
text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR')
|
|
||||||
|
|
||||||
layout.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon)
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.prop(context.space_data.overlay, 'use_gpencil_onion_skin')
|
# col.prop(context.space_data.overlay, 'use_gpencil_onion_skin') # not often used
|
||||||
|
|
||||||
|
|
||||||
if context.object and context.object.type == 'GPENCIL':
|
if context.object and context.object.type == 'GPENCIL':
|
||||||
col.prop(context.object.data, 'use_autolock_layers')
|
# col.prop(context.object.data, 'use_autolock_layers') # not often used
|
||||||
col.prop(context.object, 'show_in_front', text='X-ray')#default text "In Front"
|
col.prop(context.object, 'show_in_front', text='X-ray') # default text "In Front"
|
||||||
|
|
||||||
## rename datablock temporary layout
|
## rename datablock temporary layout
|
||||||
if context.object.name != context.object.data.name:
|
if context.object.name != context.object.data.name:
|
||||||
|
@ -184,6 +173,9 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel):
|
||||||
row.operator('gp.file_checker', text = 'Check file', icon = 'SCENE_DATA')
|
row.operator('gp.file_checker', text = 'Check file', icon = 'SCENE_DATA')
|
||||||
row.operator('gp.links_checker', text = 'Check links', icon = 'UNLINKED')
|
row.operator('gp.links_checker', text = 'Check links', icon = 'UNLINKED')
|
||||||
|
|
||||||
|
text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR')
|
||||||
|
col.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon)
|
||||||
|
|
||||||
# Mention update as notice
|
# Mention update as notice
|
||||||
addon_updater_ops.update_notice_box_ui(self, context)
|
addon_updater_ops.update_notice_box_ui(self, context)
|
||||||
|
|
||||||
|
@ -235,6 +227,28 @@ class GPTB_PT_anim_manager(bpy.types.Panel):
|
||||||
ops.skip_obj = True
|
ops.skip_obj = True
|
||||||
ops.mute = True
|
ops.mute = True
|
||||||
|
|
||||||
|
class GPTB_PT_toolbox_playblast(bpy.types.Panel):
|
||||||
|
bl_label = "Playblast"
|
||||||
|
bl_space_type = "VIEW_3D"
|
||||||
|
bl_region_type = "UI"
|
||||||
|
bl_category = "Gpencil"
|
||||||
|
bl_parent_id = "GPTB_PT_sidebar_panel"
|
||||||
|
bl_options = {'DEFAULT_CLOSED'}
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
rd = context.scene.render
|
||||||
|
row = layout.row(align=False) # split(factor=0.6)
|
||||||
|
percent = context.scene.gptoolprops.resolution_percentage
|
||||||
|
row.label(text = f'{rd.resolution_x * percent // 100} x {rd.resolution_y * percent // 100}')
|
||||||
|
row.prop(context.scene.gptoolprops, 'resolution_percentage', text='')
|
||||||
|
# row.prop(rd, 'resolution_percentage', text='') # real percent scene percentage
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator('render.thread_playblast', text = 'Playblast', icon = 'RENDER_ANIMATION')# non blocking background render playblast
|
||||||
|
# row.operator('render.playblast_anim', text = 'Playblast', icon = 'RENDER_ANIMATION').use_view = False # old (but robust) blocking playblast
|
||||||
|
row.operator('render.playblast_anim', text = 'Viewport').use_view = True
|
||||||
|
|
||||||
class GPTB_PT_tint_layers(bpy.types.Panel):
|
class GPTB_PT_tint_layers(bpy.types.Panel):
|
||||||
bl_label = "Tint layers"
|
bl_label = "Tint layers"
|
||||||
bl_space_type = "VIEW_3D"
|
bl_space_type = "VIEW_3D"
|
||||||
|
@ -293,8 +307,7 @@ class GPTB_PT_render(bpy.types.Panel):
|
||||||
blend = Path(bpy.data.filepath)
|
blend = Path(bpy.data.filepath)
|
||||||
out = blend.parents[1] / "compo" / "base"
|
out = blend.parents[1] / "compo" / "base"
|
||||||
layout.operator("wm.path_open", text='Open render folder', icon='FILE_FOLDER').filepath = str(out)
|
layout.operator("wm.path_open", text='Open render folder', icon='FILE_FOLDER').filepath = str(out)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -343,6 +356,7 @@ def palette_manager_menu(self, context):
|
||||||
classes = (
|
classes = (
|
||||||
GPTB_PT_sidebar_panel,
|
GPTB_PT_sidebar_panel,
|
||||||
GPTB_PT_anim_manager,
|
GPTB_PT_anim_manager,
|
||||||
|
GPTB_PT_toolbox_playblast,
|
||||||
GPTB_PT_tint_layers,
|
GPTB_PT_tint_layers,
|
||||||
GPTB_PT_render,
|
GPTB_PT_render,
|
||||||
## GPTB_PT_cam_ref_panel,
|
## GPTB_PT_cam_ref_panel,
|
||||||
|
@ -403,8 +417,5 @@ def GPdata_toolbox_panel(self, context):
|
||||||
row.label("Extra tools")
|
row.label("Extra tools")
|
||||||
|
|
||||||
if settings.extra_tools :
|
if settings.extra_tools :
|
||||||
layout.operator_menu_enum("gpencil.stroke_arrange", text="Arrange Strokes...", property="direction") """
|
layout.operator_menu_enum("gpencil.stroke_arrange", text="Arrange Strokes...", property="direction")
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ bl_info = {
|
||||||
"name": "GP toolbox",
|
"name": "GP toolbox",
|
||||||
"description": "Set of tools for Grease Pencil in animation production",
|
"description": "Set of tools for Grease Pencil in animation production",
|
||||||
"author": "Samuel Bernou",
|
"author": "Samuel Bernou",
|
||||||
"version": (1, 3, 3),
|
"version": (1, 4, 0),
|
||||||
"blender": (2, 91, 0),
|
"blender": (2, 91, 0),
|
||||||
"location": "sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
"doc_url": "https://gitlab.com/autour-de-minuit/blender/gp_toolbox",
|
"doc_url": "https://gitlab.com/autour-de-minuit/blender/gp_toolbox",
|
||||||
"tracker_url": "https://gitlab.com/autour-de-minuit/blender/gp_toolbox/-/issues",
|
"tracker_url": "https://gitlab.com/autour-de-minuit/blender/gp_toolbox/-/issues",
|
||||||
|
|
|
@ -6,201 +6,6 @@ from gpu_extras.batch import batch_for_shader
|
||||||
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
||||||
|
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
from bpy.types import GizmoGroup, Gizmo
|
|
||||||
|
|
||||||
|
|
||||||
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'}
|
|
||||||
|
|
||||||
|
|
||||||
# GIZMO method
|
|
||||||
'''
|
|
||||||
class CameraFrameWidget(Gizmo):
|
|
||||||
bl_idname = "VIEW3D_GT_CAM"
|
|
||||||
# bl_target_properties = (
|
|
||||||
# {"id": "offset", "type": 'FLOAT', "array_length": 1},
|
|
||||||
# )
|
|
||||||
|
|
||||||
# __slots__ = (
|
|
||||||
# "custom_shape",
|
|
||||||
# "init_mouse_y",
|
|
||||||
# "init_value",
|
|
||||||
# )
|
|
||||||
|
|
||||||
# def _update_offset_matrix(self):
|
|
||||||
# # offset behind the light
|
|
||||||
# self.matrix_offset.col[3][2] = self.target_get_value("offset") / -10.0
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
# self._update_offset_matrix()
|
|
||||||
# self.draw_custom_shape(self.custom_shape)
|
|
||||||
osd_color = (0.06, 0.4, 0.040, 0.4)
|
|
||||||
|
|
||||||
frame_point = view3d_camera_border_3d(context, context.scene.camera.parent)
|
|
||||||
self.shader_2d = gpu.shader.from_builtin('3D_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)
|
|
||||||
|
|
||||||
# def draw_select(self, context, select_id):
|
|
||||||
# self._update_offset_matrix()
|
|
||||||
# self.draw_custom_shape(self.custom_shape, select_id=select_id)
|
|
||||||
|
|
||||||
# def setup(self):
|
|
||||||
# if not hasattr(self, "custom_shape"):
|
|
||||||
# self.custom_shape = self.new_custom_shape('LINE_LOOP', custom_shape_verts)
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
# self.init_mouse_y = event.mouse_y
|
|
||||||
# self.init_value = self.target_get_value("offset")
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
def exit(self, context, cancel):
|
|
||||||
context.area.header_text_set(None)
|
|
||||||
# if cancel:
|
|
||||||
# self.target_set_value("offset", self.init_value)
|
|
||||||
|
|
||||||
def modal(self, context, event, tweak):
|
|
||||||
# context.area.header_text_set("My Gizmo: %.4f" % value)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
class CameraFrameWidgetGroup(GizmoGroup):
|
|
||||||
bl_idname = "OBJECT_GGT_light_test"
|
|
||||||
bl_label = "Test Light Widget"
|
|
||||||
bl_space_type = 'VIEW_3D'
|
|
||||||
bl_region_type = 'WINDOW'
|
|
||||||
bl_options = {'3D', 'PERSISTENT'}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
# if context.region_data.view_perspective != 'CAMERA':
|
|
||||||
# return
|
|
||||||
# if context.scene.camera.name != 'draw_cam':
|
|
||||||
# return
|
|
||||||
# if not context.scene.camera.parent:
|
|
||||||
# return
|
|
||||||
# return True
|
|
||||||
return context.region_data.view_perspective == 'CAMERA' and context.scene.camera.name == 'draw_cam' and context.scene.camera.parent
|
|
||||||
|
|
||||||
def setup(self, context):
|
|
||||||
# Assign the 'offset' target property to the light energy.
|
|
||||||
ob = context.object
|
|
||||||
gz = self.gizmos.new(CameraFrameWidget.bl_idname)
|
|
||||||
print('In setup')
|
|
||||||
# gz.target_set_prop("offset", ob.data, "energy")
|
|
||||||
|
|
||||||
# gz.color = 1.0, 0.5, 1.0
|
|
||||||
# gz.alpha = 0.5
|
|
||||||
|
|
||||||
# gz.color_highlight = 1.0, 1.0, 1.0
|
|
||||||
# gz.alpha_highlight = 0.5
|
|
||||||
|
|
||||||
# units are large, so shrink to something more reasonable.
|
|
||||||
# gz.scale_basis = 0.1
|
|
||||||
gz.use_draw_modal = True
|
|
||||||
|
|
||||||
|
|
||||||
def refresh(self, context):
|
|
||||||
ob = context.object0
|
|
||||||
# gz = self.energy_gizmo
|
|
||||||
# gz.matrix_basis = ob.matrix_world.normalized()
|
|
||||||
|
|
||||||
'''
|
|
||||||
# USED 0CODE
|
|
||||||
|
|
||||||
|
|
||||||
def extrapolate_points_by_length(a, b, length):
|
def extrapolate_points_by_length(a, b, length):
|
||||||
|
@ -214,123 +19,152 @@ def extrapolate_points_by_length(a, b, length):
|
||||||
return None
|
return None
|
||||||
return b + (ab.normalized() * length)
|
return b + (ab.normalized() * length)
|
||||||
|
|
||||||
|
def view3d_camera_border_2d(context, cam):
|
||||||
def view3d_camera_border_3d(context, cam):
|
# based on https://blender.stackexchange.com/questions/6377/coordinates-of-corners-of-camera-view-border
|
||||||
'''Return frame border as 3D coordinate'''
|
# cam = context.scene.camera
|
||||||
frame = cam.data.view_frame(scene=context.scene)
|
frame = cam.data.view_frame(scene=context.scene)
|
||||||
|
# to world-space
|
||||||
frame = [cam.matrix_world @ v for v in frame]
|
frame = [cam.matrix_world @ v for v in frame]
|
||||||
return 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_2d():
|
||||||
|
context = bpy.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
|
||||||
|
|
||||||
|
bgl.glEnable(bgl.GL_BLEND)
|
||||||
|
|
||||||
|
frame_point = view3d_camera_border_2d(
|
||||||
|
context, context.scene.camera.parent)
|
||||||
|
shader_2d = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
|
||||||
|
|
||||||
|
if context.scene.gptoolprops.drawcam_passepartout:
|
||||||
|
### PASSEPARTOUT
|
||||||
|
|
||||||
|
# frame positions
|
||||||
|
#
|
||||||
|
# lupext lup rup rupext
|
||||||
|
# D-----A
|
||||||
|
# | |
|
||||||
|
# C-----B
|
||||||
|
# ldnext ldn rdn lnext
|
||||||
|
|
||||||
|
a = frame_point[0]
|
||||||
|
b = frame_point[1]
|
||||||
|
c = frame_point[2]
|
||||||
|
d = frame_point[3]
|
||||||
|
|
||||||
|
ext = 1000
|
||||||
|
rup = extrapolate_points_by_length(b,a, ext)
|
||||||
|
rdn = extrapolate_points_by_length(a,b, ext)
|
||||||
|
rupext = rup + ((a-d).normalized() * ext)
|
||||||
|
rdnext = rdn + ((a-d).normalized() * ext)
|
||||||
|
lup = extrapolate_points_by_length(c,d, ext)
|
||||||
|
ldn = extrapolate_points_by_length(d,c, ext)
|
||||||
|
lupext = lup + ((c-b).normalized() * ext)
|
||||||
|
ldnext = ldn + ((c-b).normalized() * ext)
|
||||||
|
|
||||||
|
|
||||||
class CameraFrameWidget(Gizmo):
|
# ppp_color = (1.0, 1.0, 0.0, 1)
|
||||||
bl_idname = "VIEW3D_GT_CAM"
|
ppp_color = (0.0, 0.0, 0.0, context.scene.camera.data.passepartout_alpha)
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
# 3D0 draw
|
|
||||||
osd_color = (0.06, 0.4, 0.040, 0.4)
|
|
||||||
|
|
||||||
frame_point = view3d_camera_border_3d(
|
|
||||||
context, context.scene.camera.parent)
|
|
||||||
self.shader_2d = gpu.shader.from_builtin('3D_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)
|
|
||||||
|
|
||||||
# WIP -> custom passepartout
|
|
||||||
|
|
||||||
|
rect = [rup, rdn, rupext, rdnext,
|
||||||
|
lup, ldn, lupext, ldnext,
|
||||||
|
a, b, c, d]
|
||||||
|
|
||||||
## frame positions
|
## convert to 2d
|
||||||
# D-----A
|
# region, rv3d = context.region, context.space_data.region_3d
|
||||||
# | |
|
# rect = [location_3d_to_region_2d(region, rv3d, v) for v in rect]
|
||||||
# C-----B
|
|
||||||
|
|
||||||
# a = frame_point[0]
|
# lupext=6 lup=4 rup=0 rupext=2
|
||||||
# b = frame_point[1]
|
# d=11, a=8
|
||||||
# c = frame_point[2]
|
# c=10, b=9
|
||||||
# d = frame_point[3]
|
# ldnext=7 ldn=5 rdn=1 dnpext=3
|
||||||
|
|
||||||
|
indices = [(0,1,2), (1,2,3),
|
||||||
|
(4,5,6), (5,6,7),
|
||||||
|
(8,11,4), (8,4,0),
|
||||||
|
(10,9,5), (9,5,1),
|
||||||
|
]
|
||||||
|
|
||||||
# ext = 0.2
|
# ### passpartout_points
|
||||||
# rup = extrapolate_points_by_length(a,b, ext)
|
|
||||||
# rdn = extrapolate_points_by_length(b,a, ext)
|
|
||||||
|
|
||||||
# rupext = rup + ((a-c).normalized() * ext)
|
passepartout = batch_for_shader(
|
||||||
# rdnext = rdn + ((a-c).normalized() * ext)
|
shader_2d, 'TRIS', {"pos": rect}, indices=indices)
|
||||||
|
# shader_2d, 'LINE_LOOP', {"pos": rect})
|
||||||
|
|
||||||
|
shader_2d.bind()
|
||||||
|
shader_2d.uniform_float("color", ppp_color)
|
||||||
|
passepartout.draw(shader_2d)
|
||||||
|
|
||||||
|
|
||||||
|
### Camera framing trace over
|
||||||
|
|
||||||
|
bgl.glLineWidth(1)
|
||||||
|
bgl.glEnable(bgl.GL_LINE_SMOOTH)
|
||||||
|
|
||||||
|
"""
|
||||||
|
## need to accurately detect viewport background color (difficult)
|
||||||
|
### COUNTER CURRENT FRAMING
|
||||||
|
if False:
|
||||||
|
camf = view3d_camera_border_2d(
|
||||||
|
context, context.scene.camera)
|
||||||
|
ca = (camf[0].x + 1, camf[0].y + 1)
|
||||||
|
cb = (camf[1].x + 1, camf[1].y - 1)
|
||||||
|
cc = (camf[2].x - 1, camf[2].y - 1)
|
||||||
|
cd = (camf[3].x - 1, camf[3].y + 1)
|
||||||
|
screen_framing = batch_for_shader(
|
||||||
|
shader_2d, 'LINE_LOOP', {"pos": [ca, cb, cc, cd]})
|
||||||
|
shader_2d.bind()
|
||||||
|
shader_2d.uniform_float("color", (0.25, 0.25, 0.25, 1.0))
|
||||||
|
# shader_2d.uniform_float("color", (0.9, 0.9, 0.9, 1.0))
|
||||||
|
screen_framing.draw(shader_2d)
|
||||||
|
"""
|
||||||
|
### FRAMING
|
||||||
|
|
||||||
|
# frame_color = (0.06, 0.4, 0.040, 0.5)
|
||||||
|
frame_color = (0.0, 0.0, 0.25, 1.0)
|
||||||
|
|
||||||
|
screen_framing = batch_for_shader(
|
||||||
|
shader_2d, 'LINE_LOOP', {"pos": frame_point})
|
||||||
|
|
||||||
|
shader_2d.bind()
|
||||||
|
shader_2d.uniform_float("color", frame_color)
|
||||||
|
screen_framing.draw(shader_2d)
|
||||||
|
|
||||||
|
# bgl.glLineWidth(1)
|
||||||
|
bgl.glDisable(bgl.GL_LINE_SMOOTH)
|
||||||
|
bgl.glDisable(bgl.GL_BLEND)
|
||||||
|
|
||||||
|
|
||||||
# rect = [rup, rdn, rupext, rdnext]
|
draw_handle = None
|
||||||
|
|
||||||
# ### passpartout_points = []
|
|
||||||
# self.passepartout = batch_for_shader(
|
|
||||||
# self.shader_2d, 'TRI_FAN', {"pos": rect}) # TRIS
|
|
||||||
|
|
||||||
# self.shader_2d.bind()
|
|
||||||
# self.shader_2d.uniform_float("color", osd_color)
|
|
||||||
# self.passepartout.draw(self.shader_2d)
|
|
||||||
|
|
||||||
# def invoke(self, context, event):
|
|
||||||
# return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
# def exit(self, context, cancel):
|
|
||||||
# # context.area.header_text_set(None)
|
|
||||||
# return
|
|
||||||
|
|
||||||
# def modal(self, context, event, tweak):
|
|
||||||
# return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
class CameraFrameWidgetGroup(GizmoGroup):
|
|
||||||
bl_idname = "OBJECT_GGT_light_test"
|
|
||||||
bl_label = "Test Light Widget"
|
|
||||||
bl_space_type = 'VIEW_3D'
|
|
||||||
bl_region_type = 'WINDOW'
|
|
||||||
bl_options = {'3D', 'PERSISTENT'}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
return context.region_data.view_perspective == 'CAMERA' and context.scene.camera.name == 'draw_cam' and context.scene.camera.parent
|
|
||||||
|
|
||||||
def setup(self, context):
|
|
||||||
gz = self.gizmos.new(CameraFrameWidget.bl_idname)
|
|
||||||
|
|
||||||
|
|
||||||
# --- REGISTER ---
|
|
||||||
|
|
||||||
|
|
||||||
classes = (
|
|
||||||
# GPTB_OT_cam_frame_draw,
|
|
||||||
CameraFrameWidget,
|
|
||||||
CameraFrameWidgetGroup,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
if not bpy.app.background:
|
if bpy.app.background:
|
||||||
for cls in classes:
|
return
|
||||||
bpy.utils.register_class(cls)
|
|
||||||
|
|
||||||
# ha = DrawClass()
|
global draw_handle
|
||||||
|
draw_handle = bpy.types.SpaceView3D.draw_handler_add(
|
||||||
|
draw_cam_frame_callback_2d, (), "WINDOW", "POST_PIXEL")
|
||||||
|
|
||||||
# _handle = bpy.types.SpaceView3D.draw_handler_add(
|
|
||||||
# draw_cam_frame_callback, args, "WINDOW", "POST_PIXEL")
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
if not bpy.app.background:
|
if bpy.app.background:
|
||||||
for cls in classes:
|
return
|
||||||
bpy.utils.unregister_class(cls)
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
|
global draw_handle
|
||||||
|
if draw_handle:
|
||||||
|
bpy.types.SpaceView3D.draw_handler_remove(draw_handle, 'WINDOW')
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
register()
|
register()
|
||||||
|
|
|
@ -10,15 +10,18 @@ from bpy.props import (
|
||||||
from .OP_cursor_snap_canvas import cursor_follow_update
|
from .OP_cursor_snap_canvas import cursor_follow_update
|
||||||
|
|
||||||
def change_edit_lines_opacity(self, context):
|
def change_edit_lines_opacity(self, context):
|
||||||
# for o in context.scene.objects:
|
|
||||||
# if o.type != 'GPENCIL':
|
|
||||||
# continue
|
|
||||||
# o.data.edit_line_color[3]=self.edit_lines_opacity
|
|
||||||
for gp in bpy.data.grease_pencils:
|
for gp in bpy.data.grease_pencils:
|
||||||
if not gp.is_annotation:
|
if not gp.is_annotation:
|
||||||
gp.edit_line_color[3]=self.edit_lines_opacity
|
gp.edit_line_color[3]=self.edit_lines_opacity
|
||||||
|
|
||||||
class GP_PG_ToolsSettings(bpy.types.PropertyGroup) :
|
class GP_PG_ToolsSettings(bpy.types.PropertyGroup) :
|
||||||
|
|
||||||
|
drawcam_passepartout : BoolProperty(
|
||||||
|
name="Show cam passepartout",
|
||||||
|
description="Show a darkened overlay outside image area in Camera view",
|
||||||
|
default=True,
|
||||||
|
options={'HIDDEN'})
|
||||||
|
|
||||||
autotint_offset : IntProperty(
|
autotint_offset : IntProperty(
|
||||||
name="Tint hue offset", description="offset the tint by this value for better color",
|
name="Tint hue offset", description="offset the tint by this value for better color",
|
||||||
default=0, min=-5000, max=5000, soft_min=-999, soft_max=999, step=1,
|
default=0, min=-5000, max=5000, soft_min=-999, soft_max=999, step=1,
|
||||||
|
@ -38,7 +41,8 @@ class GP_PG_ToolsSettings(bpy.types.PropertyGroup) :
|
||||||
default=False, update=cursor_follow_update)
|
default=False, update=cursor_follow_update)
|
||||||
|
|
||||||
edit_lines_opacity : FloatProperty(
|
edit_lines_opacity : FloatProperty(
|
||||||
name="edit lines Opacity", description="Change edit lines opacity for all grease pencils", default=0.5, min=0.0, max=1.0, step=3, precision=2, update=change_edit_lines_opacity)#, get=None, set=None
|
name="edit lines Opacity", description="Change edit lines opacity for all grease pencils",
|
||||||
|
default=0.5, min=0.0, max=1.0, step=3, precision=2, update=change_edit_lines_opacity)
|
||||||
|
|
||||||
## render
|
## render
|
||||||
name_for_current_render : StringProperty(
|
name_for_current_render : StringProperty(
|
||||||
|
|
Loading…
Reference in New Issue