Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2019-04-03 02:03:16 +0300
committermano-wii <germano.costa@ig.com.br>2019-04-03 02:03:16 +0300
commit78bf358bf0805f69bc7317c4c5d1e10c0ece4dca (patch)
tree5a0ee6ab4a6864592c95ae2f97b284bcf9b004cd
parentad2ee4cd6f97d2bfbe6a77e76baa5ad4de8e4b34 (diff)
Remove support for blender2.79blender2.7
The addon does not work on all OS. And now there is an improved version of it for blender2.8.
-rw-r--r--mesh_snap_utilities_line.py1191
-rw-r--r--modules/snap_context/__init__.py322
-rw-r--r--modules/snap_context/mesh_drawing.py518
-rw-r--r--modules/snap_context/resources/3D_vert.glsl26
-rw-r--r--modules/snap_context/resources/primitive_id_frag.glsl22
-rw-r--r--modules/snap_context/utils_projection.py212
-rw-r--r--modules/snap_context/utils_shader.py85
7 files changed, 0 insertions, 2376 deletions
diff --git a/mesh_snap_utilities_line.py b/mesh_snap_utilities_line.py
deleted file mode 100644
index 8f2f2a94..00000000
--- a/mesh_snap_utilities_line.py
+++ /dev/null
@@ -1,1191 +0,0 @@
-# ##### 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 3
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# Contact for more information about the Addon:
-# Email: germano.costa@ig.com.br
-# Twitter: wii_mano @mano_wii
-
-
-bl_info = {
- "name": "Snap Utilities Line",
- "author": "Germano Cavalcante",
- "version": (5, 7, 6),
- "blender": (2, 75, 0),
- "location": "View3D > TOOLS > Snap Utilities > snap utilities",
- "description": "Extends Blender Snap controls",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Modeling/Snap_Utils_Line",
- "category": "Mesh"}
-
-import bpy
-import bgl
-import bmesh
-from mathutils import Vector
-from mathutils.geometry import (
- intersect_point_line,
- intersect_line_line,
- intersect_line_plane,
- intersect_ray_tri
- )
-from bpy.types import (
- Operator,
- Panel,
- AddonPreferences,
- )
-from bpy.props import (
- BoolProperty,
- FloatProperty,
- FloatVectorProperty,
- StringProperty,
- )
-
-##DEBUG = False
-##if DEBUG:
-## from .snap_framebuffer_debug import screenTexture
-## from .snap_context import mesh_drawing
-
-
-def get_units_info(scale, unit_system, separate_units):
- if unit_system == 'METRIC':
- scale_steps = ((1000, 'km'), (1, 'm'), (1 / 100, 'cm'),
- (1 / 1000, 'mm'), (1 / 1000000, '\u00b5m'))
- elif unit_system == 'IMPERIAL':
- scale_steps = ((5280, 'mi'), (1, '\''),
- (1 / 12, '"'), (1 / 12000, 'thou'))
- scale /= 0.3048 # BU to feet
- else:
- scale_steps = ((1, ' BU'),)
- separate_units = False
-
- return (scale, scale_steps, separate_units)
-
-
-def convert_distance(val, units_info, precision=5):
- scale, scale_steps, separate_units = units_info
- sval = val * scale
- idx = 0
- while idx < len(scale_steps) - 1:
- if sval >= scale_steps[idx][0]:
- break
- idx += 1
- factor, suffix = scale_steps[idx]
- sval /= factor
- if not separate_units or idx == len(scale_steps) - 1:
- dval = str(round(sval, precision)) + suffix
- else:
- ival = int(sval)
- dval = str(round(ival, precision)) + suffix
- fval = sval - ival
- idx += 1
- while idx < len(scale_steps):
- fval *= scale_steps[idx - 1][0] / scale_steps[idx][0]
- if fval >= 1:
- dval += ' ' \
- + ("%.1f" % fval) \
- + scale_steps[idx][1]
- break
- idx += 1
-
- return dval
-
-
-def location_3d_to_region_2d(region, rv3d, coord):
- prj = rv3d.perspective_matrix * Vector((coord[0], coord[1], coord[2], 1.0))
- width_half = region.width / 2.0
- height_half = region.height / 2.0
- return Vector((width_half + width_half * (prj.x / prj.w),
- height_half + height_half * (prj.y / prj.w),
- prj.z / prj.w
- ))
-
-
-def out_Location(rv3d, region, orig, vector):
- view_matrix = rv3d.view_matrix
- v1 = Vector((int(view_matrix[0][0] * 1.5), int(view_matrix[0][1] * 1.5), int(view_matrix[0][2] * 1.5)))
- v2 = Vector((int(view_matrix[1][0] * 1.5), int(view_matrix[1][1] * 1.5), int(view_matrix[1][2] * 1.5)))
-
- hit = intersect_ray_tri(Vector((1, 0, 0)), Vector((0, 1, 0)), Vector(), (vector), (orig), False)
- if hit is None:
- hit = intersect_ray_tri(v1, v2, Vector(), (vector), (orig), False)
- if hit is None:
- hit = intersect_ray_tri(v1, v2, Vector(), (-vector), (orig), False)
- if hit is None:
- hit = Vector()
- return hit
-
-
-def get_closest_edge(bm, point, dist):
- r_edge = None
- for edge in bm.edges:
- v1 = edge.verts[0].co
- v2 = edge.verts[1].co
- # Test the BVH (AABB) first
- for i in range(3):
- if v1[i] <= v2[i]:
- isect = v1[i] - dist <= point[i] <= v2[i] + dist
- else:
- isect = v2[i] - dist <= point[i] <= v1[i] + dist
-
- if not isect:
- break
- else:
- ret = intersect_point_line(point, v1, v2)
-
- if ret[1] < 0.0:
- tmp = v1
- elif ret[1] > 1.0:
- tmp = v2
- else:
- tmp = ret[0]
-
- new_dist = (point - tmp).length
- if new_dist <= dist:
- dist = new_dist
- r_edge = edge
-
- return r_edge
-
-
-class SnapCache():
- bvert = None
- vco = None
-
- bedge = None
- v0 = None
- v1 = None
- vmid = None
- vperp = None
- v2d0 = None
- v2d1 = None
- v2dmid = None
- v2dperp = None
-
- bm_geom_selected = None
-
-
-def snap_utilities(
- sctx, obj,
- cache, context, obj_matrix_world,
- bm, mcursor,
- constrain = None,
- previous_vert = None,
- increment = 0.0):
-
- rv3d = context.region_data
- region = context.region
- scene = context.scene
- is_increment = False
- r_loc = None
- r_type = None
- r_len = 0.0
- bm_geom = None
-
- if cache.bm_geom_selected:
- try:
- cache.bm_geom_selected.select = False
- except ReferenceError as e:
- print(e)
-
- snp_obj, loc, elem = sctx.snap_get(mcursor)
- view_vector, orig = sctx.last_ray
-
- if not snp_obj:
- is_increment = True
- if constrain:
- end = orig + view_vector
- t_loc = intersect_line_line(constrain[0], constrain[1], orig, end)
- if t_loc is None:
- t_loc = constrain
- r_loc = t_loc[0]
- else:
- r_type = 'OUT'
- r_loc = out_Location(rv3d, region, orig, view_vector)
-
- elif snp_obj.data[0] != obj: #OUT
- r_loc = loc
-
- if constrain:
- is_increment = False
- r_loc = intersect_point_line(r_loc, constrain[0], constrain[1])[0]
- if not r_loc:
- r_loc = out_Location(rv3d, region, orig, view_vector)
- elif len(elem) == 1:
- is_increment = False
- r_type = 'VERT'
- elif len(elem) == 2:
- is_increment = True
- r_type = 'EDGE'
- else:
- is_increment = True
- r_type = 'FACE'
-
- elif len(elem) == 1:
- r_type = 'VERT'
- bm_geom = bm.verts[elem[0]]
-
- if cache.bvert != bm_geom:
- cache.bvert = bm_geom
- cache.vco = loc
- #cache.v2d = location_3d_to_region_2d(region, rv3d, cache.vco)
-
- if constrain:
- r_loc = intersect_point_line(cache.vco, constrain[0], constrain[1])[0]
- else:
- r_loc = cache.vco
-
- elif len(elem) == 2:
- v1 = bm.verts[elem[0]]
- v2 = bm.verts[elem[1]]
- bm_geom = bm.edges.get([v1, v2])
-
- if cache.bedge != bm_geom:
- cache.bedge = bm_geom
- cache.v0 = obj_matrix_world * v1.co
- cache.v1 = obj_matrix_world * v2.co
- cache.vmid = 0.5 * (cache.v0 + cache.v1)
- cache.v2d0 = location_3d_to_region_2d(region, rv3d, cache.v0)
- cache.v2d1 = location_3d_to_region_2d(region, rv3d, cache.v1)
- cache.v2dmid = location_3d_to_region_2d(region, rv3d, cache.vmid)
-
- if previous_vert and previous_vert not in {v1, v2}:
- pvert_co = obj_matrix_world * previous_vert.co
- perp_point = intersect_point_line(pvert_co, cache.v0, cache.v1)
- cache.vperp = perp_point[0]
- #factor = point_perpendicular[1]
- cache.v2dperp = location_3d_to_region_2d(region, rv3d, perp_point[0])
-
- #else: cache.v2dperp = None
-
- if constrain:
- t_loc = intersect_line_line(constrain[0], constrain[1], cache.v0, cache.v1)
- if t_loc is None:
- is_increment = True
- end = orig + view_vector
- t_loc = intersect_line_line(constrain[0], constrain[1], orig, end)
- r_loc = t_loc[0]
-
- elif cache.v2dperp and\
- abs(cache.v2dperp[0] - mcursor[0]) < 10 and abs(cache.v2dperp[1] - mcursor[1]) < 10:
- r_type = 'PERPENDICULAR'
- r_loc = cache.vperp
-
- elif abs(cache.v2dmid[0] - mcursor[0]) < 10 and abs(cache.v2dmid[1] - mcursor[1]) < 10:
- r_type = 'CENTER'
- r_loc = cache.vmid
-
- else:
- if increment and previous_vert in cache.bedge.verts:
- is_increment = True
-
- r_type = 'EDGE'
- r_loc = loc
-
- elif len(elem) == 3:
- is_increment = True
- r_type = 'FACE'
- tri = [
- bm.verts[elem[0]],
- bm.verts[elem[1]],
- bm.verts[elem[2]],
- ]
-
- faces = set(tri[0].link_faces).intersection(tri[1].link_faces, tri[2].link_faces)
- if len(faces) == 1:
- bm_geom = faces.pop()
- else:
- i = -2
- edge = None
- while not edge and i != 1:
- edge = bm.edges.get([tri[i], tri[i + 1]])
- i += 1
- if edge:
- for l in edge.link_loops:
- if l.link_loop_next.vert == tri[i] or l.link_loop_prev.vert == tri[i - 2]:
- bm_geom = l.face
- break
- else: # This should never happen!!!!
- raise
- bm_geom = faces.pop()
-
- r_loc = loc
-
- if constrain:
- is_increment = False
- r_loc = intersect_point_line(r_loc, constrain[0], constrain[1])[0]
-
- if previous_vert:
- pv_co = obj_matrix_world * previous_vert.co
- vec = r_loc - pv_co
- if is_increment and increment:
- r_len = round((1 / increment) * vec.length) * increment
- r_loc = r_len * vec.normalized() + pv_co
- else:
- r_len = vec.length
-
- if bm_geom:
- bm_geom.select = True
-
- cache.bm_geom_selected = bm_geom
-
- return r_loc, r_type, bm_geom, r_len
-
-
-def get_loose_linked_edges(bmvert):
- linked = [e for e in bmvert.link_edges if not e.link_faces]
- for e in linked:
- linked += [le for v in e.verts if not v.link_faces for le in v.link_edges if le not in linked]
- return linked
-
-
-def draw_line(self, obj, bm, bm_geom, location):
- split_faces = set()
-
- drawing_is_dirt = False
- update_edit_mesh = False
- tessface = False
-
- if bm_geom is None:
- vert = bm.verts.new(location)
- self.list_verts.append(vert)
-
- elif isinstance(bm_geom, bmesh.types.BMVert):
- if (bm_geom.co - location).length_squared < .001:
- if self.list_verts == [] or self.list_verts[-1] != bm_geom:
- self.list_verts.append(bm_geom)
- else:
- vert = bm.verts.new(location)
- self.list_verts.append(vert)
- drawing_is_dirt = True
-
- elif isinstance(bm_geom, bmesh.types.BMEdge):
- self.list_edges.append(bm_geom)
- ret = intersect_point_line(location, bm_geom.verts[0].co, bm_geom.verts[1].co)
-
- if (ret[0] - location).length_squared < .001:
- if ret[1] == 0.0:
- vert = bm_geom.verts[0]
- elif ret[1] == 1.0:
- vert = bm_geom.verts[1]
- else:
- edge, vert = bmesh.utils.edge_split(bm_geom, bm_geom.verts[0], ret[1])
- drawing_is_dirt = True
- self.list_verts.append(vert)
- # self.list_edges.append(edge)
-
- else: # constrain point is near
- vert = bm.verts.new(location)
- self.list_verts.append(vert)
- drawing_is_dirt = True
-
- elif isinstance(bm_geom, bmesh.types.BMFace):
- split_faces.add(bm_geom)
- vert = bm.verts.new(location)
- self.list_verts.append(vert)
- drawing_is_dirt = True
-
- # draw, split and create face
- if len(self.list_verts) >= 2:
- v1, v2 = self.list_verts[-2:]
- # v2_link_verts = [x for y in [a.verts for a in v2.link_edges] for x in y if x != v2]
- edge = bm.edges.get([v1, v2])
- if edge:
- self.list_edges.append(edge)
-
- else: # if v1 not in v2_link_verts:
- if not v2.link_edges:
- edge = bm.edges.new([v1, v2])
- self.list_edges.append(edge)
- drawing_is_dirt = True
- else: # split face
- v1_link_faces = v1.link_faces
- v2_link_faces = v2.link_faces
- if v1_link_faces and v2_link_faces:
- split_faces.update(set(v1_link_faces).intersection(v2_link_faces))
-
- else:
- if v1_link_faces:
- faces = v1_link_faces
- co2 = v2.co.copy()
- else:
- faces = v2_link_faces
- co2 = v1.co.copy()
-
- for face in faces:
- if bmesh.geometry.intersect_face_point(face, co2):
- co = co2 - face.calc_center_median()
- if co.dot(face.normal) < 0.001:
- split_faces.add(face)
-
- if split_faces:
- edge = bm.edges.new([v1, v2])
- self.list_edges.append(edge)
- ed_list = get_loose_linked_edges(v2)
- for face in split_faces:
- facesp = bmesh.utils.face_split_edgenet(face, ed_list)
- del split_faces
- update_edit_mesh = True
- tessface = True
- else:
- if self.intersect:
- facesp = bmesh.ops.connect_vert_pair(bm, verts=[v1, v2], verts_exclude=bm.verts)
- # print(facesp)
- if not self.intersect or not facesp['edges']:
- edge = bm.edges.new([v1, v2])
- self.list_edges.append(edge)
- drawing_is_dirt = True
- else:
- for edge in facesp['edges']:
- self.list_edges.append(edge)
- update_edit_mesh = True
- tessface = True
-
- # create face
- if self.create_face:
- ed_list = set(self.list_edges)
- for edge in v2.link_edges:
- for vert in edge.verts:
- if vert != v2 and vert in self.list_verts:
- ed_list.add(edge)
- break
- else:
- continue
- # Inner loop had a break, break the outer
- break
-
- ed_list.update(get_loose_linked_edges(v2))
-
- bmesh.ops.edgenet_fill(bm, edges=list(ed_list))
- update_edit_mesh = True
- tessface = True
- # print('face created')
- if update_edit_mesh:
- bmesh.update_edit_mesh(obj.data, tessface = tessface)
- self.sctx.update_drawn_snap_object(self.snap_obj)
- #bm.verts.index_update()
- elif drawing_is_dirt:
- self.obj.update_from_editmode()
- self.sctx.update_drawn_snap_object(self.snap_obj)
-
- return [obj.matrix_world * v.co for v in self.list_verts]
-
-
-class NavigationKeys:
- def __init__(self, context):
- # TO DO:
- # 'View Orbit', 'View Pan', 'NDOF Orbit View', 'NDOF Pan View'
- self._rotate = set()
- self._move = set()
- self._zoom = set()
- for key in context.window_manager.keyconfigs.user.keymaps['3D View'].keymap_items:
- if key.idname == 'view3d.rotate':
- #self.keys_rotate[key.id]={'Alt': key.alt, 'Ctrl': key.ctrl, 'Shift':key.shift, 'Type':key.type, 'Value':key.value}
- self._rotate.add((key.alt, key.ctrl, key.shift, key.type, key.value))
- if key.idname == 'view3d.move':
- self._move.add((key.alt, key.ctrl, key.shift, key.type, key.value))
- if key.idname == 'view3d.zoom':
- if key.type == 'WHEELINMOUSE':
- self._zoom.add((key.alt, key.ctrl, key.shift, 'WHEELUPMOUSE', key.value, key.properties.delta))
- elif key.type == 'WHEELOUTMOUSE':
- self._zoom.add((key.alt, key.ctrl, key.shift, 'WHEELDOWNMOUSE', key.value, key.properties.delta))
- else:
- self._zoom.add((key.alt, key.ctrl, key.shift, key.type, key.value, key.properties.delta))
-
-
-class CharMap:
- ascii = {
- ".", ",", "-", "+", "1", "2", "3",
- "4", "5", "6", "7", "8", "9", "0",
- "c", "m", "d", "k", "h", "a",
- " ", "/", "*", "'", "\""
- # "="
- }
- type = {
- 'BACK_SPACE', 'DEL',
- 'LEFT_ARROW', 'RIGHT_ARROW'
- }
-
- @staticmethod
- def modal(self, context, event):
- c = event.ascii
- if c:
- if c == ",":
- c = "."
- self.length_entered = self.length_entered[:self.line_pos] + c + self.length_entered[self.line_pos:]
- self.line_pos += 1
- if self.length_entered:
- if event.type == 'BACK_SPACE':
- self.length_entered = self.length_entered[:self.line_pos - 1] + self.length_entered[self.line_pos:]
- self.line_pos -= 1
-
- elif event.type == 'DEL':
- self.length_entered = self.length_entered[:self.line_pos] + self.length_entered[self.line_pos + 1:]
-
- elif event.type == 'LEFT_ARROW':
- self.line_pos = (self.line_pos - 1) % (len(self.length_entered) + 1)
-
- elif event.type == 'RIGHT_ARROW':
- self.line_pos = (self.line_pos + 1) % (len(self.length_entered) + 1)
-
-
-class SnapUtilitiesLine(Operator):
- bl_idname = "mesh.snap_utilities_line"
- bl_label = "Line Tool"
- bl_description = "Draw edges. Connect them to split faces"
- bl_options = {'REGISTER', 'UNDO'}
-
- constrain_keys = {
- 'X': Vector((1, 0, 0)),
- 'Y': Vector((0, 1, 0)),
- 'Z': Vector((0, 0, 1)),
- 'RIGHT_SHIFT': 'shift',
- 'LEFT_SHIFT': 'shift',
- }
-
- @classmethod
- def poll(cls, context):
- preferences = context.user_preferences.addons[__name__].preferences
- return (context.mode in {'EDIT_MESH', 'OBJECT'} and
- preferences.create_new_obj or
- (context.object is not None and
- context.object.type == 'MESH'))
-
-
- def draw_callback_px(self, context):
- # draw 3d point OpenGL in the 3D View
- bgl.glEnable(bgl.GL_BLEND)
- bgl.glDisable(bgl.GL_DEPTH_TEST)
- # bgl.glPushMatrix()
- # bgl.glMultMatrixf(self.obj_glmatrix)
-
-## if DEBUG:
-## mesh_drawing._store_current_shader_state(mesh_drawing.PreviousGLState)
-## self.screen.Draw(self.sctx._texture)
-## mesh_drawing._restore_shader_state(mesh_drawing.PreviousGLState)
-
- if self.vector_constrain:
- vc = self.vector_constrain
- if hasattr(self, 'preloc') and self.type in {'VERT', 'FACE'}:
- bgl.glColor4f(1.0, 1.0, 1.0, 0.5)
- bgl.glPointSize(5)
- bgl.glBegin(bgl.GL_POINTS)
- bgl.glVertex3f(*self.preloc)
- bgl.glEnd()
- if vc[2] == 'X':
- Color4f = (self.axis_x_color + (1.0,))
- elif vc[2] == 'Y':
- Color4f = (self.axis_y_color + (1.0,))
- elif vc[2] == 'Z':
- Color4f = (self.axis_z_color + (1.0,))
- else:
- Color4f = self.constrain_shift_color
- else:
- if self.type == 'OUT':
- Color4f = self.out_color
- elif self.type == 'FACE':
- Color4f = self.face_color
- elif self.type == 'EDGE':
- Color4f = self.edge_color
- elif self.type == 'VERT':
- Color4f = self.vert_color
- elif self.type == 'CENTER':
- Color4f = self.center_color
- elif self.type == 'PERPENDICULAR':
- Color4f = self.perpendicular_color
- else: # self.type == None
- Color4f = self.out_color
-
- bgl.glColor4f(*Color4f)
- bgl.glPointSize(10)
- bgl.glBegin(bgl.GL_POINTS)
- bgl.glVertex3f(*self.location)
- bgl.glEnd()
-
- # draw 3d line OpenGL in the 3D View
- bgl.glEnable(bgl.GL_DEPTH_TEST)
- bgl.glDepthRange(0, 0.9999)
- bgl.glColor4f(1.0, 0.8, 0.0, 1.0)
- bgl.glLineWidth(2)
- bgl.glEnable(bgl.GL_LINE_STIPPLE)
- bgl.glBegin(bgl.GL_LINE_STRIP)
- for vert_co in self.list_verts_co:
- bgl.glVertex3f(*vert_co)
- bgl.glVertex3f(*self.location)
- bgl.glEnd()
-
- # restore opengl defaults
- # bgl.glPopMatrix()
- bgl.glDepthRange(0, 1)
- bgl.glPointSize(1)
- bgl.glLineWidth(1)
- bgl.glDisable(bgl.GL_BLEND)
- bgl.glDisable(bgl.GL_LINE_STIPPLE)
- bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-
-
- def modal_navigation(self, context, event):
- evkey = (event.alt, event.ctrl, event.shift, event.type, event.value)
- if evkey in self.navigation_keys._rotate:
- bpy.ops.view3d.rotate('INVOKE_DEFAULT')
- return True
- elif evkey in self.navigation_keys._move:
- if event.shift and self.vector_constrain and \
- self.vector_constrain[2] in {'RIGHT_SHIFT', 'LEFT_SHIFT', 'shift'}:
- self.vector_constrain = None
- bpy.ops.view3d.move('INVOKE_DEFAULT')
- return True
- else:
- for key in self.navigation_keys._zoom:
- if evkey == key[0:5]:
- if True: # TODO: Use Zoom to mouse position
- v3d = context.space_data
- dist_range = (v3d.clip_start, v3d.clip_end)
- rv3d = context.region_data
- if (key[5] < 0 and rv3d.view_distance < dist_range[1]) or\
- (key[5] > 0 and rv3d.view_distance > dist_range[0]):
- rv3d.view_location += key[5] * (self.location - rv3d.view_location) / 6
- rv3d.view_distance -= key[5] * rv3d.view_distance / 6
- else:
- bpy.ops.view3d.zoom('INVOKE_DEFAULT', delta = key[5])
- return True
- #break
-
- return False
-
-
- def modal(self, context, event):
- if self.modal_navigation(context, event):
- return {'RUNNING_MODAL'}
-
- context.area.tag_redraw()
-
- if event.ctrl and event.type == 'Z' and event.value == 'PRESS':
- bpy.ops.ed.undo()
- self.vector_constrain = None
- self.list_verts_co = []
- self.list_verts = []
- self.list_edges = []
- self.obj = bpy.context.active_object
- self.obj_matrix = self.obj.matrix_world.copy()
- self.bm = bmesh.from_edit_mesh(self.obj.data)
- self.sctx.update_drawn_snap_object(self.snap_obj)
- return {'RUNNING_MODAL'}
-
- if event.type == 'MOUSEMOVE' or self.bool_update:
- if self.rv3d.view_matrix != self.rotMat:
- self.rotMat = self.rv3d.view_matrix.copy()
- self.bool_update = True
- self.cache.bedge = None
- else:
- self.bool_update = False
-
- mval = Vector((event.mouse_region_x, event.mouse_region_y))
-
- self.location, self.type, self.geom, self.len = snap_utilities(
- self.sctx, self.obj, self.cache, context, self.obj_matrix,
- self.bm, mval,
- constrain = self.vector_constrain,
- previous_vert = (self.list_verts[-1] if self.list_verts else None),
- increment = self.incremental
- )
- if self.snap_to_grid and self.type == 'OUT':
- loc = self.location / self.rd
- self.location = Vector((round(loc.x),
- round(loc.y),
- round(loc.z))) * self.rd
-
- if self.keyf8 and self.list_verts_co:
- lloc = self.list_verts_co[-1]
- view_vec, orig = self.sctx.last_ray
- location = intersect_point_line(lloc, orig, (orig + view_vec))
- vec = (location[0] - lloc)
- ax, ay, az = abs(vec.x), abs(vec.y), abs(vec.z)
- vec.x = ax > ay > az or ax > az > ay
- vec.y = ay > ax > az or ay > az > ax
- vec.z = az > ay > ax or az > ax > ay
- if vec == Vector():
- self.vector_constrain = None
- else:
- vc = lloc + vec
- try:
- if vc != self.vector_constrain[1]:
- type = 'X' if vec.x else 'Y' if vec.y else 'Z' if vec.z else 'shift'
- self.vector_constrain = [lloc, vc, type]
- except:
- type = 'X' if vec.x else 'Y' if vec.y else 'Z' if vec.z else 'shift'
- self.vector_constrain = [lloc, vc, type]
-
- if event.value == 'PRESS':
- if self.list_verts_co and (event.ascii in CharMap.ascii or event.type in CharMap.type):
- CharMap.modal(self, context, event)
-
- elif event.type in self.constrain_keys:
- self.bool_update = True
- if self.vector_constrain and self.vector_constrain[2] == event.type:
- self.vector_constrain = ()
-
- else:
- if event.shift:
- if isinstance(self.geom, bmesh.types.BMEdge):
- if self.list_verts:
- loc = self.list_verts_co[-1]
- self.vector_constrain = (loc, loc + self.geom.verts[1].co -
- self.geom.verts[0].co, event.type)
- else:
- self.vector_constrain = [self.obj_matrix * v.co for
- v in self.geom.verts] + [event.type]
- else:
- if self.list_verts:
- loc = self.list_verts_co[-1]
- else:
- loc = self.location
- self.vector_constrain = [loc, loc + self.constrain_keys[event.type]] + [event.type]
-
- elif event.type == 'LEFTMOUSE':
- point = self.obj_matinv * self.location
- # with constraint the intersection can be in a different element of the selected one
- if self.vector_constrain and self.geom:
- geom2 = get_closest_edge(self.bm, point, 0.001)
- else:
- geom2 = self.geom
-
- self.vector_constrain = None
- self.list_verts_co = draw_line(self, self.obj, self.bm, geom2, point)
- bpy.ops.ed.undo_push(message="Undo draw line*")
-
- elif event.type == 'TAB':
- self.keytab = self.keytab is False
- if self.keytab:
- self.sctx.set_snap_mode(False, False, True)
- context.tool_settings.mesh_select_mode = (False, False, True)
- else:
- self.sctx.set_snap_mode(True, True, True)
- context.tool_settings.mesh_select_mode = (True, True, True)
-
- elif event.type == 'F8':
- self.vector_constrain = None
- self.keyf8 = self.keyf8 is False
-
- elif event.value == 'RELEASE':
- if event.type in {'RET', 'NUMPAD_ENTER'}:
- if self.length_entered != "" and self.list_verts_co:
- try:
- text_value = bpy.utils.units.to_value(self.unit_system, 'LENGTH', self.length_entered)
- vector = (self.location - self.list_verts_co[-1]).normalized()
- location = (self.list_verts_co[-1] + (vector * text_value))
- G_location = self.obj_matinv * location
- self.list_verts_co = draw_line(self, self.obj, self.bm, self.geom, G_location)
- self.length_entered = ""
- self.vector_constrain = None
-
- except: # ValueError:
- self.report({'INFO'}, "Operation not supported yet")
-
- elif event.type in {'RIGHTMOUSE', 'ESC'}:
- if self.list_verts_co == [] or event.type == 'ESC':
- del self.bm
- del self.list_edges
- del self.list_verts
- del self.list_verts_co
-
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
- context.area.header_text_set("")
- self.sctx.free()
-
- #restore initial state
- context.user_preferences.view.use_rotate_around_active = self.use_rotate_around_active
- context.tool_settings.mesh_select_mode = self.select_mode
- if not self.is_editmode:
- bpy.ops.object.editmode_toggle()
-
- return {'FINISHED'}
- else:
- self.vector_constrain = None
- self.list_edges = []
- self.list_verts = []
- self.list_verts_co = []
-
- a = ""
- if self.list_verts_co:
- if self.length_entered:
- pos = self.line_pos
- a = 'length: ' + self.length_entered[:pos] + '|' + self.length_entered[pos:]
- else:
- length = self.len
- length = convert_distance(length, self.uinfo)
- a = 'length: ' + length
-
- context.area.header_text_set(
- "hit: %.3f %.3f %.3f %s" % (self.location[0],
- self.location[1], self.location[2], a)
- )
-
- return {'RUNNING_MODAL'}
-
- def invoke(self, context, event):
- if context.space_data.type == 'VIEW_3D':
- # print('name', __name__, __package__)
- preferences = context.user_preferences.addons[__name__].preferences
-
- #Store the preferences that will be used in modal
- self.intersect = preferences.intersect
- self.create_face = preferences.create_face
- self.outer_verts = preferences.outer_verts
- self.snap_to_grid = preferences.increments_grid
-
- self.out_color = preferences.out_color
- self.face_color = preferences.face_color
- self.edge_color = preferences.edge_color
- self.vert_color = preferences.vert_color
- self.center_color = preferences.center_color
- self.perpendicular_color = preferences.perpendicular_color
- self.constrain_shift_color = preferences.constrain_shift_color
-
- self.axis_x_color = tuple(context.user_preferences.themes[0].user_interface.axis_x)
- self.axis_y_color = tuple(context.user_preferences.themes[0].user_interface.axis_y)
- self.axis_z_color = tuple(context.user_preferences.themes[0].user_interface.axis_z)
-
- if context.mode == 'OBJECT' and \
- (preferences.create_new_obj or context.object is None or context.object.type != 'MESH'):
-
- mesh = bpy.data.meshes.new("")
- obj = bpy.data.objects.new("", mesh)
- context.scene.objects.link(obj)
- context.scene.objects.active = obj
-
- #Store current state
- self.is_editmode = context.object.data.is_editmode
- self.use_rotate_around_active = context.user_preferences.view.use_rotate_around_active
- self.select_mode = context.tool_settings.mesh_select_mode[:]
-
- #Modify the current state
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='DESELECT')
- context.user_preferences.view.use_rotate_around_active = True
- context.tool_settings.mesh_select_mode = (True, True, True)
- context.space_data.use_occlude_geometry = True
-
- #Configure the unit of measure
- scale = context.scene.unit_settings.scale_length
- self.unit_system = context.scene.unit_settings.system
- separate_units = context.scene.unit_settings.use_separate
- self.uinfo = get_units_info(scale, self.unit_system, separate_units)
-
- scale /= context.space_data.grid_scale * preferences.relative_scale
- self.rd = bpy.utils.units.to_value(self.unit_system, 'LENGTH', str(1 / scale))
-
- self.incremental = bpy.utils.units.to_value(self.unit_system, 'LENGTH', str(preferences.incremental))
-
- #Store values from 3d view context
- self.rv3d = context.region_data
- self.rotMat = self.rv3d.view_matrix.copy()
- self.obj = bpy.context.active_object
- self.obj_matrix = self.obj.matrix_world.copy()
- self.obj_matinv = self.obj_matrix.inverted()
- # self.obj_glmatrix = bgl.Buffer(bgl.GL_FLOAT, [4, 4], self.obj_matrix.transposed())
- self.bm = bmesh.from_edit_mesh(self.obj.data) #remove at end
- self.cache = SnapCache()
-
- #init these variables to avoid errors
- self.prevloc = Vector()
- self.location = Vector()
- self.list_verts = []
- self.list_edges = []
- self.list_verts_co = []
- self.bool_update = False
- self.vector_constrain = ()
- self.navigation_keys = NavigationKeys(context)
- self.type = 'OUT'
- self.len = 0
- self.length_entered = ""
- self.line_pos = 0
- self.bm_geom_selected = None
-
- #Init event variables
- self.keytab = False
- self.keyf8 = False
-
- #Init Snap Context
- from snap_context import SnapContext
-
- self.sctx = SnapContext(context.region, context.space_data)
- self.sctx.set_pixel_dist(12)
- self.sctx.use_clip_planes(True)
-
- act_base = context.active_base
-
- if self.outer_verts:
- for base in context.visible_bases:
- if base != act_base:
- self.sctx.add_obj(base.object, base.object.matrix_world)
-
- self.snap_obj = self.sctx.add_obj(act_base.object, act_base.object.matrix_world)
-
- self.snap_face = context.space_data.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}
- self.sctx.set_snap_mode(True, True, self.snap_face)
-
- #modals
- self._handle = bpy.types.SpaceView3D.draw_handler_add(self.draw_callback_px, (context,), 'WINDOW', 'POST_VIEW')
- context.window_manager.modal_handler_add(self)
-
- return {'RUNNING_MODAL'}
- else:
- self.report({'WARNING'}, "Active space must be a View3d")
- return {'CANCELLED'}
-
-
-class PanelSnapUtilities(Panel):
- bl_space_type = "VIEW_3D"
- bl_region_type = "TOOLS"
- bl_category = "Snap Utilities"
- bl_label = "Snap Utilities"
-
- @classmethod
- def poll(cls, context):
- preferences = context.user_preferences.addons[__name__].preferences
- return (context.mode in {'EDIT_MESH', 'OBJECT'} and
- preferences.create_new_obj or
- (context.object is not None and
- context.object.type == 'MESH'))
-
- def draw(self, context):
- layout = self.layout
- TheCol = layout.column(align=True)
- TheCol.operator("mesh.snap_utilities_line", text="Line", icon="GREASEPENCIL")
-
- addon_prefs = context.user_preferences.addons[__name__].preferences
- expand = addon_prefs.expand_snap_settings
- icon = "TRIA_DOWN" if expand else "TRIA_RIGHT"
-
- box = layout.box()
- box.prop(addon_prefs, "expand_snap_settings", icon=icon,
- text="Settings:", emboss=False)
- if expand:
- box.prop(addon_prefs, "outer_verts")
- box.prop(addon_prefs, "incremental")
- box.prop(addon_prefs, "increments_grid")
- if addon_prefs.increments_grid:
- box.prop(addon_prefs, "relative_scale")
- box.label(text="Line Tool:")
- box.prop(addon_prefs, "intersect")
- box.prop(addon_prefs, "create_face")
- box.prop(addon_prefs, "create_new_obj")
-
-
-# Add-ons Preferences Update Panel
-
-# Define Panel classes for updating
-panels = (
- PanelSnapUtilities,
- )
-
-
-def update_panel(self, context):
- message = "Snap Utilities Line: Updating Panel locations has failed"
- addon_prefs = context.user_preferences.addons[__name__].preferences
- try:
- for panel in panels:
- if addon_prefs.category != panel.bl_category:
- if "bl_rna" in panel.__dict__:
- bpy.utils.unregister_class(panel)
-
- panel.bl_category = addon_prefs.category
- bpy.utils.register_class(panel)
-
- except Exception as e:
- print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e))
- pass
-
-
-class SnapAddonPreferences(AddonPreferences):
- # this must match the addon name, use '__package__'
- # when defining this in a submodule of a python package.
- bl_idname = __name__
-
- intersect = BoolProperty(
- name="Intersect",
- description="Intersects created line with the existing edges, "
- "even if the lines do not intersect",
- default=True
- )
- create_new_obj = BoolProperty(
- name="Create a new object",
- description="If have not a active object, or the active object "
- "is not in edit mode, it creates a new object",
- default=False
- )
- create_face = BoolProperty(
- name="Create faces",
- description="Create faces defined by enclosed edges",
- default=False
- )
- outer_verts = BoolProperty(
- name="Snap to outer vertices",
- description="The vertices of the objects are not activated also snapped",
- default=True
- )
- expand_snap_settings = BoolProperty(
- name="Expand",
- description="Expand, to display the settings",
- default=False
- )
- expand_color_settings = BoolProperty(
- name="Color Settings",
- description="Expand, to display the color settings",
- default=False
- )
- increments_grid = BoolProperty(
- name="Increments of Grid",
- description="Snap to increments of grid",
- default=False
- )
- category = StringProperty(
- name="Category",
- description="Choose a name for the category of the panel",
- default="Snap Utilities",
- update=update_panel
- )
- incremental = FloatProperty(
- name="Incremental",
- description="Snap in defined increments",
- default=0,
- min=0,
- step=1,
- precision=3
- )
- relative_scale = FloatProperty(
- name="Relative Scale",
- description="Value that divides the global scale",
- default=1,
- min=0,
- step=1,
- precision=3
- )
- out_color = FloatVectorProperty(
- name="OUT",
- default=(0.0, 0.0, 0.0, 0.5),
- size=4,
- subtype="COLOR",
- min=0, max=1
- )
- face_color = FloatVectorProperty(
- name="FACE",
- default=(1.0, 0.8, 0.0, 1.0),
- size=4,
- subtype="COLOR",
- min=0, max=1
- )
- edge_color = FloatVectorProperty(
- name="EDGE",
- default=(0.0, 0.8, 1.0, 1.0),
- size=4,
- subtype="COLOR",
- min=0, max=1
- )
- vert_color = FloatVectorProperty(
- name="VERT",
- default=(1.0, 0.5, 0.0, 1.0),
- size=4,
- subtype="COLOR",
- min=0, max=1
- )
- center_color = FloatVectorProperty(
- name="CENTER",
- default=(1.0, 0.0, 1.0, 1.0),
- size=4,
- subtype="COLOR",
- min=0, max=1
- )
- perpendicular_color = FloatVectorProperty(
- name="PERPENDICULAR",
- default=(0.1, 0.5, 0.5, 1.0),
- size=4,
- subtype="COLOR",
- min=0, max=1
- )
- constrain_shift_color = FloatVectorProperty(
- name="SHIFT CONSTRAIN",
- default=(0.8, 0.5, 0.4, 1.0),
- size=4,
- subtype="COLOR",
- min=0, max=1
- )
-
- def draw(self, context):
- layout = self.layout
- icon = "TRIA_DOWN" if self.expand_color_settings else "TRIA_RIGHT"
-
- box = layout.box()
- box.prop(self, "expand_color_settings", icon=icon, toggle=True, emboss=False)
- if self.expand_color_settings:
- split = box.split()
-
- col = split.column()
- col.prop(self, "out_color")
- col.prop(self, "constrain_shift_color")
- col = split.column()
- col.prop(self, "face_color")
- col.prop(self, "center_color")
- col = split.column()
- col.prop(self, "edge_color")
- col.prop(self, "perpendicular_color")
- col = split.column()
- col.prop(self, "vert_color")
-
- row = layout.row()
-
- col = row.column(align=True)
- box = col.box()
- box.label(text="Snap Items:")
- box.prop(self, "incremental")
- box.prop(self, "outer_verts")
- box.prop(self, "increments_grid")
- if self.increments_grid:
- box.prop(self, "relative_scale")
- else:
- box.separator()
- box.separator()
-
- col = row.column(align=True)
- box = col.box()
- box.label(text="Line Tool:")
- box.prop(self, "intersect")
- box.prop(self, "create_face")
- box.prop(self, "create_new_obj")
- box.separator()
- box.separator()
-
- row = layout.row()
- col = row.column()
- col.label(text="Tab Category:")
- col.prop(self, "category", text="")
-
-
-def register():
- bpy.utils.register_class(SnapAddonPreferences)
- bpy.utils.register_class(SnapUtilitiesLine)
- bpy.utils.register_class(PanelSnapUtilities)
- update_panel(None, bpy.context)
-
-
-def unregister():
- bpy.utils.unregister_class(PanelSnapUtilities)
- bpy.utils.unregister_class(SnapUtilitiesLine)
- bpy.utils.unregister_class(SnapAddonPreferences)
-
-
-if __name__ == "__main__":
- __name__ = "mesh_snap_utilities_line"
- register()
diff --git a/modules/snap_context/__init__.py b/modules/snap_context/__init__.py
deleted file mode 100644
index 77e84726..00000000
--- a/modules/snap_context/__init__.py
+++ /dev/null
@@ -1,322 +0,0 @@
-# ##### 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 3
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-__all__ = (
- "SnapContext",
- )
-
-import bgl
-from mathutils import Vector
-
-VERT = 1
-EDGE = 2
-FACE = 4
-
-
-class _Internal:
- from .mesh_drawing import (
- gpu_Indices_enable_state,
- gpu_Indices_restore_state,
- gpu_Indices_use_clip_planes,
- gpu_Indices_set_ProjectionMatrix,
- )
-
- from .utils_projection import (
- region_2d_to_orig_and_view_vector,
- intersect_boundbox_threshold,
- intersect_ray_segment_fac,
- project_co_v3,
- )
-
- from mathutils.geometry import intersect_line_plane
-
-
-class _SnapObjectData():
- __slots__ = ('data', 'mat')
- def __init__(self, data, omat):
- self.data = data
- self.mat = omat
-
-
-class SnapContext():
- """
- Initializes the snap context with the region and space where the snap objects will be added.
-
- .. note::
- After the context has been created, add the objects with the `add_obj` method.
-
- :arg region: region of the 3D viewport, typically bpy.context.region.
- :type region: :class:`bpy.types.Region`
- :arg space: 3D region data, typically bpy.context.space_data.
- :type space: :class:`bpy.types.SpaceView3D`
- """
-
- def __init__(self, region, space):
- import gpu
- import ctypes
-
- self.freed = False
- self.snap_objects = []
- self.drawn_count = 0
- self._offset_cur = 1 # Starts with index 1
- self.region = region
- self.rv3d = space.region_3d
-
- 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))
- self._snap_mode = VERT | EDGE | FACE
-
- self.set_pixel_dist(12)
-
- self._offscreen = gpu.offscreen.new(self.region.width, self.region.height)
-
- self._texture = self._offscreen.color_texture
- bgl.glBindTexture(bgl.GL_TEXTURE_2D, self._texture)
-
- NULL = bgl.Buffer(bgl.GL_INT, 1, (ctypes.c_int32 * 1).from_address(0))
- bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_R32UI, self.region.width, self.region.height, 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)
- bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
-
- self.winsize = Vector((self._offscreen.width, self._offscreen.height))
-
- ## PRIVATE ##
-
- def _get_snap_obj_by_index(self, index):
- for snap_obj in self.snap_objects[:self.drawn_count]:
- data = snap_obj.data[1]
- if index < data.first_index + data.get_tot_elems():
- return snap_obj
- return None
-
- def _get_nearest_index(self):
- loc = [self._dist_px, self._dist_px]
- d = 1
- m = self.threshold
- max = 2 * m - 1
- offset = 1
- last_snap_obj = None
- r_value = 0
- while m < max:
- for i in range(2):
- while 2 * loc[i] * d < m:
- value = int(self._snap_buffer[loc[0]][loc[1]])
- loc[i] += d
- if value >= offset:
- r_value = value
- snap_obj = self._get_snap_obj_by_index(r_value)
-
- if self._snap_mode & FACE and self._snap_mode & (VERT | EDGE) and last_snap_obj != snap_obj:
- data = snap_obj.data[1]
- offset = data.first_index + data.num_tris
- last_snap_obj = snap_obj
- continue
- return snap_obj, r_value
- d = -d
- m += 4 * self._dist_px * d + 1
-
- return last_snap_obj, r_value
-
- def _get_loc(self, snap_obj, index):
- index -= snap_obj.data[1].first_index
- gpu_data = snap_obj.data[1]
-
- if gpu_data.draw_tris:
- if index < snap_obj.data[1].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)]
- nor = (tri_co[1] - tri_co[0]).cross(tri_co[2] - tri_co[0])
- return _Internal.intersect_line_plane(self.last_ray[1], self.last_ray[1] + self.last_ray[0], tri_co[0], nor), tri_verts
-
- index -= gpu_data.num_tris
-
- if gpu_data.draw_edges:
- if index < snap_obj.data[1].num_edges:
- edge_verts = gpu_data.get_edge_verts(index)
- edge_co = [snap_obj.mat * Vector(v) for v in gpu_data.get_edge_co(index)]
- fac = _Internal.intersect_ray_segment_fac(*edge_co, *self.last_ray)
-
- if (self._snap_mode) & VERT and (fac < 0.25 or fac > 0.75):
- co = edge_co[0] if fac < 0.5 else edge_co[1]
- proj_co = _Internal.project_co_v3(self, co)
- dist = self.mval - proj_co
- if abs(dist.x) < self._dist_px and abs(dist.y) < self._dist_px:
- return co, (edge_verts[0] if fac < 0.5 else edge_verts[1],)
-
- if fac <= 0.0:
- co = edge_co[0]
- elif fac >= 1.0:
- co = edge_co[1]
- else:
- co = edge_co[0] + fac * (edge_co[1] - edge_co[0])
-
- return co, edge_verts
-
- index -= gpu_data.num_edges
-
- if gpu_data.draw_verts:
- if index < snap_obj.data[1].num_verts:
- return snap_obj.mat * Vector(gpu_data.get_loosevert_co(index)), (gpu_data.get_loosevert_index(index),)
-
- return None, None
-
-
- def _get_snap_obj_by_obj(self, obj):
- for snap_obj in self.snap_objects:
- if obj == snap_obj.data[0]:
- return snap_obj
-
- def __del__(self):
- if not self.freed:
- self._offscreen.free()
- # Some objects may still be being referenced
- for snap_obj in self.snap_objects:
- del snap_obj.data
- del snap_obj.mat
- del snap_obj
- del self.snap_objects
-
- ## PUBLIC ##
-
- def update_all(self):
- self.drawn_count = 0
- self._offset_cur = 1
-
- bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
- bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)
-
- def update_drawn_snap_object(self, snap_obj):
- if len(snap_obj.data) > 1:
- del snap_obj.data[1:]
- #self.update_all()
- # Update on next snap_get call #
- self.proj_mat = None
-
- def use_clip_planes(self, value):
- _Internal.gpu_Indices_use_clip_planes(self.rv3d, value)
-
- def set_pixel_dist(self, dist_px):
- 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_FLOAT, (self.threshold, self.threshold))
-
- def set_snap_mode(self, snap_to_vert, snap_to_edge, snap_to_face):
- snap_mode = 0
- if snap_to_vert:
- snap_mode |= VERT
- if snap_to_edge:
- snap_mode |= EDGE
- if snap_to_face:
- snap_mode |= FACE
-
- if snap_mode != self._snap_mode:
- self._snap_mode = snap_mode
- self.update_all()
-
- def add_obj(self, obj, matrix):
- matrix = matrix.copy()
- snap_obj = self._get_snap_obj_by_obj(obj)
- if not snap_obj:
- self.snap_objects.append(_SnapObjectData([obj], matrix))
- else:
- self.snap_objects.append(_SnapObjectData(snap_obj.data, matrix))
-
- return self.snap_objects[-1]
-
- def get_ray(self, mval):
- 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):
- ret = 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)
-
- 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_all()
-
- 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]
- bbmin = Vector(obj.bound_box[0])
- bbmax = Vector(obj.bound_box[6])
-
- if bbmin != bbmax:
- MVP = proj_mat * snap_obj.mat
- mat_inv = snap_obj.mat.inverted()
- 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
- snap_obj.data.append(GPU_Indices_Mesh(obj, snap_face, snap_edge, snap_vert))
- snap_obj.data[1].set_draw_mode(snap_face, snap_edge, snap_vert)
- snap_obj.data[1].set_ModelViewMatrix(snap_obj.mat)
- snap_obj.data[1].Draw(self._offset_cur)
- self._offset_cur += snap_obj.data[1].get_tot_elems()
-
- self.snap_objects[self.drawn_count], self.snap_objects[i] = self.snap_objects[i], self.snap_objects[self.drawn_count]
- 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)
-
- snap_obj, index = self._get_nearest_index()
- #print(index)
- if snap_obj:
- ret = self._get_loc(snap_obj, index)
-
- self._offscreen.unbind()
- _Internal.gpu_Indices_restore_state()
-
- return snap_obj, ret[0], ret[1]
-
- def free(self):
- self.__del__()
- self.freed = True
diff --git a/modules/snap_context/mesh_drawing.py b/modules/snap_context/mesh_drawing.py
deleted file mode 100644
index bdfca4d3..00000000
--- a/modules/snap_context/mesh_drawing.py
+++ /dev/null
@@ -1,518 +0,0 @@
-# ##### 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 3
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-import bgl
-import bmesh
-import numpy as np
-from mathutils import Matrix
-
-from .utils_shader import Shader
-
-
-def load_shader(shadername):
- from os import path
- with open(path.join(path.dirname(__file__), 'resources', shadername), 'r') as f:
- return f.read()
-
-def gl_buffer_void_as_long(value):
- import ctypes
- a = (ctypes.c_byte * 1).from_address(value)
- return bgl.Buffer(bgl.GL_BYTE, 1, a)
-
-def get_mesh_vert_co_array(me):
- tot_vco = len(me.vertices)
- if tot_vco:
- verts_co = np.empty(len(me.vertices) * 3, 'f4')
- me.vertices.foreach_get("co", verts_co)
- verts_co.shape = (-1, 3)
- return verts_co
- return None
-
-
-def get_bmesh_vert_co_array(bm):
- tot_vco = len(bm.verts)
- if tot_vco:
- return np.array([v.co for v in bm.verts], 'f4')
- return None
-
-
-def get_mesh_tri_verts_array(me):
- me.calc_tessface()
- len_tessfaces = len(me.tessfaces)
- if len_tessfaces:
- tessfaces = np.empty(len_tessfaces * 4, 'i4')
- me.tessfaces.foreach_get("vertices_raw", tessfaces)
- tessfaces.shape = (-1, 4)
-
- quad_indices = tessfaces[:, 3].nonzero()[0]
- tris = np.empty(((len_tessfaces + len(quad_indices)), 3), 'i4')
-
- tris[:len_tessfaces] = tessfaces[:, :3]
- tris[len_tessfaces:] = tessfaces[quad_indices][:, (0, 2, 3)]
-
- del tessfaces
- return tris
- return None
-
-
-def get_bmesh_tri_verts_array(bm):
- ltris = bm.calc_tessface()
- tris = [[ltri[0].vert.index, ltri[1].vert.index, ltri[2].vert.index] for ltri in ltris if not ltri[0].face.hide]
- if tris:
- return np.array(tris, 'i4')
- return None
-
-
-def get_mesh_edge_verts_array(me):
- tot_edges = len(me.edges)
- if tot_edges:
- edge_verts = np.empty(tot_edges * 2, 'i4')
- me.edges.foreach_get("vertices", edge_verts)
- edge_verts.shape = tot_edges, 2
- return edge_verts
- return None
-
-
-def get_bmesh_edge_verts_array(bm):
- bm.edges.ensure_lookup_table()
- edges = [[e.verts[0].index, e.verts[1].index] for e in bm.edges if not e.hide]
- if edges:
- return np.array(edges, 'i4')
- return None
-
-
-def get_mesh_loosevert_array(me, edges):
- verts = np.arange(len(me.vertices))
-
- mask = np.in1d(verts, edges, invert=True)
-
- verts = verts[mask]
- if len(verts):
- return verts
- return None
-
-
-def get_bmesh_loosevert_array(bm):
- looseverts = [v.index for v in bm.verts if not (v.link_edges or v.hide)]
- if looseverts:
- return np.array(looseverts, 'i4')
- return None
-
-
-class _Mesh_Arrays():
- def __init__(self, obj, create_tris, create_edges, create_looseverts):
- self.tri_verts = self.edge_verts = self.looseverts = None
- self.tris_co = self.edges_co = self.looseverts_co = None
- if obj.type == 'MESH':
- me = obj.data
- if me.is_editmode:
- bm = bmesh.from_edit_mesh(me)
- bm.verts.ensure_lookup_table()
-
- self.verts_co = get_bmesh_vert_co_array(bm)
-
- if create_tris:
- self.tri_verts = get_bmesh_tri_verts_array(bm)
- if create_edges:
- self.edge_verts = get_bmesh_edge_verts_array(bm)
- if create_looseverts:
- self.looseverts = get_bmesh_loosevert_array(bm)
- else:
- self.verts_co = get_mesh_vert_co_array(me)
-
- if create_tris:
- self.tri_verts = get_mesh_tri_verts_array(me)
- if create_edges:
- self.edge_verts = get_mesh_edge_verts_array(me)
- if create_looseverts:
- edge_verts = self.edge_verts
- if edge_verts is None:
- edge_verts = get_mesh_edge_verts_array(me)
- self.looseverts = get_mesh_loosevert_array(me, edge_verts)
- del edge_verts
-
- else: #TODO
- self.verts_co = np.zeros((1,3), 'f4')
- self.looseverts = np.zeros(1, 'i4')
-
- def __del__(self):
- del self.tri_verts, self.edge_verts, self.looseverts
- del self.verts_co
-
-
-class GPU_Indices_Mesh():
- shader = None
-
- @classmethod
- def end_opengl(cls):
- del cls.shader
- del cls._NULL
- del cls.P
- del cls.MV
- del cls.MVP
- del cls.vert_index
- del cls.tri_co
- del cls.edge_co
- del cls.vert_co
-
- del cls
-
- @classmethod
- def init_opengl(cls):
- # OpenGL was already initialized, nothing to do here.
- if cls.shader is not None:
- return
-
- import atexit
-
- # Make sure we only registered the callback once.
- atexit.unregister(cls.end_opengl)
- atexit.register(cls.end_opengl)
-
- cls.shader = Shader(
- load_shader('3D_vert.glsl'),
- None,
- load_shader('primitive_id_frag.glsl'),
- )
-
- cls.unif_use_clip_planes = bgl.glGetUniformLocation(cls.shader.program, 'use_clip_planes')
- cls.unif_clip_plane = bgl.glGetUniformLocation(cls.shader.program, 'clip_plane')
-
- cls._NULL = gl_buffer_void_as_long(0)
-
- cls.unif_MVP = bgl.glGetUniformLocation(cls.shader.program, 'MVP')
- cls.unif_MV = bgl.glGetUniformLocation(cls.shader.program, 'MV')
- cls.unif_offset = bgl.glGetUniformLocation(cls.shader.program, 'offset')
-
- cls.attr_pos = bgl.glGetAttribLocation(cls.shader.program, 'pos')
- cls.attr_primitive_id = bgl.glGetAttribLocation(cls.shader.program, 'primitive_id')
-
- cls.P = bgl.Buffer(bgl.GL_FLOAT, (4, 4))
- cls.MV = bgl.Buffer(bgl.GL_FLOAT, (4, 4))
- cls.MVP = bgl.Buffer(bgl.GL_FLOAT, (4, 4))
-
- # returns of public API #
- cls.vert_index = bgl.Buffer(bgl.GL_INT, 1)
-
- cls.tri_co = bgl.Buffer(bgl.GL_FLOAT, (3, 3))
- cls.edge_co = bgl.Buffer(bgl.GL_FLOAT, (2, 3))
- cls.vert_co = bgl.Buffer(bgl.GL_FLOAT, 3)
-
- def __init__(self, obj, draw_tris, draw_edges, draw_verts):
- GPU_Indices_Mesh.init_opengl()
-
- self.obj = obj
- self.draw_tris = draw_tris
- self.draw_edges = draw_edges
- self.draw_verts = draw_verts
-
- self.vbo = None
- self.vbo_tris = None
- self.vbo_edges = None
- self.vbo_verts = None
-
- ## Create VAO ##
- self.vao = bgl.Buffer(bgl.GL_INT, 1)
- bgl.glGenVertexArrays(1, self.vao)
- bgl.glBindVertexArray(self.vao[0])
-
- ## Init Array ##
- mesh_arrays = _Mesh_Arrays(obj, draw_tris, draw_edges, draw_verts)
-
- ## Create VBO for vertices ##
- if mesh_arrays.verts_co is None:
- self.draw_tris = False
- self.draw_edges = False
- self.draw_verts = False
- return
-
- if False: # Blender 2.8
- self.vbo_len = len(mesh_arrays.verts_co)
-
- self.vbo = bgl.Buffer(bgl.GL_INT, 1)
- bgl.glGenBuffers(1, self.vbo)
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo[0])
- verts_co = bgl.Buffer(bgl.GL_FLOAT, mesh_arrays.verts_co.shape, mesh_arrays.verts_co)
- bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.vbo_len * 12, verts_co, bgl.GL_STATIC_DRAW)
-
- ## Create VBO for Tris ##
- if mesh_arrays.tri_verts is not None:
- self.tri_verts = mesh_arrays.tri_verts
- self.num_tris = len(self.tri_verts)
-
- np_tris_co = mesh_arrays.verts_co[mesh_arrays.tri_verts]
- np_tris_co = bgl.Buffer(bgl.GL_FLOAT, np_tris_co.shape, np_tris_co)
- self.vbo_tris = bgl.Buffer(bgl.GL_INT, 1)
- bgl.glGenBuffers(1, self.vbo_tris)
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tris[0])
- bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_tris * 36, np_tris_co, bgl.GL_STATIC_DRAW)
- del np_tris_co
-
- tri_indices = np.repeat(np.arange(self.num_tris, dtype = 'f4'), 3)
- tri_indices = bgl.Buffer(bgl.GL_FLOAT, tri_indices.shape, tri_indices)
- self.vbo_tri_indices = bgl.Buffer(bgl.GL_INT, 1)
- bgl.glGenBuffers(1, self.vbo_tri_indices)
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tri_indices[0])
- bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_tris * 12, tri_indices, bgl.GL_STATIC_DRAW)
- del tri_indices
-
- else:
- self.num_tris = 0
- self.draw_tris = False
-
- ## Create VBO for Edges ##
- if mesh_arrays.edge_verts is not None:
- self.edge_verts = mesh_arrays.edge_verts
- self.num_edges = len(self.edge_verts)
-
- np_edges_co = mesh_arrays.verts_co[mesh_arrays.edge_verts]
- np_edges_co = bgl.Buffer(bgl.GL_FLOAT, np_edges_co.shape, np_edges_co)
- self.vbo_edges = bgl.Buffer(bgl.GL_INT, 1)
- bgl.glGenBuffers(1, self.vbo_edges)
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edges[0])
- bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_edges * 24, np_edges_co, bgl.GL_STATIC_DRAW)
- del np_edges_co
-
- edge_indices = np.repeat(np.arange(self.num_edges, dtype = 'f4'), 2)
- edge_indices = bgl.Buffer(bgl.GL_FLOAT, edge_indices.shape, edge_indices)
- self.vbo_edge_indices = bgl.Buffer(bgl.GL_INT, 1)
- bgl.glGenBuffers(1, self.vbo_edge_indices)
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edge_indices[0])
- bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_edges * 8, edge_indices, bgl.GL_STATIC_DRAW)
- del edge_indices
- else:
- self.num_edges = 0
- self.draw_edges = False
-
- ## Create EBO for Loose Verts ##
- if mesh_arrays.looseverts is not None:
- self.looseverts = mesh_arrays.looseverts
- self.num_verts = len(mesh_arrays.looseverts)
-
- np_lverts_co = mesh_arrays.verts_co[mesh_arrays.looseverts]
- np_lverts_co = bgl.Buffer(bgl.GL_FLOAT, np_lverts_co.shape, np_lverts_co)
- self.vbo_verts = bgl.Buffer(bgl.GL_INT, 1)
- bgl.glGenBuffers(1, self.vbo_verts)
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_verts[0])
- bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_verts * 12, np_lverts_co, bgl.GL_STATIC_DRAW)
- del np_lverts_co
-
- looseverts_indices = np.arange(self.num_verts, dtype = 'f4')
- looseverts_indices = bgl.Buffer(bgl.GL_FLOAT, looseverts_indices.shape, looseverts_indices)
- self.vbo_looseverts_indices = bgl.Buffer(bgl.GL_INT, 1)
- bgl.glGenBuffers(1, self.vbo_looseverts_indices)
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_looseverts_indices[0])
- bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_verts * 4, looseverts_indices, bgl.GL_STATIC_DRAW)
- del looseverts_indices
- else:
- self.num_verts = 0
- self.draw_verts = False
-
- del mesh_arrays
-
- bgl.glBindVertexArray(0)
-
-
- def get_tot_elems(self):
- tot = 0
-
- if self.draw_tris:
- tot += self.num_tris
-
- if self.draw_edges:
- tot += self.num_edges
-
- if self.draw_verts:
- tot += self.num_verts
-
- return tot
-
-
- def set_draw_mode(self, draw_tris, draw_edges, draw_verts):
- self.draw_tris = draw_tris and self.vbo_tris
- self.draw_edges = draw_edges and self.vbo_edges
- self.draw_verts = draw_verts and self.vbo_verts
-
-
- def set_ModelViewMatrix(self, MV):
- self.MV[:] = MV[:]
- self.MVP[:] = Matrix(self.P) * MV
-
-
- def Draw(self, index_offset):
- self.first_index = index_offset
- bgl.glUseProgram(self.shader.program)
- bgl.glBindVertexArray(self.vao[0])
-
- bgl.glUniformMatrix4fv(self.unif_MV, 1, bgl.GL_TRUE, self.MV)
- bgl.glUniformMatrix4fv(self.unif_MVP, 1, bgl.GL_TRUE, self.MVP)
-
- if self.draw_tris:
- bgl.glUniform1f(self.unif_offset, float(index_offset)) # bgl has no glUniform1ui :\
-
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tris[0])
- bgl.glEnableVertexAttribArray(self.attr_pos)
- bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL)
-
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tri_indices[0])
- bgl.glEnableVertexAttribArray(self.attr_primitive_id)
- bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL)
-
- bgl.glDrawArrays(bgl.GL_TRIANGLES, 0, self.num_tris * 3)
-
- index_offset += self.num_tris
- bgl.glDepthRange(-0.00005, 0.99995)
-
- if self.draw_edges:
- bgl.glUniform1f(self.unif_offset, float(index_offset)) #TODO: use glUniform1ui
-
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edges[0])
- bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL)
- bgl.glEnableVertexAttribArray(self.attr_pos)
-
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edge_indices[0])
- bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL)
- bgl.glEnableVertexAttribArray(self.attr_primitive_id)
-
- bgl.glDrawArrays(bgl.GL_LINES, 0, self.num_edges * 2)
-
- index_offset += self.num_edges
-
- if self.draw_verts:
- bgl.glUniform1f(self.unif_offset, float(index_offset)) #TODO: use glUniform1ui
-
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_verts[0])
- bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL)
- bgl.glEnableVertexAttribArray(self.attr_pos)
-
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_looseverts_indices[0])
- bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL)
- bgl.glEnableVertexAttribArray(self.attr_primitive_id)
-
- bgl.glDrawArrays(bgl.GL_POINTS, 0, self.num_verts)
-
- bgl.glDepthRange(0.0, 1.0)
-
-
- def get_tri_co(self, index):
- bgl.glBindVertexArray(self.vao[0])
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tris[0])
- bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 36, 36, self.tri_co)
- bgl.glBindVertexArray(0)
- return self.tri_co
-
-
- def get_edge_co(self, index):
- bgl.glBindVertexArray(self.vao[0])
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edges[0])
- bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 24, 24, self.edge_co)
- bgl.glBindVertexArray(0)
- return self.edge_co
-
-
- def get_loosevert_co(self, index):
- bgl.glBindVertexArray(self.vao[0])
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_verts[0])
- bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 12, 12, self.vert_co)
- bgl.glBindVertexArray(0)
- return self.vert_co
-
-
- def get_tri_verts(self, index):
- return self.tri_verts[index]
-
-
- def get_edge_verts(self, index):
- return self.edge_verts[index]
-
-
- def get_loosevert_index(self, index):
- return self.looseverts[index]
-
-
- def __del__(self):
- if self.vbo_tris:
- bgl.glDeleteBuffers(1, self.vbo_tris)
- bgl.glDeleteBuffers(1, self.vbo_tri_indices)
- del self.tri_verts
-
- if self.vbo_edges:
- bgl.glDeleteBuffers(1, self.vbo_edges)
- bgl.glDeleteBuffers(1, self.vbo_edge_indices)
- del self.edge_verts
-
- if self.vbo_verts:
- bgl.glDeleteBuffers(1, self.vbo_verts)
- bgl.glDeleteBuffers(1, self.vbo_looseverts_indices)
- del self.looseverts
-
- bgl.glDeleteVertexArrays(1, self.vao)
- #print('mesh_del', self.obj.name)
-
-
-class PreviousGLState:
- buf = bgl.Buffer(bgl.GL_INT, (4, 1))
- cur_program = buf[0]
- cur_vao = buf[1]
- cur_vbo = buf[2]
- cur_ebo = buf[3]
-
-
-def _store_current_shader_state(cls):
- bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, cls.cur_program)
- bgl.glGetIntegerv(bgl.GL_VERTEX_ARRAY_BINDING, cls.cur_vao)
- bgl.glGetIntegerv(bgl.GL_ARRAY_BUFFER_BINDING, cls.cur_vbo)
- bgl.glGetIntegerv(bgl.GL_ELEMENT_ARRAY_BUFFER_BINDING, cls.cur_ebo)
-
-
-def _restore_shader_state(cls):
- bgl.glUseProgram(cls.cur_program[0])
- bgl.glBindVertexArray(cls.cur_vao[0])
- bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, cls.cur_vbo[0])
- bgl.glBindBuffer(bgl.GL_ELEMENT_ARRAY_BUFFER, cls.cur_ebo[0])
-
-
-def gpu_Indices_enable_state():
- _store_current_shader_state(PreviousGLState)
-
- GPU_Indices_Mesh.init_opengl()
- bgl.glUseProgram(GPU_Indices_Mesh.shader.program)
- #bgl.glBindVertexArray(GPU_Indices_Mesh.vao[0])
-
-
-def gpu_Indices_restore_state():
- bgl.glBindVertexArray(0)
- _restore_shader_state(PreviousGLState)
-
-
-def gpu_Indices_use_clip_planes(rv3d, value):
- if rv3d.use_clip_planes:
- planes = bgl.Buffer(bgl.GL_FLOAT, (6, 4), rv3d.clip_planes)
-
- _store_current_shader_state(PreviousGLState)
- GPU_Indices_Mesh.init_opengl()
- bgl.glUseProgram(GPU_Indices_Mesh.shader.program)
- bgl.glUniform1i(GPU_Indices_Mesh.unif_use_clip_planes, value)
-
- bgl.glUniform4fv(GPU_Indices_Mesh.unif_clip_plane, 4, planes)
-
- _restore_shader_state(PreviousGLState)
-
-
-def gpu_Indices_set_ProjectionMatrix(P):
- GPU_Indices_Mesh.P[:] = P
diff --git a/modules/snap_context/resources/3D_vert.glsl b/modules/snap_context/resources/3D_vert.glsl
deleted file mode 100644
index c97df2bf..00000000
--- a/modules/snap_context/resources/3D_vert.glsl
+++ /dev/null
@@ -1,26 +0,0 @@
-#version 120
-
-uniform bool use_clip_planes;
-uniform vec4 clip_plane[4];
-varying vec4 clip_distance;
-
-uniform mat4 MV;
-uniform mat4 MVP;
-
-attribute vec3 pos;
-attribute float primitive_id;
-varying float primitive_id_var;
-
-void main()
-{
- if (use_clip_planes) {
- vec4 g_pos = MV * vec4(pos, 1.0);
-
- for (int i = 0; i != 4; i++) {
- clip_distance[i] = dot(clip_plane[i], g_pos);
- }
- }
-
- primitive_id_var = primitive_id;
- gl_Position = MVP * vec4(pos, 1.0);
-}
diff --git a/modules/snap_context/resources/primitive_id_frag.glsl b/modules/snap_context/resources/primitive_id_frag.glsl
deleted file mode 100644
index f3f7a124..00000000
--- a/modules/snap_context/resources/primitive_id_frag.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-#version 120
-
-uniform bool use_clip_planes;
-varying vec4 clip_distance;
-
-uniform float offset;
-
-varying float primitive_id_var;
-
-void main()
-{
- if (use_clip_planes &&
- ((clip_distance[0] < 0) ||
- (clip_distance[1] < 0) ||
- (clip_distance[2] < 0) ||
- (clip_distance[3] < 0)))
- {
- discard;
- }
-
- gl_FragColor = vec4(offset + primitive_id_var, 0, 0, 0);
-}
diff --git a/modules/snap_context/utils_projection.py b/modules/snap_context/utils_projection.py
deleted file mode 100644
index d3970b46..00000000
--- a/modules/snap_context/utils_projection.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# ##### 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 3
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-from mathutils import Vector
-from mathutils.geometry import intersect_point_line
-
-
-def depth_get(co, ray_start, ray_dir):
- dvec = co - ray_start
- return dvec.dot(ray_dir)
-
-
-def region_2d_to_orig_and_view_vector(region, rv3d, coord):
- viewinv = rv3d.view_matrix.inverted()
- persinv = rv3d.perspective_matrix.inverted()
-
- dx = (2.0 * coord[0] / region.width) - 1.0
- dy = (2.0 * coord[1] / region.height) - 1.0
-
- if rv3d.is_perspective:
- origin_start = viewinv.translation.copy()
-
- out = Vector((dx, dy, -0.5))
-
- w = out.dot(persinv[3].xyz) + persinv[3][3]
-
- view_vector = ((persinv * out) / w) - origin_start
- else:
- view_vector = -viewinv.col[2].xyz
-
- origin_start = ((persinv.col[0].xyz * dx) +
- (persinv.col[1].xyz * dy) +
- viewinv.translation)
-
- view_vector.normalize()
- return view_vector, origin_start
-
-
-def project_co_v3(sctx, co):
- proj_co = sctx.proj_mat * co.to_4d()
- proj_co.xy /= proj_co.w
-
- win_half = sctx.winsize * 0.5
- proj_co[0] = (proj_co[0] + 1.0) * win_half[0]
- proj_co[1] = (proj_co[1] + 1.0) * win_half[1]
-
- return proj_co.xy
-
-
-
-def intersect_boundbox_threshold(sctx, MVP, ray_origin_local, ray_direction_local, bbmin, bbmax):
- local_bvmin = Vector()
- local_bvmax = Vector()
- tmin = Vector()
- tmax = Vector()
-
- if (ray_direction_local[0] < 0.0):
- local_bvmin[0] = bbmax[0]
- local_bvmax[0] = bbmin[0]
- else:
- local_bvmin[0] = bbmin[0]
- local_bvmax[0] = bbmax[0]
-
- if (ray_direction_local[1] < 0.0):
- local_bvmin[1] = bbmax[1]
- local_bvmax[1] = bbmin[1]
- else:
- local_bvmin[1] = bbmin[1]
- local_bvmax[1] = bbmax[1]
-
- if (ray_direction_local[2] < 0.0):
- local_bvmin[2] = bbmax[2]
- local_bvmax[2] = bbmin[2]
- else:
- local_bvmin[2] = bbmin[2]
- local_bvmax[2] = bbmax[2]
-
- if (ray_direction_local[0]):
- tmin[0] = (local_bvmin[0] - ray_origin_local[0]) / ray_direction_local[0]
- tmax[0] = (local_bvmax[0] - ray_origin_local[0]) / ray_direction_local[0]
- else:
- tmin[0] = tmax[0] = sctx.depth_range[1]
-
- if (ray_direction_local[1]):
- tmin[1] = (local_bvmin[1] - ray_origin_local[1]) / ray_direction_local[1]
- tmax[1] = (local_bvmax[1] - ray_origin_local[1]) / ray_direction_local[1]
- else:
- tmin[1] = tmax[1] = sctx.depth_range[1]
-
- if (ray_direction_local[2]):
- tmin[2] = (local_bvmin[2] - ray_origin_local[2]) / ray_direction_local[2]
- tmax[2] = (local_bvmax[2] - ray_origin_local[2]) / ray_direction_local[2]
- else:
- tmin[2] = tmax[2] = sctx.depth_range[1]
-
- # `va` and `vb` are the coordinates of the AABB edge closest to the ray #
- va = Vector()
- vb = Vector()
- # `rtmin` and `rtmax` are the minimum and maximum distances of the ray hits on the AABB #
-
- if ((tmax[0] <= tmax[1]) and (tmax[0] <= tmax[2])):
- rtmax = tmax[0]
- va[0] = vb[0] = local_bvmax[0]
- main_axis = 3
- elif ((tmax[1] <= tmax[0]) and (tmax[1] <= tmax[2])):
- rtmax = tmax[1]
- va[1] = vb[1] = local_bvmax[1]
- main_axis = 2
- else:
- rtmax = tmax[2]
- va[2] = vb[2] = local_bvmax[2]
- main_axis = 1
-
- if ((tmin[0] >= tmin[1]) and (tmin[0] >= tmin[2])):
- rtmin = tmin[0]
- va[0] = vb[0] = local_bvmin[0]
- main_axis -= 3
-
- elif ((tmin[1] >= tmin[0]) and (tmin[1] >= tmin[2])):
- rtmin = tmin[1]
- va[1] = vb[1] = local_bvmin[1]
- main_axis -= 1
-
- else:
- rtmin = tmin[2]
- va[2] = vb[2] = local_bvmin[2]
- main_axis -= 2
-
- if (main_axis < 0):
- main_axis += 3
-
-#ifdef IGNORE_BEHIND_RAY
- depth_max = depth_get(local_bvmax, ray_origin_local, ray_direction_local)
- if (depth_max < sctx.depth_range[0]):
- return False
-#endif
-
- if (rtmin <= rtmax):
- # if rtmin < rtmax, ray intersect `AABB` #
- return True
-
- if (ray_direction_local[main_axis] < 0.0):
- va[main_axis] = local_bvmax[main_axis]
- vb[main_axis] = local_bvmin[main_axis]
-
- else:
- va[main_axis] = local_bvmin[main_axis]
- vb[main_axis] = local_bvmax[main_axis]
-
- win_half = sctx.winsize * 0.5
-
- scale = abs(local_bvmax[main_axis] - local_bvmin[main_axis])
-
- va2d = Vector((
- (MVP[0].xyz.dot(va) + MVP[0][3]),
- (MVP[1].xyz.dot(va) + MVP[1][3]),
- ))
-
- vb2d = Vector((
- (va2d[0] + MVP[0][main_axis] * scale),
- (va2d[1] + MVP[1][main_axis] * scale),
- ))
-
- depth_a = MVP[3].xyz.dot(va) + MVP[3][3]
- depth_b = depth_a + MVP[3][main_axis] * scale
-
- va2d /= depth_a
- vb2d /= depth_b
-
- va2d[0] = (va2d[0] + 1.0) * win_half[0]
- va2d[1] = (va2d[1] + 1.0) * win_half[1]
- vb2d[0] = (vb2d[0] + 1.0) * win_half[0]
- vb2d[1] = (vb2d[1] + 1.0) * win_half[1]
-
- p, fac = intersect_point_line(sctx.mval, va2d, vb2d)
- if fac < 0.0:
- return (sctx.mval - va2d).length_squared < sctx._dist_px_sq
- elif fac > 1.0:
- return (sctx.mval - vb2d).length_squared < sctx._dist_px_sq
- else:
- return (sctx.mval - p).length_squared < sctx._dist_px_sq
-
-
-def intersect_ray_segment_fac(v0, v1, ray_direction, ray_origin):
- a = v1 - v0
- t = v0 - ray_origin
- n = a.cross(ray_direction)
- nlen = n.length_squared
-
- # if (nlen == 0.0f) the lines are parallel, has no nearest point, only distance squared.*/
- if nlen == 0.0:
- # Calculate the distance to the nearest point to origin then #
- return a.dot(ray_direction) < 0
- else:
- c = n - t
- cray = c.cross(ray_direction)
- return cray.dot(n) / nlen
diff --git a/modules/snap_context/utils_shader.py b/modules/snap_context/utils_shader.py
deleted file mode 100644
index 1758585a..00000000
--- a/modules/snap_context/utils_shader.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# ##### 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 3
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-
-import bgl
-
-def check_shaderError(shader, flag, isProgram, errorMessage):
- success = bgl.Buffer(bgl.GL_INT, 1)
-
- if isProgram:
- bgl.glGetProgramiv(shader, flag, success)
- else:
- bgl.glGetShaderiv(shader, flag, success)
-
- if success[0] == bgl.GL_FALSE:
- import numpy as np
- import ctypes
-
- offset = bgl.Buffer(bgl.GL_INT, 1, (ctypes.c_int32 * 1).from_address(0))
- error = bgl.Buffer(bgl.GL_BYTE, 1024)
- if isProgram:
- bgl.glGetProgramInfoLog(shader, 1024, offset, error)
- print(errorMessage, np.bytes_(error).decode("utf-8"))
- else:
- bgl.glGetShaderInfoLog(shader, 1024, offset, error)
- print(errorMessage, np.bytes_(error).decode("utf-8"))
-
- del offset
- raise #RuntimeError(errorMessage, bgl.glGetShaderInfoLog(shader))
-
-
-def create_shader(source, shaderType):
- shader = bgl.glCreateShader(shaderType)
-
- if shader == 0:
- raise RuntimeError("Error: Shader creation failed!")
-
- bgl.glShaderSource(shader, source)
- bgl.glCompileShader(shader)
-
- check_shaderError(shader, bgl.GL_COMPILE_STATUS, False, "Error: Shader compilation failed:")
-
- return shader
-
-
-class Shader():
- def __init__(self, vertexcode, geomcode, fragcode):
- self.program = bgl.glCreateProgram()
- self.shaders = []
-
- if vertexcode:
- self.shaders.append(create_shader(vertexcode, bgl.GL_VERTEX_SHADER))
- if geomcode:
- self.shaders.append(create_shader(geomcode, bgl.GL_GEOMETRY_SHADER))
- if fragcode:
- self.shaders.append(create_shader(fragcode, bgl.GL_FRAGMENT_SHADER))
-
- for shad in self.shaders:
- bgl.glAttachShader(self.program, shad)
-
- bgl.glLinkProgram(self.program)
- check_shaderError(self.program, bgl.GL_LINK_STATUS, True, "Error: Program linking failed:")
- bgl.glValidateProgram(self.program)
- check_shaderError(self.program, bgl.GL_VALIDATE_STATUS, True, "Error: Program is invalid:")
-
- def __del__(self):
- for shad in self.shaders:
- bgl.glDetachShader(self.program, shad)
- bgl.glDeleteShader(shad)
- bgl.glDeleteProgram(self.program)
- #print('shader_del')