[Bf-extensions-cvs] [d7e2005d] greasepencil-addon: First commit GP addon

Pullusb noreply at git.blender.org
Fri Jul 10 23:35:04 CEST 2020


Commit: d7e2005d22435e104507ac129cd15d2eb6a10258
Author: Pullusb
Date:   Fri Jul 10 23:26:43 2020 +0200
Branches: greasepencil-addon
https://developer.blender.org/rBAd7e2005d22435e104507ac129cd15d2eb6a10258

First commit GP addon

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

A	greasepencil-addon/__init__.py
A	greasepencil-addon/box_deform.py
A	greasepencil-addon/line_reshape.py
A	greasepencil-addon/prefs.py
A	greasepencil-addon/ui_panels.py

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

diff --git a/greasepencil-addon/__init__.py b/greasepencil-addon/__init__.py
new file mode 100644
index 00000000..b6e759fa
--- /dev/null
+++ b/greasepencil-addon/__init__.py
@@ -0,0 +1,54 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+
+bl_info = {
+"name": "Grease Pencil Tools",
+"description": "Pack of tools for Grease pencil drawing",
+"author": "Samuel Bernou",
+"version": (0, 0, 5),
+"blender": (2, 83, 0),
+"location": "sidebar (N) > Grease pencil > Grease pencil",
+"warning": "",
+"doc_url": "https://github.com/Pullusb/greasepencil-addon",
+"tracker_url": "https://github.com/Pullusb/greasepencil-addon/issues",
+"category": "Object",
+# "support": "COMMUNITY",
+}
+
+
+from .  import (prefs,
+                box_deform,
+                line_reshape,
+                ui_panels,
+                )
+
+def register():
+    prefs.register()
+    box_deform.register()
+    line_reshape.register()
+    ui_panels.register()
+
+def unregister():
+    ui_panels.unregister()
+    box_deform.unregister()
+    line_reshape.unregister()
+    prefs.unregister()
+
+if __name__ == "__main__":
+    register()
\ No newline at end of file
diff --git a/greasepencil-addon/box_deform.py b/greasepencil-addon/box_deform.py
new file mode 100644
index 00000000..8996ae70
--- /dev/null
+++ b/greasepencil-addon/box_deform.py
@@ -0,0 +1,591 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+'''Based on Box_deform standalone addon - Author: Samuel Bernou'''
+
+import bpy
+import numpy as np
+
+def get_addon_prefs():
+    import os
+    addon_name = os.path.splitext(__name__)[0]
+    preferences = bpy.context.preferences
+    addon_prefs = preferences.addons[addon_name].preferences
+    return (addon_prefs)
+
+
+def location_to_region(worldcoords):
+    from bpy_extras import view3d_utils
+    return view3d_utils.location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, worldcoords)
+
+def region_to_location(viewcoords, depthcoords):
+    from bpy_extras import view3d_utils
+    return view3d_utils.region_2d_to_location_3d(bpy.context.region, bpy.context.space_data.region_3d, viewcoords, depthcoords)
+
+def assign_vg(obj, vg_name):
+    ## create vertex group
+    vg = obj.vertex_groups.get(vg_name)
+    if vg:
+        # remove to start clean
+        obj.vertex_groups.remove(vg)
+    vg = obj.vertex_groups.new(name=vg_name)
+    bpy.ops.gpencil.vertex_group_assign()
+    return vg
+
+def view_cage(obj):
+    prefs = get_addon_prefs()
+    lattice_interp = prefs.default_deform_type
+
+    gp = obj.data
+    gpl = gp.layers
+
+    coords = []
+    initial_mode = bpy.context.mode
+
+    ## get points
+    if bpy.context.mode == 'EDIT_GPENCIL':
+        for l in gpl:
+            if l.lock or l.hide or not l.active_frame:#or len(l.frames)
+                continue
+            if gp.use_multiedit:
+                target_frames = [f for f in l.frames if f.select]
+            else:
+                target_frames = [l.active_frame]
+            
+            for f in target_frames:
+                for s in f.strokes:
+                    if not s.select:
+                        continue
+                    for p in s.points:
+                        if p.select:
+                            # get real location
+                            coords.append(obj.matrix_world @ p.co)
+
+    elif bpy.context.mode == 'OBJECT':#object mode -> all points
+        for l in gpl:# if l.hide:continue# only visible ? (might break things)
+            if not len(l.frames):
+                continue#skip frameless layer
+            for s in l.active_frame.strokes:
+                for p in s.points:
+                    coords.append(obj.matrix_world @ p.co)
+    
+    elif bpy.context.mode == 'PAINT_GPENCIL':
+        # get last stroke points coordinated
+        if not gpl.active or not gpl.active.active_frame:
+            return 'No frame to deform'
+
+        if not len(gpl.active.active_frame.strokes):
+            return 'No stroke found to deform'
+        
+        paint_id = -1
+        if bpy.context.scene.tool_settings.use_gpencil_draw_onback:
+            paint_id = 0
+        coords = [obj.matrix_world @ p.co for p in gpl.active.active_frame.strokes[paint_id].points]
+    
+    else:
+        return 'Wrong mode!'
+
+    if not coords:
+        ## maybe silent return instead (need special str code to manage errorless return)
+        return 'No points found!'
+
+    if bpy.context.mode in ('EDIT_GPENCIL', 'PAINT_GPENCIL') and len(coords) < 2:
+        # Dont block object mod
+        return 'Less than two point selected'
+
+    vg_name = 'lattice_cage_deform_group'
+
+    if bpy.context.mode == 'EDIT_GPENCIL':
+        vg = assign_vg(obj, vg_name)
+    
+    if bpy.context.mode == 'PAINT_GPENCIL':
+        # points cannot be assign to API yet(ugly and slow workaround but only way)
+        # -> https://developer.blender.org/T56280 so, hop'in'ops !
+        
+        # store selection and deselect all
+        plist = []
+        for s in gpl.active.active_frame.strokes:
+            for p in s.points:
+                plist.append([p, p.select])
+                p.select = False
+        
+        # select
+        ## foreach_set does not update
+        # gpl.active.active_frame.strokes[paint_id].points.foreach_set('select', [True]*len(gpl.active.active_frame.strokes[paint_id].points))
+        for p in gpl.active.active_frame.strokes[paint_id].points:
+            p.select = True
+        
+        # assign
+        bpy.ops.object.mode_set(mode='EDIT_GPENCIL')
+        vg = assign_vg(obj, vg_name)
+
+        # restore
+        for pl in plist:
+            pl[0].select = pl[1]
+        
+
+    ## View axis Mode ---
+
+    ## get view coordinate of all points
+    coords2D = [location_to_region(co) for co in coords]
+
+    # find centroid for depth (or more economic, use obj origin...)
+    centroid = np.mean(coords, axis=0)
+
+    # not a mean ! a mean of extreme ! centroid2d = np.mean(coords2D, axis=0)
+    all_x, all_y = np.array(coords2D)[:, 0], np.array(coords2D)[:, 1]
+    min_x, min_y = np.min(all_x), np.min(all_y)
+    max_x, max_y = np.max(all_x), np.max(all_y)
+
+    width = (max_x - min_x)
+    height = (max_y - min_y)
+    center_x = min_x + (width/2)
+    center_y = min_y + (height/2)
+
+    centroid2d = (center_x,center_y)
+    center = region_to_location(centroid2d, centroid)
+    # bpy.context.scene.cursor.location = center#Dbg
+
+
+    #corner Bottom-left to Bottom-right
+    x0 = region_to_location((min_x, min_y), centroid)
+    x1 = region_to_location((max_x, min_y), centroid)
+    x_worldsize = (x0 - x1).length
+
+    #corner Bottom-left to top-left
+    y0 = region_to_location((min_x, min_y), centroid)
+    y1 = region_to_location((min_x, max_y), centroid)
+    y_worldsize = (y0 - y1).length
+
+    ## in case of 3
+
+    lattice_name = 'lattice_cage_deform'
+    # cleaning
+    cage = bpy.data.objects.get(lattice_name)
+    if cage:
+        bpy.data.objects.remove(cage)
+
+    lattice = bpy.data.lattices.get(lattice_name)
+    if lattice:
+        bpy.data.lattices.remove(lattice)
+
+    # create lattice object
+    lattice = bpy.data.lattices.new(lattice_name)
+    cage = bpy.data.objects.new(lattice_name, lattice)
+    cage.show_in_front = True
+
+    ## Master (root) collection
+    bpy.context.scene.collection.objects.link(cage)
+
+    # spawn cage and align it to view (Again ! align something to a vector !!! argg)
+
+    r3d = bpy.context.space_data.region_3d
+    viewmat = r3d.view_matrix
+
+    cage.matrix_world = viewmat.inverted()
+    cage.scale = (x_worldsize, y_worldsize, 1)
+    ## Z aligned in view direction (need minus X 90 degree to be aligned FRONT)
+    # cage.rotation_euler.x -= radians(90)
+    # cage.scale = (x_worldsize, 1, y_worldsize)
+    cage.location = center
+
+    lattice.points_u = 2
+    lattice.points_v = 2
+    lattice.points_w = 1
+
+    lattice.interpolation_type_u = lattice_interp#'KEY_LINEAR'-'KEY_BSPLINE'
+    lattice.interpolation_type_v = lattice_interp#'KEY_LINEAR'-'KEY_BSPLINE'
+    lattice.interpolation_type_w = lattice_interp#'KEY_LINEAR'-'KEY_BSPLINE'
+
+    mod = obj.grease_pencil_modifiers.new('tmp_lattice', 'GP_LATTICE')
+
+    # move to top if modifiers exists
+    for _ in range(len(obj.grease_pencil_modifiers)):
+        bpy.ops.object.gpencil_modifier_move_up(modifier='tmp_lattice')
+
+    mod.object = cage
+
+    if initial_mode == 'PAINT_GPENCIL':
+        mod.layer = gpl.active.info
+    
+    # note : if initial was Paint, changed to Edit
+    #        so vertex attribution is valid even for paint
+    if bpy.context.mode == 'EDIT_GPENCIL':
+        mod.vertex_group = vg.

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list