[Bf-extensions-cvs] [81b348c4] master: GPencil Tools: Canvas rotate improvement

Pullusb noreply at git.blender.org
Tue Jul 6 23:57:05 CEST 2021


Commit: 81b348c4525abdbbd0f176c7486cdc19c0024776
Author: Pullusb
Date:   Tue Jul 6 23:56:52 2021 +0200
Branches: master
https://developer.blender.org/rBA81b348c4525abdbbd0f176c7486cdc19c0024776

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.

===================================================================

M	greasepencil_tools/__init__.py
M	greasepencil_tools/prefs.py
M	greasepencil_tools/rotate_canvas.py

===================================================================

diff --git a/greasepencil_tools/__init__.py b/greasepencil_tools/__init__.py
index 494354d5..646f4862 100644
--- a/greasepencil_tools/__init__.py
+++ b/greasepencil_tools/__init__.py
@@ -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": "",
diff --git a/greasepencil_tools/prefs.py b/greasepencil_tools/prefs.py
index 270497b0..57cf0ee5 100644
--- a/greasepencil_tools/prefs.py
+++ b/greasepencil_tools/prefs.py
@@ -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
diff --git a/greasepencil_tools/rotate_canvas.py b/greasepencil_tools/rotate_canvas.py
index 12ee7339..0b46299d 100644
--- a/greasepencil_tools/rotate_canvas.py
+++ b/greasepencil_tools/rotate_canvas.py
@@ -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



More information about the Bf-extensions-cvs mailing list