Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeffii/9464848 to your computer and use it in GitHub Desktop.
Save zeffii/9464848 to your computer and use it in GitHub Desktop.
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
bl_info = {
'name': 'EDGE Visualiser (BMesh)',
'author': 'zeffii',
'version': (0, 0, 1),
'blender': (2, 7, 0),
'location': '',
'warning': '',
'description': '',
'wiki_url': '',
'tracker_url': '',
'category': '3D View'
}
"""
Display the indices of vertices, edges and faces in the 3d-view.
How to use:
- Select a mesh and go into editmode
- Display the properties panel (N-key)
- Go to the Mesh Display tab, it helps to fold the tabs above it
- Press the 'Visualise indices button'
"""
import bpy
import bgl
import blf
import mathutils
import bmesh
import math
from bpy_extras.view3d_utils import location_3d_to_region_2d as loc3d2d
point_dict = {}
def adjust_list(in_list, x, y):
return [[old_x + x, old_y + y] for (old_x, old_y) in in_list]
def generate_points(width, height, amp=5):
''' amp: radius fillet '''
width += 2
height += 4
width = ((width/2) - amp) + 2
height -= (2*amp)
pos_list, final_list = [], []
n_points = 10
seg_angle = 2 * math.pi / n_points
for i in range(n_points + 1):
angle = i * seg_angle
x = math.cos(angle) * amp
y = math.sin(angle) * amp
pos_list.append([x, -y])
w_list, h_list = [1, -1, -1, 1], [-1, -1, 1, 1]
slice_list = [[i, i+4] for i in range(0, n_points, 3)]
for idx, (start, end) in enumerate(slice_list):
point_array = pos_list[start:end]
w = width * w_list[idx]
h = height * h_list[idx]
final_list += adjust_list(point_array, w, h)
return final_list
def get_points(index):
'''
index: string representation of the index number
returns: rounded rect point_list used for background.
the neat thing about this is if a width has been calculated once, it
is stored in a dict and used if another polygon is saught with that width.
'''
width, height = blf.dimensions(0, index)
if not (width in point_dict):
point_dict[width] = generate_points(width, height)
return point_dict[width]
# calculate locations and store them as ID property in the mesh
def draw_callback_px(self, context):
# polling
if context.mode != "EDIT_MESH":
return
# get screen information
region = context.region
rv3d = context.space_data.region_3d
this_object = context.active_object
matrix_world = this_object.matrix_world
text_height = 13
blf.size(0, text_height, 72)
def draw_index(rgb, index, coord):
vector3d = matrix_world * coord
x, y = loc3d2d(region, rv3d, vector3d)
index = str(index)
polyline = get_points(index)
''' draw polygon '''
bgl.glColor4f(0.103, 0.2, 0.2, 0.2)
bgl.glBegin(bgl.GL_POLYGON)
for pointx, pointy in polyline:
bgl.glVertex2f(pointx+x, pointy+y)
bgl.glEnd()
''' draw text '''
txt_width, txt_height = blf.dimensions(0, index)
bgl.glColor3f(*rgb)
blf.position(0, x - (txt_width / 2), y - (txt_height / 2), 0)
blf.draw(0, index)
vert_idx_color = (1.0, 1.0, 1.0)
edge_idx_color = (1.0, 1.0, 0.0)
face_idx_color = (1.0, 0.8, 0.8)
scene = context.scene
me = context.active_object.data
bm = bmesh.from_edit_mesh(me)
#if scene.live_mode:
me.update()
if True:
for e in bm.edges:
if not e.hide and e.select:
v1 = e.verts[0].co
v2 = e.verts[1].co
loc = v1 + ((v2 - v1) / 2)
draw_index(edge_idx_color, e.index, loc.to_4d())
# operator
class EdgeHover(bpy.types.Operator):
bl_idname = "view3d.edge_visualiser"
bl_label = "EDGE Visualiser"
bl_description = "Toggle the visualisation of indices"
_handle = None
@classmethod
def poll(cls, context):
return context.mode == "EDIT_MESH"
def modal(self, context, event):
if event.type in ('RET'):
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
# from here it is possible to call mesh updates.
return {"CANCELLED"}
if context.area:
context.area.tag_redraw()
return {"PASS_THROUGH"}
def invoke(self, context, event):
if context.area.type == "VIEW_3D":
sc = (self, context)
w = 'WINDOW'
pp = 'POST_PIXEL'
draw_handler = bpy.types.SpaceView3D.draw_handler_add
self._handle = draw_handler(draw_callback_px, sc, w, pp)
context.window_manager.modal_handler_add(self)
return {"RUNNING_MODAL"}
else:
self.report({"WARNING"}, "View3D not found, can't run operator")
return {"CANCELLED"}
def register():
bpy.utils.register_class(EdgeHover)
def unregister():
bpy.utils.unregister_class(EdgeHover)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment