GPencil Tools: Canvas rotate improvement
In camera view : New rotate canvas pivot mode from view center instead of camera center (enabled by default). Fix rotate canvas precision in free navigation. Also now compatible with region overlap toggled off.
This commit is contained in:
parent
046114b96a
commit
81b348c452
|
@ -21,7 +21,7 @@ bl_info = {
|
|||
"name": "Grease Pencil Tools",
|
||||
"description": "Extra tools for Grease Pencil",
|
||||
"author": "Samuel Bernou, Antonio Vazquez, Daniel Martinez Lara, Matias Mendiola",
|
||||
"version": (1, 4, 3),
|
||||
"version": (1, 5, 0),
|
||||
"blender": (2, 91, 0),
|
||||
"location": "Sidebar > Grease Pencil > Grease Pencil Tools",
|
||||
"warning": "",
|
||||
|
|
|
@ -89,6 +89,11 @@ class GreasePencilAddonPrefs(bpy.types.AddonPreferences):
|
|||
name = "Use Hud",
|
||||
description = "Display angle lines and angle value as text on viewport",
|
||||
default = False)
|
||||
|
||||
canvas_use_view_center: BoolProperty(
|
||||
name = "Rotate From View Center In Camera",
|
||||
description = "Rotate from view center in camera view, Else rotate from camera center",
|
||||
default = True)
|
||||
|
||||
## Canvas rotate
|
||||
canvas_use_shortcut: BoolProperty(
|
||||
|
@ -197,6 +202,7 @@ class GreasePencilAddonPrefs(bpy.types.AddonPreferences):
|
|||
else:
|
||||
box.label(text="No hotkey has been set automatically. Following operators needs to be set manually:", icon="ERROR")
|
||||
box.label(text="view3d.rotate_canvas")
|
||||
box.prop(self, 'canvas_use_view_center')
|
||||
box.prop(self, 'canvas_use_hud')
|
||||
|
||||
## SCRUB TIMELINE
|
||||
|
|
|
@ -43,6 +43,15 @@ def draw_callback_px(self, context):
|
|||
shader.uniform_float("color", (0.3, 0.7, 0.2, 0.5))
|
||||
batch.draw(shader)
|
||||
|
||||
## debug lines
|
||||
# batch = batch_for_shader(shader, 'LINES', {"pos": [
|
||||
# (0,0), (context.area.width, context.area.height),
|
||||
# (context.area.width, 0), (0, context.area.height)
|
||||
# ]})
|
||||
# shader.bind()
|
||||
# shader.uniform_float("color", (0.8, 0.1, 0.1, 0.5))
|
||||
# batch.draw(shader)
|
||||
|
||||
# restore opengl defaults
|
||||
bgl.glLineWidth(1)
|
||||
bgl.glDisable(bgl.GL_BLEND)
|
||||
|
@ -111,7 +120,26 @@ class RC_OT_RotateCanvas(bpy.types.Operator):
|
|||
self.cam.matrix_world = self.cam_matrix
|
||||
self.cam.rotation_euler.rotate_axis("Z", self.angle)
|
||||
|
||||
else:#free view
|
||||
if self.use_view_center:
|
||||
## apply inverse of the rotation on view offset in cam rotate from view center
|
||||
neg = -self.angle
|
||||
rot_mat2d = mathutils.Matrix([[math.cos(neg), -math.sin(neg)], [math.sin(neg), math.cos(neg)]])
|
||||
|
||||
# scale_mat = mathutils.Matrix([[1.0, 0.0], [0.0, self.ratio]])
|
||||
new_cam_offset = self.view_cam_offset.copy()
|
||||
|
||||
## area deformation correction
|
||||
new_cam_offset = mathutils.Vector((new_cam_offset[0], new_cam_offset[1] * self.ratio))
|
||||
|
||||
## rotate by matrix
|
||||
new_cam_offset.rotate(rot_mat2d)
|
||||
|
||||
## area deformation restore
|
||||
new_cam_offset = mathutils.Vector((new_cam_offset[0], new_cam_offset[1] * self.ratio_inv))
|
||||
|
||||
context.space_data.region_3d.view_camera_offset = new_cam_offset
|
||||
|
||||
else: # free view
|
||||
context.space_data.region_3d.view_rotation = self._rotation
|
||||
rot = context.space_data.region_3d.view_rotation
|
||||
rot = rot.to_euler()
|
||||
|
@ -139,20 +167,38 @@ class RC_OT_RotateCanvas(bpy.types.Operator):
|
|||
self.execute(context)
|
||||
if self.in_cam:
|
||||
self.cam.matrix_world = self.cam_matrix
|
||||
context.space_data.region_3d.view_camera_offset = self.view_cam_offset
|
||||
else:
|
||||
context.space_data.region_3d.view_rotation = self._rotation
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.current_area = context.area
|
||||
prefs = get_addon_prefs()
|
||||
self.hud = prefs.canvas_use_hud
|
||||
self.use_view_center = prefs.canvas_use_view_center
|
||||
self.angle = 0.0
|
||||
self.in_cam = context.region_data.view_perspective == 'CAMERA'
|
||||
|
||||
## store ratio for view rotate correction
|
||||
|
||||
# CORRECT UI OVERLAP FROM HEADER TOOLBAR
|
||||
regs = context.area.regions
|
||||
if context.preferences.system.use_region_overlap:
|
||||
w = context.area.width
|
||||
# minus tool header
|
||||
h = context.area.height - regs[0].height
|
||||
else:
|
||||
# minus tool leftbar + sidebar right
|
||||
w = context.area.width - regs[2].width - regs[3].width
|
||||
# minus tool header + header
|
||||
h = context.area.height - regs[0].height - regs[1].height
|
||||
|
||||
self.ratio = h / w
|
||||
self.ratio_inv = w / h
|
||||
|
||||
if self.in_cam:
|
||||
# Get camera from scene
|
||||
self.cam = bpy.context.scene.camera
|
||||
|
@ -161,8 +207,12 @@ class RC_OT_RotateCanvas(bpy.types.Operator):
|
|||
if self.cam.lock_rotation[:] != (False, False, False):
|
||||
self.report({'WARNING'}, 'Camera rotation is locked')
|
||||
return {'CANCELLED'}
|
||||
|
||||
if self.use_view_center:
|
||||
self.center = mathutils.Vector((w/2, h/2))
|
||||
else:
|
||||
self.center = self.get_center_view(context, self.cam)
|
||||
|
||||
self.center = self.get_center_view(context, self.cam)
|
||||
# store original rotation mode
|
||||
self.org_rotation_mode = self.cam.rotation_mode
|
||||
# set to euler to works with quaternions, restored at finish
|
||||
|
@ -170,9 +220,13 @@ class RC_OT_RotateCanvas(bpy.types.Operator):
|
|||
# store camera matrix world
|
||||
self.cam_matrix = self.cam.matrix_world.copy()
|
||||
# self.cam_init_euler = self.cam.rotation_euler.copy()
|
||||
|
||||
## initialize current view_offset in camera
|
||||
self.view_cam_offset = mathutils.Vector(context.space_data.region_3d.view_camera_offset)
|
||||
|
||||
else:
|
||||
self.center = mathutils.Vector((context.area.width/2, context.area.height/2))
|
||||
self.center = mathutils.Vector((w/2, h/2))
|
||||
# self.center = mathutils.Vector((context.area.width/2, context.area.height/2))
|
||||
|
||||
# store current rotation
|
||||
self._rotation = context.space_data.region_3d.view_rotation.copy()
|
||||
|
@ -188,6 +242,7 @@ class RC_OT_RotateCanvas(bpy.types.Operator):
|
|||
# Initializes the current vector with the same initial vector.
|
||||
self.vector_current = self.vector_initial.copy()
|
||||
|
||||
|
||||
#Snap keys
|
||||
self.snap_ctrl = not prefs.use_ctrl
|
||||
self.snap_shift = not prefs.use_shift
|
||||
|
|
Loading…
Reference in New Issue