[Bf-extensions-cvs] [a5ebaabe] master: mesh_snap_utilities_line: Fix framebuffer being created and cleaned in the wrong context

mano-wii noreply at git.blender.org
Mon Feb 11 01:48:09 CET 2019


Commit: a5ebaabeee575be340ad0c7464489de4afac5eb3
Author: mano-wii
Date:   Sun Feb 10 21:45:47 2019 -0200
Branches: master
https://developer.blender.org/rBAa5ebaabeee575be340ad0c7464489de4afac5eb3

mesh_snap_utilities_line: Fix framebuffer being created and cleaned in the wrong context

The solution is somewhat hackistic because it requires the creation of a global framebuffer at the time the addon is registered

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

M	mesh_snap_utilities_line/__init__.py
M	mesh_snap_utilities_line/snap_context_l/__init__.py
M	mesh_snap_utilities_line/widgets.py

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

diff --git a/mesh_snap_utilities_line/__init__.py b/mesh_snap_utilities_line/__init__.py
index be37d8a0..40194f1d 100644
--- a/mesh_snap_utilities_line/__init__.py
+++ b/mesh_snap_utilities_line/__init__.py
@@ -22,7 +22,7 @@
 bl_info = {
     "name": "Snap_Utilities_Line",
     "author": "Germano Cavalcante",
-    "version": (5, 9, 1),
+    "version": (5, 9, 2),
     "blender": (2, 80, 0),
     "location": "View3D > TOOLS > Line Tool",
     "description": "Extends Blender Snap controls",
@@ -154,6 +154,10 @@ classes = (
 )
 
 def register():
+    from .snap_context_l import global_snap_context_init
+    # This makes sure that the framebuffer is created in the correct context
+    global_snap_context_init(None, None, None)
+
     for cls in classes:
         bpy.utils.register_class(cls)
 
@@ -161,6 +165,9 @@ def register():
 
 
 def unregister():
+    from .snap_context_l import global_snap_context_destroy
+    global_snap_context_destroy()
+
     unregister_snap_tools()
 
     for cls in reversed(classes):
diff --git a/mesh_snap_utilities_line/snap_context_l/__init__.py b/mesh_snap_utilities_line/snap_context_l/__init__.py
index 2aab0a3e..1904886c 100644
--- a/mesh_snap_utilities_line/snap_context_l/__init__.py
+++ b/mesh_snap_utilities_line/snap_context_l/__init__.py
@@ -27,6 +27,12 @@ EDGE = 2
 FACE = 4
 
 
+def check_gl_error():
+    error = bgl.glGetError()
+    if error != bgl.GL_NO_ERROR:
+        raise Exception(error)
+
+
 class _Internal:
     global_snap_context = None
 
@@ -79,15 +85,14 @@ class _SnapOffscreen():
 
         bgl.glGenRenderbuffers(1, self.buf_depth)
         bgl.glGenTextures(1, self.buf_color)
-        self._config_textures()
 
-        bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_NEAREST)
-        bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST)
+        self._config_textures()
 
         bgl.glGetIntegerv(bgl.GL_FRAMEBUFFER_BINDING, self.cur_fbo)
 
         bgl.glGenFramebuffers(1, self.fbo)
         bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.fbo[0])
+
         bgl.glFramebufferRenderbuffer(
                 bgl.GL_FRAMEBUFFER, bgl.GL_DEPTH_ATTACHMENT,
                 bgl.GL_RENDERBUFFER, self.buf_depth[0])
@@ -116,6 +121,8 @@ class _SnapOffscreen():
                 0, bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT, NULL)
         del NULL
 
+        bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_NEAREST)
+        bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST)
 
     def bind(self):
         if self is not _SnapOffscreen.bound:
@@ -134,7 +141,7 @@ class _SnapOffscreen():
             _SnapOffscreen.bound = None
 
     def clear(self):
-        is_bound =  self is _SnapOffscreen.bound
+        is_bound = self is _SnapOffscreen.bound
         if not is_bound:
             self.bind()
 
@@ -161,7 +168,6 @@ class _SnapOffscreen():
         if not is_bound:
             self.unbind()
 
-
     def __del__(self):
         if not self.freed:
             bgl.glDeleteFramebuffers(1, self.fbo)
@@ -200,14 +206,6 @@ class SnapContext():
         self.snap_objects = []
         self.drawn_count = 0
         self._offset_cur = 1 # Starts with index 1
-        self.region = region
-        self.rv3d = space.region_3d
-        self.depsgraph = depsgraph
-
-        if self.rv3d.is_perspective:
-            self.depth_range = Vector((space.clip_start, space.clip_end))
-        else:
-            self.depth_range = Vector((-space.clip_end, space.clip_end))
 
         self.proj_mat = None
         self.mval = Vector((0, 0))
@@ -215,11 +213,25 @@ class SnapContext():
 
         self.set_pixel_dist(12)
 
-        self._offscreen = _SnapOffscreen(self.region.width, self.region.height)
+        self.region = region
+        self.depsgraph = depsgraph
 
-        self.winsize = Vector((self._offscreen.width, self._offscreen.height))
+        if not (depsgraph or region or space):
+            self.rv3d = None
+            self.depth_range = Vector((-1.0, 1.0))
+            self._offscreen = _SnapOffscreen(1, 1)
+        else:
+            self.rv3d = space.region_3d
 
-        self._offscreen.clear()
+            if self.rv3d.is_perspective:
+                self.depth_range = Vector((space.clip_start, space.clip_end))
+            else:
+                self.depth_range = Vector((-space.clip_end, space.clip_end))
+
+            self._offscreen = _SnapOffscreen(self.region.width, self.region.height)
+            self._offscreen.clear()
+
+        self.winsize = Vector((self._offscreen.width, self._offscreen.height))
 
 
     ## PRIVATE ##
@@ -360,7 +372,13 @@ class SnapContext():
             self._offscreen.resize(*self.winsize)
 
     def clear_snap_objects(self):
-        self.update_all()
+        for snap_obj in self.snap_objects:
+            if len(snap_obj.data) == 2:
+                snap_obj.data[1].free()
+                del snap_obj.data[1:]
+
+        self.update_drawing(False)
+
         self.snap_objects.clear()
         _Internal.gpu_Indices_mesh_cache_clear()
 
@@ -372,10 +390,11 @@ class SnapContext():
 
         self.update_drawing()
 
-    def update_drawing(self):
+    def update_drawing(self, clear_offscreen = True):
         self.drawn_count = 0
         self._offset_cur = 1
-        self._offscreen.clear()
+        if clear_offscreen:
+            self._offscreen.clear()
 
     def tag_update_drawn_snap_object(self, snap_obj):
         if len(snap_obj.data) > 1:
@@ -502,9 +521,11 @@ class SnapContext():
                 self.drawn_count += 1
 
         bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)
+
         bgl.glReadPixels(
                 int(self.mval[0]) - self._dist_px, int(self.mval[1]) - self._dist_px,
                 self.threshold, self.threshold, bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT, self._snap_buffer)
+
         #bgl.glReadBuffer(bgl.GL_BACK)
         #import numpy as np
         #a = np.array(self._snap_buffer)
@@ -516,6 +537,7 @@ class SnapContext():
             ret = self._get_loc(snap_obj, index)
 
         bgl.glDisable(bgl.GL_DEPTH_TEST)
+
         self._offscreen.unbind()
         _Internal.gpu_Indices_restore_state()
 
@@ -525,11 +547,9 @@ class SnapContext():
         self.__del__()
         self.freed = True
 
-def global_snap_context_get(depsgraph, region, space):
-    if _Internal.global_snap_context == None:
-        if depsgraph is None or region is None or space is None:
-            return
 
+def global_snap_context_init(depsgraph, region, space):
+    if _Internal.global_snap_context == None:
         import atexit
 
         _Internal.global_snap_context = SnapContext(depsgraph, region, space)
@@ -538,7 +558,14 @@ def global_snap_context_get(depsgraph, region, space):
         atexit.unregister(_Internal.snap_context_free)
         atexit.register(_Internal.snap_context_free)
 
-    elif depsgraph is not None:
+
+def global_snap_context_get(depsgraph, region, space):
+    if (depsgraph and region and space):
         _Internal.global_snap_context.update_viewport_context(depsgraph, region, space, True)
 
     return _Internal.global_snap_context
+
+
+def global_snap_context_destroy():
+    if _Internal.global_snap_context != None:
+        _Internal.global_snap_context.free()
diff --git a/mesh_snap_utilities_line/widgets.py b/mesh_snap_utilities_line/widgets.py
index 6f8639e0..92256f81 100644
--- a/mesh_snap_utilities_line/widgets.py
+++ b/mesh_snap_utilities_line/widgets.py
@@ -131,66 +131,6 @@ class SnapPointWidget(SnapWidgetCommon, bpy.types.Gizmo):
         self.init_snapwidget(bpy.context)
 
 
-class SnapFaceWidget(SnapWidgetCommon, bpy.types.Gizmo):
-    bl_idname = "VIEW3D_GT_snap_face_point"
-
-    def test_select(self, context, mval):
-        self.update_snap(context, mval)
-        self.snap_to_grid()
-
-        context.area.tag_redraw()
-        return -1
-
-    def draw(self, context):
-        self.draw_point_and_elem()
-
-    def setup(self):
-        self.init_snapwidget(bpy.context, False)
-
-
-class SnapCircleWidget(SnapWidgetCommon, bpy.types.Gizmo):
-    bl_idname = "VIEW3D_GT_snap_circle"
-
-    from mathutils import Vector
-    zero_vector = Vector()
-    default_normal = Vector((0.0, 0.0, 1.0))
-
-    def get_normal(self, context):
-        if self.constrain:
-            return
-
-        view_vector, orig = self.sctx.last_ray
-        if not self.rv3d.is_perspective:
-            #temporary hack
-            orig -= view_vector * 100
-
-        normal_face = context.scene.ray_cast(context.view_layer, orig, view_vector)[2]
-        if normal_face and normal_face != self.zero_vector:
-            self.normal = normal_face
-        else:
-            self.normal = self.default_normal
-
-    def test_select(self, context, mval):
-        self.update_snap(context, mval)
-        self.snap_to_grid()
-        self.get_normal(context)
-
-        context.area.tag_redraw()
-        return -1
-
-    def draw(self, context):
-        self.draw_point_and_elem()
-        self.draw_cache.draw_rot_tool(
-                self.rv3d.view_distance / 15,
-                self.location, self.normal, None)
-
-    def setup(self):
-        context = bpy.context
-        self.init_snapwidget(context)
-        self.rv3d = context.region_data
-        self.normal = self.default_normal
-
-
 def context_mode_check(context, widget_group):
     workspace = context.workspace
     mode = workspace.tools_mode
@@ -226,19 +166,3 @@ class SnapPointWidgetGroup(SnapWidgetGroupCommon, bpy.types.GizmoGroup):
 
     def setup(self, context):
         self.init_tool(context, SnapPointWidget.bl_idname)
-
-
-class SnapCircleWidgetGroup(SnapWidgetGroupCommon, bpy.types.GizmoGroup):
-    bl_idname = "MESH_GGT_snap_circle"
-    bl_label = "Draw Snap Circle"
-
-    def setup(self, context):
-        self.init_tool(context, SnapCircleWidget.bl_idname)
-
-
-class SnapFaceWidgetGroup(SnapWidgetGroupCommon, bpy.types.GizmoGroup):
-    bl_idname = "MESH_GGT_face_snap_point"
-    bl_label = "Draw Face and Snap Point"
-
-    def setup(self, context):
-        self.init_tool(context, SnapFaceWidget.bl_idname)



More information about the Bf-extensions-cvs mailing list