diff options
author | Germano Cavalcante <germano.costa@ig.com.br> | 2021-02-17 18:45:52 +0300 |
---|---|---|
committer | Germano Cavalcante <germano.costa@ig.com.br> | 2021-02-17 18:57:50 +0300 |
commit | f01d08b7c5f7873e0ce8a77b84788e2f6b1ad716 (patch) | |
tree | beb173e6acaf16c2c326b23f63abc2d3fb41fe3f /mesh_snap_utilities_line | |
parent | 33b39ecc88a9d86437f5afe5fe372a623f86ae77 (diff) |
Snap Utilities Line: Replace the uses of the bgl module with the gpu equivalent
Also a little style update due to automatic updates.
Ref T80730, T85675
Diffstat (limited to 'mesh_snap_utilities_line')
-rw-r--r-- | mesh_snap_utilities_line/__init__.py | 4 | ||||
-rw-r--r-- | mesh_snap_utilities_line/drawing_utilities.py | 60 | ||||
-rw-r--r-- | mesh_snap_utilities_line/op_line.py | 1 | ||||
-rw-r--r-- | mesh_snap_utilities_line/snap_context_l/__init__.py | 376 | ||||
-rw-r--r-- | mesh_snap_utilities_line/snap_context_l/mesh_drawing.py | 100 |
5 files changed, 217 insertions, 324 deletions
diff --git a/mesh_snap_utilities_line/__init__.py b/mesh_snap_utilities_line/__init__.py index 5e4d2f96..ee6503aa 100644 --- a/mesh_snap_utilities_line/__init__.py +++ b/mesh_snap_utilities_line/__init__.py @@ -21,8 +21,8 @@ bl_info = { "name": "Snap_Utilities_Line", "author": "Germano Cavalcante", - "version": (5, 9, 19), - "blender": (2, 80, 0), + "version": (6, 9, 20), + "blender": (2, 93, 0), "location": "View3D > TOOLS > Line Tool", "description": "Extends Blender Snap controls", "doc_url" : "https://blenderartists.org/t/cad-snap-utilities", diff --git a/mesh_snap_utilities_line/drawing_utilities.py b/mesh_snap_utilities_line/drawing_utilities.py index 0488f0f3..cf67db4b 100644 --- a/mesh_snap_utilities_line/drawing_utilities.py +++ b/mesh_snap_utilities_line/drawing_utilities.py @@ -14,13 +14,12 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # # ##### END GPL LICENSE BLOCK ##### - -import bgl +import gpu from mathutils import Vector class SnapDrawn(): - __slots__ = ( + __slots__ = (\ 'out_color', 'face_color', 'edge_color', @@ -33,11 +32,9 @@ class SnapDrawn(): 'axis_z_color', '_format_pos', '_format_pos_and_color', - '_is_point_size_enabled', '_program_unif_col', '_program_smooth_col', - '_batch_point', - ) + '_batch_point',) def __init__(self, out_color, face_color, edge_color, vert_color, center_color, @@ -72,17 +69,11 @@ class SnapDrawn(): def _gl_state_push(self): - self._is_point_size_enabled = bgl.glIsEnabled(bgl.GL_PROGRAM_POINT_SIZE) - if self._is_point_size_enabled: - bgl.glDisable(bgl.GL_PROGRAM_POINT_SIZE) - - # draw 3d point OpenGL in the 3D View - bgl.glEnable(bgl.GL_BLEND) + gpu.state.program_point_size_set(False) + gpu.state.blend_set('ALPHA') def _gl_state_restore(self): - bgl.glDisable(bgl.GL_BLEND) - if self._is_point_size_enabled: - bgl.glEnable(bgl.GL_PROGRAM_POINT_SIZE) + gpu.state.blend_set('NONE') def batch_line_strip_create(self, coords): from gpu.types import ( @@ -138,22 +129,29 @@ class SnapDrawn(): if list_verts_co: # draw 3d line OpenGL in the 3D View - bgl.glDepthRange(0, 0.9999) - bgl.glLineWidth(3.0) + winmat = gpu.matrix.get_projection_matrix() + winmat[3][2] -= 0.0001 + gpu.matrix.push_projection() + gpu.matrix.load_projection_matrix(winmat) + gpu.state.line_width_set(3.0) batch = self.batch_line_strip_create([v.to_tuple() for v in list_verts_co] + [location.to_tuple()]) + self._program_unif_col.bind() self._program_unif_col.uniform_float("color", (1.0, 0.8, 0.0, 0.5)) batch.draw(self._program_unif_col) + gpu.matrix.pop_projection() del batch - bgl.glDisable(bgl.GL_DEPTH_TEST) + gpu.state.depth_test_set('NONE') point_batch = self.batch_point_get() if vector_constrain: if prevloc: - bgl.glPointSize(5.0) + gpu.state.point_size_set(5.0) gpu.matrix.translate(prevloc) + + self._program_unif_col.bind() self._program_unif_col.uniform_float("color", (1.0, 1.0, 1.0, 0.5)) point_batch.draw(self._program_unif_col) gpu.matrix.translate(-prevloc) @@ -182,17 +180,17 @@ class SnapDrawn(): else: # type == None Color4f = self.out_color - bgl.glPointSize(10.0) + gpu.state.point_size_set(10.0) gpu.matrix.translate(location) + self._program_unif_col.bind() self._program_unif_col.uniform_float("color", Color4f) point_batch.draw(self._program_unif_col) # restore opengl defaults - bgl.glDepthRange(0.0, 1.0) - bgl.glPointSize(1.0) - bgl.glLineWidth(1.0) - bgl.glEnable(bgl.GL_DEPTH_TEST) + gpu.state.point_size_set(1.0) + gpu.state.line_width_set(1.0) + gpu.state.depth_test_set('LESS_EQUAL') gpu.matrix.pop() self._gl_state_restore() @@ -208,7 +206,7 @@ class SnapDrawn(): with gpu.matrix.push_pop(): self._gl_state_push() - bgl.glDisable(bgl.GL_DEPTH_TEST) + gpu.state.depth_test_set('NONE') gpu.matrix.multiply_matrix(snap_obj.mat) @@ -225,24 +223,26 @@ class SnapDrawn(): edges.shape = -1 self._program_smooth_col.bind() - bgl.glLineWidth(3.0) + gpu.state.line_width_set(3.0) batch = self.batch_lines_smooth_color_create(edges["pos"], edges["color"]) batch.draw(self._program_smooth_col) - bgl.glLineWidth(1.0) + gpu.state.line_width_set(1.0) else: self._program_unif_col.bind() if isinstance(elem, BMEdge): + self._program_unif_col.bind() self._program_unif_col.uniform_float("color", self.edge_color) - bgl.glLineWidth(3.0) + gpu.state.line_width_set(3.0) batch = self.batch_line_strip_create([v.co for v in elem.verts]) batch.draw(self._program_unif_col) - bgl.glLineWidth(1.0) + gpu.state.line_width_set(1.0) elif isinstance(elem, BMFace): if len(snap_obj.data) == 2: face_color = self.face_color[0], self.face_color[1], self.face_color[2], self.face_color[3] * 0.2 + self._program_unif_col.bind() self._program_unif_col.uniform_float("color", face_color) tris = snap_obj.data[1].get_loop_tri_co_by_bmface(bm, elem) @@ -251,6 +251,6 @@ class SnapDrawn(): batch.draw(self._program_unif_col) # restore opengl defaults - bgl.glEnable(bgl.GL_DEPTH_TEST) + gpu.state.depth_test_set('LESS_EQUAL') self._gl_state_restore() diff --git a/mesh_snap_utilities_line/op_line.py b/mesh_snap_utilities_line/op_line.py index 685ebca4..f63eb219 100644 --- a/mesh_snap_utilities_line/op_line.py +++ b/mesh_snap_utilities_line/op_line.py @@ -408,7 +408,6 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator): #Store values from 3d view context self.rv3d = context.region_data self.rotMat = self.rv3d.view_matrix.copy() - # self.obj_glmatrix = bgl.Buffer(bgl.GL_FLOAT, [4, 4], # self.obj_matrix.transposed()) #modals diff --git a/mesh_snap_utilities_line/snap_context_l/__init__.py b/mesh_snap_utilities_line/snap_context_l/__init__.py index 3c09e537..74c85499 100644 --- a/mesh_snap_utilities_line/snap_context_l/__init__.py +++ b/mesh_snap_utilities_line/snap_context_l/__init__.py @@ -14,25 +14,15 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # # ##### END GPL LICENSE BLOCK ##### +__all__ = ("SnapContext",) -__all__ = ( - "SnapContext", - ) - -import bgl +import gpu from mathutils import Vector VERT = 1 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 @@ -46,7 +36,6 @@ class _Internal: gpu_Indices_enable_state, gpu_Indices_restore_state, gpu_Indices_use_clip_planes, - gpu_Indices_set_ProjectionMatrix, gpu_Indices_mesh_cache_clear, ) @@ -70,119 +59,41 @@ class _SnapObjectData(): class _SnapOffscreen(): bound = None def __init__(self, width, height): - self.freed = False - self.is_bound = False + self._fbo = None self.width = width self.height = height - self.fbo = bgl.Buffer(bgl.GL_INT, 1) - self.buf_color = bgl.Buffer(bgl.GL_INT, 1) - self.buf_depth = bgl.Buffer(bgl.GL_INT, 1) - - self.cur_fbo = bgl.Buffer(bgl.GL_INT, 1) - self.cur_viewport = bgl.Buffer(bgl.GL_INT, 4) - - bgl.glGenRenderbuffers(1, self.buf_depth) - bgl.glGenTextures(1, self.buf_color) - - 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]) - - bgl.glFramebufferTexture(bgl.GL_FRAMEBUFFER, bgl.GL_COLOR_ATTACHMENT0, self.buf_color[0], 0) + self._framebuffer_config() - bgl.glDrawBuffers(1, bgl.Buffer(bgl.GL_INT, 1, [bgl.GL_COLOR_ATTACHMENT0])) + def _framebuffer_config(self): + self._framebuffer_free() - status = bgl.glCheckFramebufferStatus(bgl.GL_FRAMEBUFFER) - if status != bgl.GL_FRAMEBUFFER_COMPLETE: - print("Framebuffer Invalid", status) + self._tex_color = gpu.types.GPUTexture((self.width, self.height), format='R32UI') + self._tex_depth = gpu.types.GPUTexture((self.width, self.height), format='DEPTH_COMPONENT32F') + self._fbo = gpu.types.GPUFrameBuffer(depth_slot=self._tex_depth, color_slots=self._tex_color) - bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.cur_fbo[0]) - - def _config_textures(self): - import ctypes - - bgl.glBindRenderbuffer(bgl.GL_RENDERBUFFER, self.buf_depth[0]) - bgl.glRenderbufferStorage( - bgl.GL_RENDERBUFFER, bgl.GL_DEPTH_COMPONENT, self.width, self.height) - - NULL = bgl.Buffer(bgl.GL_INT, 1, (ctypes.c_int32 * 1).from_address(0)) - bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.buf_color[0]) - bgl.glTexImage2D( - bgl.GL_TEXTURE_2D, 0, bgl.GL_R32UI, self.width, self.height, - 0, bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT, None) - 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 _framebuffer_free(self): + self._fbo = self._tex_color = self._tex_depth = None def bind(self): - if self is not _SnapOffscreen.bound: - if _SnapOffscreen.bound is None: - bgl.glGetIntegerv(bgl.GL_FRAMEBUFFER_BINDING, self.cur_fbo) - bgl.glGetIntegerv(bgl.GL_VIEWPORT, self.cur_viewport) - - bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.fbo[0]) - bgl.glViewport(0, 0, self.width, self.height) - _SnapOffscreen.bound = self - - def unbind(self): - if self is _SnapOffscreen.bound: - bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.cur_fbo[0]) - bgl.glViewport(*self.cur_viewport) - _SnapOffscreen.bound = None + return self._fbo.bind() def clear(self): - is_bound = self is _SnapOffscreen.bound - if not is_bound: - self.bind() - - bgl.glColorMask(bgl.GL_TRUE, bgl.GL_TRUE, bgl.GL_TRUE, bgl.GL_TRUE) - bgl.glClearColor(0.0, 0.0, 0.0, 0.0) - - bgl.glDepthMask(bgl.GL_TRUE) - bgl.glClearDepth(1.0); - - bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) - - if not is_bound: - self.unbind() + #self._fbo.clear(color=(0.0, 0.0, 0.0, 0.0), depth=1.0) + self._tex_color.clear(format='UINT', value=(0,)) + self._tex_depth.clear(format='FLOAT', value=(1.0,)) def resize(self, width, height): - is_bound = self is _SnapOffscreen.bound - if not is_bound: - self.bind() - self.width = int(width) self.height = int(height) - self._config_textures() - - if not is_bound: - self.unbind() + self._framebuffer_config() def __del__(self): - if not self.freed: - bgl.glDeleteFramebuffers(1, self.fbo) - bgl.glDeleteRenderbuffers(1, self.buf_depth) - bgl.glDeleteTextures(1, self.buf_color) - del self.fbo - del self.buf_color - del self.buf_depth - - del self.cur_fbo - del self.cur_viewport + self._framebuffer_free() def free(self): - self.__del__() - self.freed = True + self._framebuffer_free() class SnapContext(): @@ -198,7 +109,7 @@ class SnapContext(): :type space: :class:`bpy.types.SpaceView3D` """ - __slots__ = ( + __slots__ = (\ '_dist_px', '_dist_px_sq', '_offscreen', @@ -216,13 +127,9 @@ class SnapContext(): 'rv3d', 'snap_objects', 'threshold', - 'winsize', - ) + 'winsize',) def __init__(self, depsgraph, region, space): - #print('Render:', bgl.glGetString(bgl.GL_RENDERER)) - #print('OpenGL Version:', bgl.glGetString(bgl.GL_VERSION)) - self.freed = False self.snap_objects = [] self.drawn_count = 0 @@ -266,39 +173,28 @@ class SnapContext(): return snap_obj return None - def _read_buffer(self, mval): - xmin = int(mval[0]) - self._dist_px - ymin = int(mval[1]) - self._dist_px - size_x = size_y = self.threshold - - if xmin < 0: - #size_x += xmin - xmin = 0 - - if ymin < 0: - #size_y += ymin - ymin = 0 + def _read_buffer(self): + self._snap_buffer = self._offscreen._tex_color.read() - bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0) - bgl.glReadPixels( - xmin, ymin, size_x, size_y, - bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT, self._snap_buffer) - - def _get_nearest_index(self): + def _get_nearest_index(self, mval): r_snap_obj = None r_value = 0 - loc = [self._dist_px, self._dist_px] - d = 1 - m = self.threshold - max_val = 2 * m - 1 + loc_curr = [int(mval[1]), int(mval[0])] + rect = ((max(0, loc_curr[0] - self.threshold), min(self._snap_buffer.dimensions[0], loc_curr[0] + self.threshold)), + (max(0, loc_curr[1] - self.threshold), min(self._snap_buffer.dimensions[1], loc_curr[1] + self.threshold))) + + if loc_curr[0] < rect[0][0] or loc_curr[0] >= rect[0][1] or loc_curr[1] < rect[1][0] or loc_curr[1] >= rect[1][1]: + return r_snap_obj, r_value + find_next_index = self._snap_mode & FACE and self._snap_mode & (VERT | EDGE) last_value = -1 if find_next_index else 0 - while m < max_val: - for i in range(2): - while 2 * loc[i] * d < m: - value = int(self._snap_buffer[loc[0]][loc[1]]) - loc[i] += d + spiral_direction = 0 + for nr in range(1, 2 * self.threshold): + for a in range(2): + for b in range(0, nr): + # TODO: Make the buffer flat. + value = int(self._snap_buffer[loc_curr[0]][loc_curr[1]]) if value != last_value: r_value = value if find_next_index: @@ -308,18 +204,31 @@ class SnapContext(): snap_data = r_snap_obj.data[1] if value < (snap_data.first_index + len(snap_data.tri_verts)): # snap to a triangle - continue - else: - continue - find_next_index = False - elif (r_snap_obj is None) or\ - (value < r_snap_obj.data[1].first_index) or\ - (value >= (r_snap_obj.data[1].first_index + r_snap_obj.data[1].get_tot_elems())): + find_next_index = False + else: + return r_snap_obj, r_value + else: + if (r_snap_obj is None) or \ + (value < r_snap_obj.data[1].first_index) or \ + (value >= (r_snap_obj.data[1].first_index + r_snap_obj.data[1].get_tot_elems())): r_snap_obj = self._get_snap_obj_by_index(value) + + return r_snap_obj, r_value + + # Next spiral step. + if (spiral_direction == 0): + loc_curr[1] += 1 # right + elif (spiral_direction == 1): + loc_curr[0] -= 1 # down + elif (spiral_direction == 2): + loc_curr[1] -= 1 # left + else: + loc_curr[0] += 1 # up + + if (loc_curr[not a] < rect[not a][0] or loc_curr[not a] >= rect[not a][1]): return r_snap_obj, r_value - d = -d - m += 4 * self._dist_px * d + 1 + spiral_direction = (spiral_direction + 1) % 4 return r_snap_obj, r_value def _get_loc(self, snap_obj, index): @@ -331,7 +240,8 @@ class SnapContext(): if index < num_tris: tri_verts = gpu_data.get_tri_verts(index) tri_co = [snap_obj.mat @ Vector(v) for v in gpu_data.get_tri_co(index)] - #loc = _Internal.intersect_ray_tri(*tri_co, self.last_ray[0], self.last_ray[1], False) + #loc = _Internal.intersect_ray_tri(*tri_co, self.last_ray[0], + #self.last_ray[1], False) nor = (tri_co[1] - tri_co[0]).cross(tri_co[2] - tri_co[0]).normalized() loc = _Internal.intersect_line_plane(self.last_ray[1], self.last_ray[1] + self.last_ray[0], tri_co[0], nor) return loc, tri_verts, tri_co @@ -379,6 +289,7 @@ class SnapContext(): def __del__(self): if not self.freed: self._offscreen.free() + self._snap_buffer = None # Some objects may still be being referenced for snap_obj in self.snap_objects: if len(snap_obj.data) == 2: @@ -392,7 +303,7 @@ class SnapContext(): ## PUBLIC ## - def update_viewport_context(self, depsgraph, region, space, resize = False): + def update_viewport_context(self, depsgraph, region, space, resize=False): rv3d = space.region_3d if not resize and self.rv3d == rv3d and self.region == region: @@ -413,7 +324,7 @@ class SnapContext(): self.winsize = winsize self._offscreen.resize(*self.winsize) - def clear_snap_objects(self, clear_offscreen = False): + def clear_snap_objects(self, clear_offscreen=False): for snap_obj in self.snap_objects: if len(snap_obj.data) == 2: snap_obj.data[1].free() @@ -432,7 +343,7 @@ class SnapContext(): self.update_drawing() - def update_drawing(self, clear_offscreen = True): + def update_drawing(self, clear_offscreen=True): self.drawn_count = 0 self._offset_cur = 1 if clear_offscreen: @@ -447,7 +358,7 @@ class SnapContext(): self.proj_mat = None def update_drawn_snap_object(self, snap_obj): - _Internal.gpu_Indices_enable_state() + _Internal.gpu_Indices_enable_state(self.rv3d.window_matrix, self.rv3d.view_matrix) from .mesh_drawing import GPU_Indices_Mesh snap_vert = self._snap_mode & VERT != 0 @@ -470,7 +381,7 @@ class SnapContext(): self._dist_px = int(dist_px) self._dist_px_sq = self._dist_px ** 2 self.threshold = 2 * self._dist_px + 1 - self._snap_buffer = bgl.Buffer(bgl.GL_INT, (self.threshold, self.threshold)) + self._snap_buffer = None def set_snap_mode(self, snap_to_vert, snap_to_edge, snap_to_face): snap_mode = 0 @@ -494,96 +405,87 @@ class SnapContext(): self.last_ray = _Internal.region_2d_to_orig_and_view_vector(self.region, self.rv3d, mval) return self.last_ray - def snap_get(self, mval, main_snap_obj = None): + def snap_get(self, mval, main_snap_obj=None): ret = None, None, None self.mval[:] = mval snap_vert = self._snap_mode & VERT != 0 snap_edge = self._snap_mode & EDGE != 0 snap_face = self._snap_mode & FACE != 0 - _Internal.gpu_Indices_enable_state() - self._offscreen.bind() - - #bgl.glDisable(bgl.GL_DITHER) # dithering and AA break color coding, so disable # - #multisample_enabled = bgl.glIsEnabled(bgl.GL_MULTISAMPLE) - #bgl.glDisable(bgl.GL_MULTISAMPLE) - bgl.glEnable(bgl.GL_DEPTH_TEST) - - is_point_size_enabled = bgl.glIsEnabled(bgl.GL_PROGRAM_POINT_SIZE) - if is_point_size_enabled: - bgl.glDisable(bgl.GL_PROGRAM_POINT_SIZE) - - bgl.glPointSize(4.0) - - proj_mat = self.rv3d.perspective_matrix.copy() - if self.proj_mat != proj_mat: - self.proj_mat = proj_mat - _Internal.gpu_Indices_set_ProjectionMatrix(self.proj_mat) - self.update_drawing() - - ray_dir, ray_orig = self.get_ray(mval) - for i, snap_obj in enumerate(self.snap_objects[self.drawn_count:], self.drawn_count): - obj = snap_obj.data[0] - try: - bbmin = Vector(obj.bound_box[0]) - bbmax = Vector(obj.bound_box[6]) - except ReferenceError: - self.snap_objects.remove(snap_obj) - continue - - if bbmin != bbmax: - MVP = proj_mat @ snap_obj.mat - mat_inv = snap_obj.mat.inverted_safe() - ray_orig_local = mat_inv @ ray_orig - ray_dir_local = mat_inv.to_3x3() @ ray_dir - in_threshold = _Internal.intersect_boundbox_threshold( - self, MVP, ray_orig_local, ray_dir_local, bbmin, bbmax) - else: - proj_co = _Internal.project_co_v3(self, snap_obj.mat.translation) - dist = self.mval - proj_co - in_threshold = abs(dist.x) < self._dist_px and abs(dist.y) < self._dist_px - #snap_obj.data[1] = primitive_point - - if in_threshold: - if len(snap_obj.data) == 1: - from .mesh_drawing import GPU_Indices_Mesh - is_bound = obj.display_type == 'BOUNDS' - draw_face = snap_face and not is_bound and obj.display_type != 'WIRE' - draw_edge = snap_edge and not is_bound - draw_vert = snap_vert and not is_bound - snap_obj.data.append(GPU_Indices_Mesh(self.depsgraph, obj, draw_face, draw_edge, draw_vert)) - - snap_obj.data[1].set_draw_mode(snap_face, snap_edge, snap_vert) - snap_obj.data[1].set_ModelViewMatrix(snap_obj.mat) - - if snap_obj == main_snap_obj: - snap_obj.data[1].Draw(self._offset_cur, -0.0001) + _Internal.gpu_Indices_enable_state(self.rv3d.window_matrix, self.rv3d.view_matrix) + gpu.state.depth_mask_set(True) + gpu.state.depth_test_set('LESS_EQUAL') + gpu.state.program_point_size_set(True) + + with self._offscreen.bind(): + update_buffer = False + proj_mat = self.rv3d.perspective_matrix.copy() + if self.proj_mat != proj_mat: + self.proj_mat = proj_mat + self.update_drawing() + update_buffer = True + + ray_dir, ray_orig = self.get_ray(mval) + for i, snap_obj in enumerate(self.snap_objects[self.drawn_count:], self.drawn_count): + obj = snap_obj.data[0] + try: + bbmin = Vector(obj.bound_box[0]) + bbmax = Vector(obj.bound_box[6]) + except ReferenceError: + self.snap_objects.remove(snap_obj) + continue + + if bbmin != bbmax: + MVP = proj_mat @ snap_obj.mat + mat_inv = snap_obj.mat.inverted_safe() + ray_orig_local = mat_inv @ ray_orig + ray_dir_local = mat_inv.to_3x3() @ ray_dir + in_threshold = _Internal.intersect_boundbox_threshold(self, MVP, ray_orig_local, ray_dir_local, bbmin, bbmax) else: - snap_obj.data[1].Draw(self._offset_cur) - self._offset_cur += snap_obj.data[1].get_tot_elems() - - tmp = self.snap_objects[self.drawn_count] - self.snap_objects[self.drawn_count] = self.snap_objects[i] - self.snap_objects[i] = tmp - - self.drawn_count += 1 - - self._read_buffer(mval) - #import numpy as np - #a = np.array(self._snap_buffer) - #print(a) - - snap_obj, index = self._get_nearest_index() - #print("index:", index) - if snap_obj: - ret = self._get_loc(snap_obj, index) - - if is_point_size_enabled: - bgl.glEnable(bgl.GL_PROGRAM_POINT_SIZE) - - bgl.glDisable(bgl.GL_DEPTH_TEST) + proj_co = _Internal.project_co_v3(self, snap_obj.mat.translation) + dist = self.mval - proj_co + in_threshold = abs(dist.x) < self._dist_px and abs(dist.y) < self._dist_px + #snap_obj.data[1] = primitive_point + + if in_threshold: + if len(snap_obj.data) == 1: + from .mesh_drawing import GPU_Indices_Mesh + is_bound = obj.display_type == 'BOUNDS' + draw_face = snap_face and not is_bound and obj.display_type != 'WIRE' + draw_edge = snap_edge and not is_bound + draw_vert = snap_vert and not is_bound + snap_obj.data.append(GPU_Indices_Mesh(self.depsgraph, obj, draw_face, draw_edge, draw_vert)) + + snap_obj.data[1].set_draw_mode(snap_face, snap_edge, snap_vert) + + if snap_obj == main_snap_obj: + snap_obj.data[1].Draw(self._offset_cur, snap_obj.mat, 0.0001) + else: + snap_obj.data[1].Draw(self._offset_cur, snap_obj.mat) + self._offset_cur += snap_obj.data[1].get_tot_elems() + + tmp = self.snap_objects[self.drawn_count] + self.snap_objects[self.drawn_count] = self.snap_objects[i] + self.snap_objects[i] = tmp + + self.drawn_count += 1 + update_buffer = True + + if update_buffer: + self._read_buffer() + #import numpy as np + #a = np.array(self._snap_buffer) + #print(a) + + snap_obj, index = self._get_nearest_index(mval) + #print("index:", index) + if snap_obj: + ret = self._get_loc(snap_obj, index) + + gpu.state.program_point_size_set(False) + gpu.state.depth_mask_set(False) + gpu.state.depth_test_set('NONE') _Internal.gpu_Indices_restore_state() - self._offscreen.unbind() return (snap_obj, *ret) diff --git a/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py b/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py index a7509df6..219d7311 100644 --- a/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py +++ b/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py @@ -14,9 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # # ##### END GPL LICENSE BLOCK ##### - - -import bgl +import gpu import bmesh from mathutils import Matrix @@ -176,7 +174,7 @@ class _Mesh_Arrays(): class GPU_Indices_Mesh(): - __slots__ = ( + __slots__ = (\ "ob_data", "draw_tris", "draw_edges", @@ -189,8 +187,7 @@ class GPU_Indices_Mesh(): "edge_verts", "looseverts", "first_index", - "users" - ) + "users") _Hash = {} shader = None @@ -198,7 +195,6 @@ class GPU_Indices_Mesh(): @classmethod def end_opengl(cls): del cls.shader - del cls.P del cls @@ -210,28 +206,18 @@ class GPU_Indices_Mesh(): return import atexit - import gpu # Make sure we only registered the callback once. atexit.unregister(cls.end_opengl) atexit.register(cls.end_opengl) - cls.shader = gpu.types.GPUShader( - load_shader("ID_color_vert.glsl"), - load_shader("ID_color_frag.glsl"), - ) - #cls.unif_use_clip_planes = cls.shader.uniform_from_name('use_clip_planes') + cls.shader = gpu.types.GPUShader(load_shader("ID_color_vert.glsl"), + load_shader("ID_color_frag.glsl"),) + #cls.unif_use_clip_planes = + #cls.shader.uniform_from_name('use_clip_planes') #cls.unif_clip_plane = cls.shader.uniform_from_name('clip_plane') cls.unif_offset = cls.shader.uniform_from_name('offset') - cls.P = Matrix() - - - @staticmethod - def set_ModelViewMatrix(MV): - import gpu - gpu.matrix.load_matrix(MV) - def __init__(self, depsgraph, obj, draw_tris, draw_edges, draw_verts): self.ob_data = obj.original.data @@ -240,17 +226,17 @@ class GPU_Indices_Mesh(): src = GPU_Indices_Mesh._Hash[self.ob_data] dst = self - dst.draw_tris = src.draw_tris - dst.draw_edges = src.draw_edges - dst.draw_verts = src.draw_verts - dst.batch_tris = src.batch_tris - dst.batch_edges = src.batch_edges + dst.draw_tris = src.draw_tris + dst.draw_edges = src.draw_edges + dst.draw_verts = src.draw_verts + dst.batch_tris = src.batch_tris + dst.batch_edges = src.batch_edges dst.batch_lverts = src.batch_lverts - dst.verts_co = src.verts_co - dst.tri_verts = src.tri_verts - dst.edge_verts = src.edge_verts - dst.looseverts = src.looseverts - dst.users = src.users + dst.verts_co = src.verts_co + dst.tri_verts = src.tri_verts + dst.edge_verts = src.edge_verts + dst.looseverts = src.looseverts + dst.users = src.users dst.users.append(self) update = False @@ -258,11 +244,9 @@ class GPU_Indices_Mesh(): else: GPU_Indices_Mesh._Hash[self.ob_data] = self self.users = [self] - update = True; + update = True if update: - import gpu - self.draw_tris = draw_tris self.draw_edges = draw_edges self.draw_verts = draw_verts @@ -343,15 +327,35 @@ class GPU_Indices_Mesh(): self.draw_verts = draw_verts and len(self.looseverts) > 0 - def Draw(self, index_offset, depth_offset = -0.00005): + def Draw(self, index_offset, ob_mat, depth_offset=0.00005): self.first_index = index_offset + gpu.matrix.push() + gpu.matrix.push_projection() + gpu.matrix.multiply_matrix(ob_mat) if self.draw_tris: + self.shader.bind() self.shader.uniform_int("offset", (index_offset,)) self.batch_tris.draw(self.shader) index_offset += len(self.tri_verts) - bgl.glDepthRange(depth_offset, 1 + depth_offset) + + winmat = gpu.matrix.get_projection_matrix() + is_persp = winmat[3][3] == 0.0 + if is_persp: + near = winmat[2][3] / (winmat[2][2] - 1.0) + far_ = winmat[2][3] / (winmat[2][2] + 1.0) + else: + near = (winmat[2][3] + 1.0) / winmat[2][2] + far_ = (winmat[2][3] - 1.0) / winmat[2][2] + + far_ += depth_offset + near += depth_offset + fn = (far_ - near) + winmat[2][2] = -(far_ + near) / fn + winmat[2][3] = (-2 * far_ * near) / fn + gpu.matrix.load_projection_matrix(winmat) if self.draw_edges: + self.shader.bind() self.shader.uniform_int("offset", (index_offset,)) #bgl.glLineWidth(3.0) self.batch_edges.draw(self.shader) @@ -359,10 +363,12 @@ class GPU_Indices_Mesh(): index_offset += len(self.edge_verts) if self.draw_verts: + self.shader.bind() self.shader.uniform_int("offset", (index_offset,)) self.batch_lverts.draw(self.shader) - bgl.glDepthRange(0.0, 1.0) + gpu.matrix.pop() + gpu.matrix.pop_projection() def get_tri_co(self, index): @@ -402,21 +408,16 @@ class GPU_Indices_Mesh(): GPU_Indices_Mesh._Hash.pop(self.ob_data) #print('mesh_del', self.obj.name) - - -def gpu_Indices_enable_state(): - import gpu - +def gpu_Indices_enable_state(winmat, viewmat): GPU_Indices_Mesh.init_opengl() gpu.matrix.push() gpu.matrix.push_projection() - gpu.matrix.load_projection_matrix(GPU_Indices_Mesh.P) + gpu.matrix.load_projection_matrix(winmat) + gpu.matrix.load_matrix(viewmat) GPU_Indices_Mesh.shader.bind() def gpu_Indices_restore_state(): - import gpu - gpu.matrix.pop() gpu.matrix.pop_projection() @@ -434,14 +435,5 @@ def gpu_Indices_use_clip_planes(rv3d, value): #bgl.glUniform4fv(GPU_Indices_Mesh.unif_clip_plane, 4, planes) #_restore_shader_state(PreviousGLState) - - -def gpu_Indices_set_ProjectionMatrix(P): - import gpu - - gpu.matrix.load_projection_matrix(P) - GPU_Indices_Mesh.P[:] = P - - def gpu_Indices_mesh_cache_clear(): GPU_Indices_Mesh._Hash.clear() |