def find_uv(context): obj_data = bmesh.from_edit_mesh(context.object.data) l = [] first = 0 diff = 0 for f, face in enumerate(obj_data.faces): for v, vertex in enumerate(face.verts): if vertex.select: l.append([f, v]) if first == 0: v1 = vertex.link_loops[0].vert.co sv1 = loc3d2d(context.region, context.space_data.region_3d, v1) v2 = vertex.link_loops[0].link_loop_next.vert.co sv2 = loc3d2d(context.region, context.space_data.region_3d, v2) vres = sv2 - sv1 va = vres.angle(Vector((0.0, 1.0))) uv1 = vertex.link_loops[0][obj_data.loops.layers.uv.active].uv uv2 = vertex.link_loops[0].link_loop_next[obj_data.loops.layers.uv.active].uv uvres = uv2 - uv1 uva = uvres.angle(Vector((0.0, 1.0))) diff = uva - va first += 1 return l, diff
def find_uv(context): obj_data = bmesh.from_edit_mesh(context.object.data) l = [] first = 0 diff = 0 for f, face in enumerate(obj_data.faces): for v, vertex in enumerate(face.verts): if vertex.select: l.append([f, v]) if first == 0: v1 = vertex.link_loops[0].vert.co sv1 = loc3d2d(context.region, context.space_data.region_3d, v1) v2 = vertex.link_loops[0].link_loop_next.vert.co sv2 = loc3d2d(context.region, context.space_data.region_3d, v2) vres = sv2 - sv1 va = vres.angle(Vector((0.0, 1.0))) uv1 = vertex.link_loops[0][ obj_data.loops.layers.uv.active].uv uv2 = vertex.link_loops[0].link_loop_next[ obj_data.loops.layers.uv.active].uv uvres = uv2 - uv1 uva = uvres.angle(Vector((0.0, 1.0))) diff = uva - va first += 1 return l, diff
def ScreenDistance(self, vertex_zero_co, vertex_one_co): matw = bpy.context.active_object.matrix_world V0 = matw * vertex_zero_co res0 = loc3d2d(bpy.context.region, bpy.context.space_data.region_3d, V0) V1 = matw * vertex_one_co res1 = loc3d2d(bpy.context.region, bpy.context.space_data.region_3d, V1) result = (res0 - res1).length return result
def draw_tetrahedron(region, rv3d, context, tetra_coords): apex, base1, base2, base3 = tetra_coords # converting to screen coordinates screen_apex = loc3d2d(region, rv3d, apex) screen_base1 = loc3d2d(region, rv3d, base1) screen_base2 = loc3d2d(region, rv3d, base2) screen_base3 = loc3d2d(region, rv3d, base3) # colour + line setup, 50% alpha, 1 px width line bgl.glEnable(bgl.GL_BLEND) bgl.glLineWidth(1) # linear distance line bgl.glColor4f(0.6, 0.6, 0.6, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_apex) bgl.glVertex2f(*screen_base3) bgl.glEnd() # x bgl.glColor4f(1.0, 0.1, 0.1, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_base3) bgl.glVertex2f(*screen_base2) bgl.glEnd() # y bgl.glColor4f(0.0, 1.0, 0.1, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_base2) bgl.glVertex2f(*screen_base1) bgl.glEnd() # z bgl.glColor4f(0.1, 0.3, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_apex) bgl.glVertex2f(*screen_base1) bgl.glEnd() # distraction line 1 & 2 bgl.glColor4f(0.3, 0.3, 0.3, 0.6) bgl.glLineStipple(4, 0x5555) bgl.glEnable(bgl.GL_LINE_STIPPLE) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_apex) bgl.glVertex2f(*screen_base2) bgl.glVertex2f(*screen_base1) bgl.glVertex2f(*screen_base3) bgl.glEnd() # done bgl.glDisable(bgl.GL_LINE_STIPPLE) bgl.glEnable(bgl.GL_BLEND) # back to uninterupted lines
def screen_v3dBGL_overlay(context, args): if not args[2]: return alpha = args[3] region = context.region region3d = context.space_data.region_3d bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) for matrix, color in args[0]: r, g, b = color bgl.glColor4f(r, g, b, alpha) bgl.glBegin(bgl.GL_QUADS) M = Matrix(matrix) for x, y in [(-.5, .5), (.5 ,.5), (.5 ,-.5), (-.5 ,-.5)]: vector3d = M * Vector((x, y, 0)) vector2d = loc3d2d(region, region3d, vector3d) bgl.glVertex2f(*vector2d) bgl.glEnd() # restore opengl defaults bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def screen_v3dBGL_overlay(context, args): if not args[2]: return alpha = args[3] region = context.region region3d = context.space_data.region_3d bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) for matrix, color in args[0]: r, g, b = color bgl.glColor4f(r, g, b, alpha) bgl.glBegin(bgl.GL_QUADS) M = Matrix(matrix) for x, y in [(-.5, .5), (.5, .5), (.5, -.5), (-.5, -.5)]: vector3d = M * Vector((x, y, 0)) vector2d = loc3d2d(region, region3d, vector3d) bgl.glVertex2f(*vector2d) bgl.glEnd() # restore opengl defaults bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def draw_data(self, context): region = context.region rv3d = context.space_data.region_3d obj = context.active_object vertlist = obj.data.vertices edge_list = [] for edge in obj.data.edges: idx1, idx2 = edge.vertices[:] co1, co2 = vertlist[idx1].co, vertlist[idx2].co co2d_1 = loc3d2d(region, rv3d, co1) co2d_2 = loc3d2d(region, rv3d, co2) edge_list.append((co2d_1, co2d_2)) write_svg(edge_list, region) return
def draw_gl_strip(coords, line_thickness): bgl.glLineWidth(line_thickness) bgl.glBegin(bgl.GL_LINES) for coord in coords: vector3d = matrix_world * coord vector2d = loc3d2d(region, rv3d, vector3d) bgl.glVertex2f(*vector2d) bgl.glEnd()
def generate_2d_draw_list(unique_set, context): region, rv3d, obj, vertlist = get_locals(context) edge_list = [] for edge in unique_set: local_coords = [vertlist[idx].co for idx in edge] world_coords = [obj.matrix_world * point for point in local_coords] edge_as_2d = [loc3d2d(region, rv3d, point) for point in world_coords] edge_list.append(edge_as_2d) return edge_list, region
def draw_callback_px(self, context): """Modally called function that draws the lines as they are streamed. Firstly updates the viewport's text. Then draws the line based on points in self.point_path. """ print("data points", len(self.point_path)) # get region so can draw intermediate lines region = context.region rv3d = context.space_data.region_3d draw_text_on_viewport("{} vertices added, timestamp {}" .format(str(len(self.point_path)), str(self.latest_ts))) # set the line parameters # 50% alpha, 2 pixel width line bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 0.5) bgl.glLineWidth(2) # draw the line here..... bgl.glBegin(bgl.GL_LINE_STRIP) # start from the origin for visual purposes for i in [0]: vertex = loc3d2d(region, rv3d, (i, i, i)) print('vertex is', vertex) bgl.glVertex2f(vertex[0], vertex[1]) for i, loc3d in enumerate(self.point_path): loc2d = loc3d2d(region, rv3d, loc3d) print(loc2d[0], loc2d[1], 'is the viewport coordinates') bgl.glVertex2i(math.floor(loc2d[0]), math.floor(loc2d[1])) #bgl.glVertex2i(math.floor(loc2d[0]%10), math.floor(loc2d[1]%10)) bgl.glEnd() # restore opengl defaults bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def draw_callback_px(self, context): """Modally called function that draws the lines as they are streamed. Firstly updates the viewport's text. Then draws the line based on points in self.point_path. """ print("data points", len(self.point_path)) # get region so can draw intermediate lines region = context.region rv3d = context.space_data.region_3d draw_text_on_viewport("{} vertices added, timestamp {}".format( str(len(self.point_path)), str(self.latest_ts))) # set the line parameters # 50% alpha, 2 pixel width line bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 0.5) bgl.glLineWidth(2) # draw the line here..... bgl.glBegin(bgl.GL_LINE_STRIP) # start from the origin for visual purposes for i in [0]: vertex = loc3d2d(region, rv3d, (i, i, i)) print('vertex is', vertex) bgl.glVertex2f(vertex[0], vertex[1]) for i, loc3d in enumerate(self.point_path): loc2d = loc3d2d(region, rv3d, loc3d) print(loc2d[0], loc2d[1], 'is the viewport coordinates') bgl.glVertex2i(math.floor(loc2d[0]), math.floor(loc2d[1])) #bgl.glVertex2i(math.floor(loc2d[0]%10), math.floor(loc2d[1]%10)) bgl.glEnd() # restore opengl defaults bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def draw_linear_line(region, rv3d, context, coordinate_list): # 50% alpha, 2 pixel width line bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.7, 0.7, 0.7, 0.5) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for coord in coordinate_list: vector3d = (coord.x, coord.y, coord.z) vector2d = loc3d2d(region, rv3d, vector3d) bgl.glVertex2f(*vector2d) bgl.glEnd()
def generate_2d_draw_data(context): """ this gets vertex coordinates, converts local to global generates edge_list with 2d screen coordinates. """ region, rv3d, obj, vertlist = get_locals(context) edge_list = [] for edge in obj.data.edges: local_coords = [vertlist[idx].co for idx in edge.vertices] world_coords = [obj.matrix_world * point for point in local_coords] edge_as_2d = [loc3d2d(region, rv3d, point) for point in world_coords] edge_list.append(edge_as_2d) return edge_list, region
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)
def draw_points(context, points, size, gl_col): region = context.region rv3d = context.space_data.region_3d bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(size) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) bgl.glBegin(bgl.GL_POINTS) bgl.glColor4f(*gl_col) for coord in points: vector3d = (coord.x, coord.y, coord.z) vector2d = loc3d2d(region, rv3d, vector3d) bgl.glVertex2f(*vector2d) bgl.glEnd() bgl.glDisable(bgl.GL_POINT_SMOOTH) bgl.glDisable(bgl.GL_POINTS) return
def draw_callback_px(self, context): x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[self.ActiveVertex].co) # Draw an * at the active vertex blf.position(0, x, y, 0) blf.size(0, 26, 72) blf.draw(0, "*") #Draw Help yPos=30 blf.size(0, 11, context.user_preferences.system.dpi) txtHelp1 = "{SHIFT}:Precision" txtHelp2 = "{WHEEL}:Change the vertex/edge" txtHelp3 = "{ALT}:Continuos slide" txtHelp4 = "{LEFT ARROW}:Reverse the movement" txtHelp5 = "{RIGHT ARROW}:Restore the movement" blf.position(0, 70, yPos, 0) blf.draw(0, txtHelp5) yPos += (int(blf.dimensions(0, txtHelp4)[1]*2)) blf.position(0 , 70, yPos, 0) blf.draw(0, txtHelp4) yPos += (int(blf.dimensions(0, txtHelp3)[1]*2)) blf.position(0 , 70, yPos, 0) blf.draw(0, txtHelp3) yPos += (int(blf.dimensions(0, txtHelp2)[1]*2)) blf.position(0 , 70, yPos, 0) blf.draw(0, txtHelp2) yPos += (int(blf.dimensions(0, txtHelp1)[1]*2)) blf.position(0 , 70, yPos, 0) blf.draw(0, txtHelp1) # Draw edge bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 0.1, 0.8, 1.0) bgl.glBegin(bgl.GL_LINES) for p in self.LinkedVertices1: bgl.glVertex2f(self.Vertex1.x2D, self.Vertex1.y2D) bgl.glVertex2f(p.x2D, p.y2D) for p in self.LinkedVertices2: bgl.glVertex2f(self.Vertex2.x2D, self.Vertex2.y2D) bgl.glVertex2f(p.x2D, p.y2D) bgl.glEnd()
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, 0, 0, 0) 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)
def draw_points(context, points, size, gl_col): region = context.region rv3d = context.space_data.region_3d # needed for adjusting the size of gl_points bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(size) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) bgl.glBegin(bgl.GL_POINTS) bgl.glColor4f(*gl_col) for coord in points: vector3d = (coord.x, coord.y, coord.z) vector2d = loc3d2d(region, rv3d, vector3d) bgl.glVertex2f(*vector2d) bgl.glEnd() bgl.glDisable(bgl.GL_POINT_SMOOTH) bgl.glDisable(bgl.GL_POINTS) return
def screen_v3d_batch_matrix_overlay(context, args): region = context.region region3d = context.space_data.region_3d cdat, alpha = args[0], args[1] if not alpha > 0.0: return pt = 0.5 G = -0.001 # to z offset the plane from the axis coords = (-pt, pt, G), (pt, pt, G), (pt, -pt, G), (-pt, -pt, G) indices_plane = [(0, 1, 2), (0, 2, 3)] # first calculate positions and lerp colors coords_transformed = [] indices_shifted = [] idx_offset = 0 colors = [] for i, (matrix, color) in enumerate(cdat): r, g, b = color for x, y, z in coords: vector3d = matrix @ Vector((x, y, z)) vector2d = loc3d2d(region, region3d, vector3d) coords_transformed.append(vector2d) colors.append((r, g, b, alpha)) for indices in indices_plane: indices_shifted.append(tuple(idx + idx_offset for idx in indices)) idx_offset += 4 batch = batch_for_shader(smooth_2d_shader, 'TRIS', { "pos": coords_transformed, "color": colors }, indices=indices_shifted) # smooth_2d_shader.bind() batch.draw(smooth_2d_shader)
def draw_polyline_from_coordinates(context, points, LINE_TYPE): region = context.region rv3d = context.space_data.region_3d bgl.glColor4f(1.0, 1.0, 1.0, 1.0) if LINE_TYPE == "GL_LINE_STIPPLE": bgl.glLineStipple(4, 0x5555) bgl.glEnable(bgl.GL_LINE_STIPPLE) bgl.glColor4f(0.3, 0.3, 0.3, 1.0) bgl.glBegin(bgl.GL_LINE_STRIP) for coord in points: vector3d = (coord.x, coord.y, coord.z) vector2d = loc3d2d(region, rv3d, vector3d) bgl.glVertex2f(*vector2d) bgl.glEnd() if LINE_TYPE == "GL_LINE_STIPPLE": bgl.glDisable(bgl.GL_LINE_STIPPLE) bgl.glEnable(bgl.GL_BLEND) # back to uninterupted lines return
def draw_points(context, points, size, gl_col): region = context.region rv3d = context.space_data.region_3d this_object = context.active_object matrix_world = this_object.matrix_world # needed for adjusting the size of gl_points bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(size) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) bgl.glBegin(bgl.GL_POINTS) bgl.glColor4f(*gl_col) for coord in points: # vector3d = matrix_world * (coord.x, coord.y, coord.z) vector3d = matrix_world * coord vector2d = loc3d2d(region, rv3d, vector3d) bgl.glVertex2f(*vector2d) bgl.glEnd() bgl.glDisable(bgl.GL_POINT_SMOOTH) bgl.glDisable(bgl.GL_POINTS) return
def modal(self, context, event): dist2d = lambda p1, p2: sqrt((p2[0] - p1[0])**2 + (p2[1] - p1[1])**2) if event.type in {'MOUSEMOVE'}: region = context.region rv3d = context.space_data.region_3d self.mouseCoNew = (event.mouse_region_x, event.mouse_region_y, 0) # loc2d = loc3d2d(region, rv3d, self.obLoc) dx = self.mouseCoNew[0] - self.mouseCo[0] dy = self.mouseCoNew[1] - self.mouseCo[1] first_loc = Vector(self.first_value) last_loc = Vector((first_loc[0] + dx/(1000 if self.precision else 100), first_loc[1] + dy/(1000 if self.precision else 100), first_loc[2])) if self.axis == 2: #xy context.area.header_text_set("Move Dx: %.4f Dy: %.4f" % (dx, dy)) last_loc[2] = self.backup_value[2] elif self.axis == 1: #y last_loc[0] = self.first_value[0] last_loc[2] = self.backup_value[2] context.area.header_text_set("Move: %.4f along local Y" % dy) elif self.axis == 0: #x last_loc[1] = self.first_value[1] last_loc[2] = self.backup_value[2] context.area.header_text_set("Move: %.4f along local X" % dx) last_loc[0] = (last_loc[0] + 2) % 4 - 2 obj_ref['move'].location = last_loc self.tmp_value = last_loc return {'RUNNING_MODAL'} elif event.type == 'X' and event.value == 'PRESS': self.axis = 0 if self.axis != 0 else 2 elif event.type == 'Y' and event.value == 'PRESS': self.axis = 1 if self.axis != 1 else 2 elif event.type in {'LEFT_SHIFT', 'RIGHT_SHIFT'}: if event.value == 'PRESS': self.precision = True tmp = self.first_value self.first_value = self.tmp_value self.tmp_value = tmp tmp = self.mouseCo self.mouseCo = self.mouseCoNew self.mouseCoNew = tmp elif event.value == 'RELEASE': self.precision = False tmp = self.first_value self.first_value = self.tmp_value self.tmp_value = tmp tmp = self.mouseCo self.mouseCo = self.mouseCoNew self.mouseCoNew = tmp elif event.type == 'LEFTMOUSE': context.area.header_text_set() return {'FINISHED'} elif event.type in {'RIGHTMOUSE', 'ESC'}: obj_ref['move'].location = self.backup_value context.area.header_text_set() return {'CANCELLED'} else: #return {'PASS_THROUGH'} return {'RUNNING_MODAL'} return {'RUNNING_MODAL'}
def draw_dimensions(region, rv3d, context, tetra_coords): apex, base1, base2, base3 = tetra_coords # TODO WARNING FACTORABLE CODE AHEAD # converting to screen coordinates screen_apex = loc3d2d(region, rv3d, apex) screen_base1 = loc3d2d(region, rv3d, base1) screen_base2 = loc3d2d(region, rv3d, base2) screen_base3 = loc3d2d(region, rv3d, base3) # DRAW X if base3.y > apex.y: YDIR = 1 else: YDIR = -1 # do we need to draw at all if there is no x distance? if base3.y != apex.y: y_dir = NUM_UNITS * YDIR base3_ext_y = Vector((base3.x, base3.y + y_dir, base3.z)) base2_ext_y = Vector((base2.x, base2.y + y_dir, base2.z)) scr_base3_ext_y = loc3d2d(region, rv3d, base3_ext_y) scr_base2_ext_y = loc3d2d(region, rv3d, base2_ext_y) bgl.glColor4f(0.203, 0.8, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_base3) bgl.glVertex2f(*scr_base3_ext_y) bgl.glVertex2f(*screen_base2) bgl.glVertex2f(*scr_base2_ext_y) bgl.glEnd() # DRAW Y if base3.x > apex.x: XDIR = -1 else: XDIR = 1 # do we need to draw at all if there is no y distance? if base3.x != apex.x: x_dir = NUM_UNITS * XDIR base2_ext_x = Vector((base2.x + x_dir, base2.y, base2.z)) base1_ext_x = Vector((base1.x + x_dir, base1.y, base1.z)) scr_base2_ext_x = loc3d2d(region, rv3d, base2_ext_x) scr_base1_ext_x = loc3d2d(region, rv3d, base1_ext_x) bgl.glColor4f(0.203, 0.8, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_base2) bgl.glVertex2f(*scr_base2_ext_x) bgl.glVertex2f(*screen_base1) bgl.glVertex2f(*scr_base1_ext_x) bgl.glEnd() # DRAW Z # check if there is a z distance if apex.z != base3.z: # draw z, use oposite y direction y_dir = NUM_UNITS * -YDIR apex_ext_y = Vector((apex.x, apex.y + y_dir, apex.z)) base1_ext_y = Vector((base1.x, base1.y + y_dir, base1.z)) scr_apex_ext_y = loc3d2d(region, rv3d, apex_ext_y) scr_base1_ext_y = loc3d2d(region, rv3d, base1_ext_y) bgl.glColor4f(0.203, 0.8, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_apex) bgl.glVertex2f(*scr_apex_ext_y) bgl.glVertex2f(*screen_base1) bgl.glVertex2f(*scr_base1_ext_y) bgl.glEnd() # DRAW LINEAR # necessarily at the end because we know the y direction now. # X/Y angle (between base1, base3, base2) # find a cleaner (more clever) way to do if (apex.x > base3.x) and (apex.y > base3.y): vec1 = base1 - base3 vec2 = base2 - base3 XY_RAD = vec1.angle(vec2) # -(pi*0.75) elif (apex.x > base3.x) and (apex.y < base3.y): vec1 = base2 - base1 vec2 = base3 - base1 XY_RAD = vec1.angle(vec2) + (1.5 * pi) elif (apex.y > base3.y) and (apex.x < base3.x): vec1 = base2 - base1 vec2 = base3 - base1 XY_RAD = vec1.angle(vec2) - (0.5 * pi) elif (apex.x < base3.x) and (apex.y < base3.y): vec1 = base2 - base1 vec2 = base3 - base1 XY_RAD = -vec1.angle(vec2) + (0.5 * pi) elif apex.y == base3.y: XY_RAD = pi elif apex.x == base3.x: XY_RAD = 0.5 * pi else: # dont bother drawing it. return # what a jungle. marker_xyz = Vector((0.0, NUM_UNITS * -YDIR, 0.0)) myEul = Euler((0.0, 0.0, XY_RAD), 'XYZ') marker_xyz.rotate(myEul) # rotate and modify vector in place. apex_ext_xyz = apex + marker_xyz base3_ext_xyz = base3 + marker_xyz scr_apex_ext_xyz = loc3d2d(region, rv3d, apex_ext_xyz) scr_base3_ext_xyz = loc3d2d(region, rv3d, base3_ext_xyz) bgl.glColor4f(0.203, 0.8, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_base3) bgl.glVertex2f(*scr_base3_ext_xyz) bgl.glVertex2f(*screen_apex) bgl.glVertex2f(*scr_apex_ext_xyz) bgl.glEnd() #print("drawing dimensions next") return
def draw_tris(region, rv3d, context): divs = 24 # verts per fan. n = 3 # ratio of shortest edge. def get_tri_coords(object_list): # replace for empties code. coordlist = [obj.location for obj in object_list] return coordlist def get_angle_rad(set_of_coords): coord1, coord2, coord3 = set_of_coords angle_rad = (coord1 - coord2).angle(coord3 - coord2) angle_deg = degrees(angle_rad) return angle_rad, angle_deg # if 3 empties selected coord1, coord2, coord3 = get_tri_coords(context.selected_objects) # measure angle between angle1 = [coord3, coord1, coord2] angle2 = [coord1, coord2, coord3] angle3 = [coord2, coord3, coord1] edge1 = (coord1 - coord2).length edge2 = (coord2 - coord3).length edge3 = (coord3 - coord1).length shortest_edge = min(edge1, edge2, edge3) radial_d = shortest_edge / n def make_fan_poly_from_edges(angle_object, radius): coordinate_1, shared_co, coordinate_2 = angle_object # get length of edge, lerp it , place a point at radial distance (pointN) len1 = (coordinate_1 - shared_co).length len2 = (coordinate_2 - shared_co).length tlerp1 = 1 / (len1 / radius) tlerp2 = 1 / (len2 / radius) point1 = shared_co.lerp(coordinate_1, tlerp1) point2 = shared_co.lerp(coordinate_2, tlerp2) # place imaginary line between (point1, point2) radial_collection = [] radial_collection.append(shared_co) # start from point1, place temp point (1/24)*i # collect points. check all points for distance to angle_point. rate = 1 / divs for notch in range(divs + 1): new_vec = point1.lerp(point2, rate * notch) # move new vec away from shared point until the distance is radius. new_vec_len = (new_vec - shared_co).length lerp_distance = radius / new_vec_len radial_point = shared_co.lerp(new_vec, lerp_distance) radial_collection.append(radial_point) radial_collection.append(shared_co) # make polygon return radial_collection bgl.glEnable(bgl.GL_BLEND) # enable blending bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) angle_list = [angle1, angle2, angle3] for item in angle_list: polyline = make_fan_poly_from_edges(item, radial_d) #can be modified per polyline bgl.glColor4f(0.103, 0.3, 0.6, 0.4) bgl.glBegin(bgl.GL_POLYGON) for segment in polyline: scr_pixel = loc3d2d(region, rv3d, segment) bgl.glVertex2f(*scr_pixel) bgl.glEnd() # get text. for item in angle_list: bgl.glColor4f(0.83, 0.8, 0.9, 0.7) angrad, angdeg = get_angle_rad(item) polyline = make_fan_poly_from_edges(item, radial_d) # find coordinate to place the text cpoint1 = polyline[0] midpoint = floor(len(polyline) / 2) cpoint2 = polyline[midpoint] cmidway = cpoint1.lerp(cpoint2, 0.5) scr_coord = loc3d2d(region, rv3d, cmidway) # round both text angrad_round = round(angrad, ANG_ROUND) angdeg_round = round(angdeg, DEG_ROUND) str_angrad = str(angrad_round) str_angdeg = str(angdeg_round) combined_string = str_angrad + " , " + str_angdeg # get length of text, place text .5 of length to the left of the coord. font_id = 0 blf.size(font_id, 12, 72) text_width, text_height = blf.dimensions(font_id, combined_string) x_pos = text_width / 2 blf.position(font_id, scr_coord[0] - x_pos, scr_coord[1], 0) blf.draw(font_id, combined_string) return
def modal(self, context, event): if event.type == 'MOUSEMOVE': Vertices = self.bm.verts # Calculate the temp t value. Stored in td tmpMouse = Vector((event.mouse_x, event.mouse_y)) t_diff = (tmpMouse - self.tmpMouse).length self.tmpMouse = tmpMouse if self.Vertex2.original.idx is not None: # 2 vertex selected td = t_diff * self.Direction / self.ScreenDistance(self.Vertex1.original.co, self.Vertex2.original.co) else: # 1 vertex selected td = t_diff * self.Direction / self.ScreenDistance(self.Vertex1.original.co, self.LinkedVertices1[self.VertLinkedIdx].original.co) if event.mouse_x < self.tmpMouse_x: td = -td if self.Vertex2.original.idx is not None: # 2 vertex selected # Calculate the t valuse if self.FirstVertexMove: self.Vertex1.t = self.Vertex1.t + td else: self.Vertex2.t = self.Vertex2.t + td # Move the vertex Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex1.original.co, self.Vertex2.original.co, self.Vertex1.t) Vertices[self.Vertex2.original.idx].co = NewCoordinate(self.Vertex2.original.co, self.Vertex1.original.co, self.Vertex2.t) else: # 1 vertex selected if self.LeftAltPress: # Continuous slide # Calculate the t valuse self.Vertex2.t = self.Vertex2.t + td # Move the vertex Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex2.original.co, self.LinkedVertices1[self.VertLinkedIdx].original.co, self.Vertex2.t) else: # Calculate the t valuse self.LinkedVertices1[self.VertLinkedIdx].t = self.LinkedVertices1[self.VertLinkedIdx].t + td # Move the vertex Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex1.original.co, self.LinkedVertices1[self.VertLinkedIdx].original.co, self.LinkedVertices1[self.VertLinkedIdx].t) self.ActiveVertex = self.Vertex1.original.idx self.tmpMouse_x = event.mouse_x context.area.tag_redraw() elif event.type == 'LEFT_SHIFT': # Hold left SHIFT for precision self.LeftShiftPress = not self.LeftShiftPress if self.LeftShiftPress: self.Direction *= 0.1 else: if self.Direction < 0: self.Direction = -1 else: self.Direction = 1 elif event.type == 'LEFT_ALT': # Hold ALT to use continuous slide self.LeftAltPress = not self.LeftAltPress if self.LeftAltPress and self.Vertex2.original.idx is None: vert = self.bm.verts[self.Vertex1.original.idx] self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z)) self.Vertex2.t = 0 elif event.type == 'LEFT_ARROW': # Reverse direction if self.Direction < 0.0: self.Direction = - self.Direction elif event.type == 'RIGHT_ARROW': # Restore direction if self.Direction > 0.0: self.Direction = - self.Direction elif event.type == 'WHEELDOWNMOUSE': # Change the vertex to be moved if self.Vertex2.original.idx is None: if self.LeftAltPress: vert=self.bm.verts[self.Vertex1.original.idx] self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z)) self.Vertex2.t = 0 self.VertLinkedIdx = self.VertLinkedIdx + 1 if self.VertLinkedIdx > len(self.LinkedVertices1) - 1: self.VertLinkedIdx = 0 bpy.ops.mesh.select_all(action='DESELECT') self.bm.verts[self.Vertex1.original.idx].select = True self.bm.verts[self.LinkedVertices1[self.VertLinkedIdx].original.idx].select = True else: self.FirstVertexMove = not self.FirstVertexMove if self.LeftAltPress == False: self.Vertex1.t = 0 self.Vertex2.t = 0 if self.FirstVertexMove: self.ActiveVertex = self.Vertex1.original.idx else: self.ActiveVertex = self.Vertex2.original.idx # Keep Vertex movement coherent with Mouse movement if self.Vertex2.original.idx is not None: if self.FirstVertexMove: tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co) tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co) if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction >= 0)): self.Direction = -self.Direction else: tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co) tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co) if (tmpX1 < tmpX2 and self.Direction < 0) or (tmpX2 < tmpX1 and self.Direction >= 0): self.Direction = -self.Direction else: tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co) tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[self.VertLinkedIdx].original.co) if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction < 0)): self.Direction = -self.Direction context.area.tag_redraw() elif event.type == 'WHEELUPMOUSE': # Change the vertex to be moved if self.Vertex2.original.idx is None: if self.LeftAltPress: vert = self.bm.verts[self.Vertex1.original.idx] self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z)) self.Vertex2.t = 0 self.VertLinkedIdx = self.VertLinkedIdx - 1 if self.VertLinkedIdx < 0: self.VertLinkedIdx = len(self.LinkedVertices1) - 1 bpy.ops.mesh.select_all(action='DESELECT') self.bm.verts[self.Vertex1.original.idx].select = True self.bm.verts[self.LinkedVertices1[self.VertLinkedIdx].original.idx].select = True else: self.FirstVertexMove = not self.FirstVertexMove if self.LeftAltPress == False: self.Vertex1.t = 0 self.Vertex2.t = 0 if self.FirstVertexMove: self.ActiveVertex = self.Vertex1.original.idx else: self.ActiveVertex = self.Vertex2.original.idx # Keep Vertex movement coherent with Mouse movement if self.Vertex2.original.idx is not None: if self.FirstVertexMove: tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co) tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co) if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction >= 0)): self.Direction = -self.Direction else: tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co) tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co) if (tmpX1 < tmpX2 and self.Direction < 0) or (tmpX2 < tmpX1 and self.Direction >= 0): self.Direction = -self.Direction else: tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co) tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[self.VertLinkedIdx].original.co) if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction < 0)): self.Direction = -self.Direction context.area.tag_redraw() elif event.type == 'LEFTMOUSE': # Confirm and exit Vertices = self.bm.verts bpy.ops.mesh.select_all(action='DESELECT') Vertices[self.Vertex1.original.idx].select = True if self.Vertex2.original.idx is not None: Vertices[self.Vertex2.original.idx].select = True context.region.callback_remove(self._handle) context.area.tag_redraw() return {'FINISHED'} elif event.type in {'RIGHTMOUSE', 'ESC'}: # Restore and exit Vertices = self.bm.verts bpy.ops.mesh.select_all(action='DESELECT') Vertices[self.Vertex1.original.idx].co = self.Vertex1.original.co Vertices[self.Vertex1.original.idx].select = True if self.Vertex2.original.idx is not None: Vertices[self.Vertex2.original.idx].co = self.Vertex2.original.co Vertices[self.Vertex2.original.idx].select = True context.region.callback_remove(self._handle) context.area.tag_redraw() return {'CANCELLED'} return {'RUNNING_MODAL'}
def invoke(self, context, event): if context.active_object == None or context.active_object.type != "MESH": self.report({'WARNING'}, "Not any active object or not an mesh object:") return {'CANCELLED'} if context.active_object.mode != 'EDIT': self.report({'WARNING'}, "Mesh isn't in Edit Mode") return {'CANCELLED'} self.obj = bpy.context.object self.mesh = self.obj.data self.bm = bmesh.from_edit_mesh(self.mesh) Count=0 Selected=False SelectedVertices = [] # Index of selected vertices for i, v in enumerate(self.bm.verts): if v.select and v.is_valid: SelectedVertices.append(v.index) Selected = True Count += 1 if (Count > 2): # More than 2 vertices selected Selected = False break if Selected == False: self.report({'WARNING'}, "0 or more then 2 vertices selected, could not start") return {'CANCELLED'} self.tmpMouse[0], self.tmpMouse[1] = (event.mouse_x, event.mouse_y) self.tmpMouse_x = self.tmpMouse[0] self.Vertex1 = Point() self.Vertex2 = Point() self.LinkedVertices1 = [] self.LinkedVertices2 = [] # Store selected vertices data. To move in the first Loop self.Vertex1.original.idx = SelectedVertices[0] self.Vertex1.original.co = self.bm.verts[SelectedVertices[0]].co.copy() self.Vertex1.new = self.Vertex1.original x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[SelectedVertices[0]].co) # For draw edge self.Vertex1.x2D = x self.Vertex1.y2D = y if len(SelectedVertices) == 2: self.Vertex2.original.idx = SelectedVertices[1] self.Vertex2.original.co = self.bm.verts[SelectedVertices[1]].co.copy() self.Vertex2.new = self.Vertex2.original x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[SelectedVertices[1]].co) # For draw edge self.Vertex2.x2D = x self.Vertex2.y2D = y if len(SelectedVertices) == 2: self.bm.verts[self.Vertex2.original.idx].select = False # Unselect the second selected vertex # Store linked vertices data, except the selected vertices for i, vert in enumerate(self.bm.verts[self.Vertex1.original.idx].link_edges): self.LinkedVertices1.append(Point()) self.LinkedVertices1[-1].original.idx = vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).index #e_0.other_vert(v_0).index self.LinkedVertices1[-1].original.co = vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).co.copy() self.LinkedVertices1[-1].new = self.LinkedVertices1[-1].original x, y = loc3d2d(context.region, context.space_data.region_3d, vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).co) # For draw edge self.LinkedVertices1[-1].x2D = x self.LinkedVertices1[-1].y2D = y if len(SelectedVertices) == 2: for i, vert in enumerate(self.bm.verts[self.Vertex2.original.idx].link_edges): self.LinkedVertices2.append(Point()) self.LinkedVertices2[-1].original.idx = vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).index self.LinkedVertices2[-1].original.co = vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).co.copy() self.LinkedVertices2[-1].new = self.LinkedVertices1[-1].original x, y = loc3d2d(context.region, context.space_data.region_3d, vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).co) # For draw edge self.LinkedVertices2[-1].x2D = x self.LinkedVertices2[-1].y2D = y # Check for no linked vertex. Can be happen also with a mix of Select Mode # Need only with 1 vertex selected if len(SelectedVertices) == 1 and len(self.LinkedVertices1) == 0: self.report({'WARNING'}, "Isolated vertex or mixed Select Mode!") return {'CANCELLED'} # Check for duplicate vertices. If some linked vertice have the same coords of selected vertice # we have the error "division by 0 if self.Vertex1.original.co == self.Vertex2.original.co: self.report({'WARNING'}, "At least one duplicate vertex") return {'CANCELLED'} self.bm.verts[self.Vertex1.original.idx].select = True # Select the first selected vertex if len(SelectedVertices) == 2: self.bm.verts[self.Vertex2.original.idx].select = True # Select the second selected vertex else: self.bm.verts[self.LinkedVertices1[0].original.idx].select = True # Select the first linked vertex self.ActiveVertex = self.Vertex1.original.idx # Keep Vertex movement coherent with Mouse movement tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co) if len(SelectedVertices) == 2: tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co) else: tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[0].original.co) if tmpX2 - tmpX1 < 0: self.Direction = -self.Direction context.area.tag_redraw() # Force the redraw of the 3D View # Add the region OpenGL drawing callback # draw in view space with 'POST_VIEW' and 'PRE_VIEW' self._handle = context.region.callback_add(self.__class__.draw_callback_px, (self, context), 'POST_PIXEL') context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'}
def draw_dimensions(region, rv3d, context, tetra_coords): apex, base1, base2, base3 = tetra_coords # TODO WARNING FACTORABLE CODE AHEAD # converting to screen coordinates screen_apex = loc3d2d(region, rv3d, apex) screen_base1 = loc3d2d(region, rv3d, base1) screen_base2 = loc3d2d(region, rv3d, base2) screen_base3 = loc3d2d(region, rv3d, base3) # another 8. # [x] 1 scr_base3_ext_y # [x] 2 scr_base2_ext_y # [x] 3 scr_base2_ext_x # [x] 4 scr_base1_ext_x # [x] 5 scr_apex_ext_y # [x] 6 scr_base1_ext_y # [x] 7 scr_liner_top # [x] 8 scr_liner_bottom # DRAW X if base3.y > apex.y: YDIR = 1 else: YDIR = -1 # do we need to draw at all if there is no x distance? if base3.y != apex.y: y_dir = NUM_UNITS * YDIR base3_ext_y = Vector((base3.x, base3.y+y_dir, base3.z)) base2_ext_y = Vector((base2.x, base2.y+y_dir, base2.z)) scr_base3_ext_y = loc3d2d(region, rv3d, base3_ext_y) scr_base2_ext_y = loc3d2d(region, rv3d, base2_ext_y) bgl.glColor4f(0.203, 0.8, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_base3) bgl.glVertex2f(*scr_base3_ext_y) bgl.glVertex2f(*screen_base2) bgl.glVertex2f(*scr_base2_ext_y) bgl.glEnd() # DRAW Y if base3.x > apex.x: XDIR = -1 else: XDIR = 1 # do we need to draw at all if there is no y distance? if base3.x != apex.x: x_dir = NUM_UNITS * XDIR base2_ext_x = Vector((base2.x+x_dir, base2.y, base2.z)) base1_ext_x = Vector((base1.x+x_dir, base1.y, base1.z)) scr_base2_ext_x = loc3d2d(region, rv3d, base2_ext_x) scr_base1_ext_x = loc3d2d(region, rv3d, base1_ext_x) bgl.glColor4f(0.203, 0.8, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_base2) bgl.glVertex2f(*scr_base2_ext_x) bgl.glVertex2f(*screen_base1) bgl.glVertex2f(*scr_base1_ext_x) bgl.glEnd() # DRAW Z # check if there is a z distance if apex.z != base3.z: # draw z, use oposite y direction y_dir = NUM_UNITS * -YDIR apex_ext_y = Vector((apex.x, apex.y+y_dir, apex.z)) base1_ext_y = Vector((base1.x, base1.y+y_dir, base1.z)) scr_apex_ext_y = loc3d2d(region, rv3d, apex_ext_y) scr_base1_ext_y = loc3d2d(region, rv3d, base1_ext_y) bgl.glColor4f(0.203, 0.8, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_apex) bgl.glVertex2f(*scr_apex_ext_y) bgl.glVertex2f(*screen_base1) bgl.glVertex2f(*scr_base1_ext_y) bgl.glEnd() # DRAW LINEAR # necessarily at the end because we know the y direction now. # X/Y angle (between base1, base3, base2) # find a cleaner (more clever) way to do if (apex.x > base3.x) and (apex.y > base3.y): vec1 = base1-base3 vec2 = base2-base3 XY_RAD = vec1.angle(vec2) # -(pi*0.75) elif (apex.x > base3.x) and (apex.y < base3.y): vec1 = base2-base1 vec2 = base3-base1 XY_RAD = vec1.angle(vec2)+(1.5*pi) elif (apex.y > base3.y) and (apex.x < base3.x): vec1 = base2-base1 vec2 = base3-base1 XY_RAD = vec1.angle(vec2)-(0.5*pi) elif (apex.x < base3.x) and (apex.y < base3.y): vec1 = base2-base1 vec2 = base3-base1 XY_RAD = -vec1.angle(vec2) +(0.5*pi) elif apex.y == base3.y: XY_RAD = pi elif apex.x == base3.x: XY_RAD = 0.5*pi else: # dont bother drawing it. return # what a jungle. marker_xyz = Vector((0.0, NUM_UNITS*-YDIR, 0.0)) myEul = Euler((0.0, 0.0, XY_RAD), 'XYZ') marker_xyz.rotate(myEul) # rotate and modify vector in place. apex_ext_xyz = apex + marker_xyz base3_ext_xyz = base3 + marker_xyz scr_apex_ext_xyz = loc3d2d(region, rv3d, apex_ext_xyz) scr_base3_ext_xyz = loc3d2d(region, rv3d, base3_ext_xyz) bgl.glColor4f(0.203, 0.8, 1.0, 0.8) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(*screen_base3) bgl.glVertex2f(*scr_base3_ext_xyz) bgl.glVertex2f(*screen_apex) bgl.glVertex2f(*scr_apex_ext_xyz) bgl.glEnd() #print("drawing dimensions next") return
def draw_tris(region, rv3d, context): divs = 24 # verts per fan. n = 3 # ratio of shortest edge. def get_tri_coords(object_list): # replace for empties code. coordlist = [obj.location for obj in object_list] return coordlist def get_angle_rad(set_of_coords): # angle1_rad = (coord3-coord1).angle(coord2-coord1) # angle2_rad = (coord1-coord2).angle(coord3-coord2) # angle3_rad = (coord2-coord3).angle(coord1-coord3) # angle1_deg = degrees(angle1_rad) # angle2_deg = degrees(angle2_rad) # angle3_deg = degrees(angle3_rad) coord1, coord2, coord3 = set_of_coords angle_rad = (coord1-coord2).angle(coord3-coord2) angle_deg = degrees(angle_rad) return angle_rad, angle_deg # if 3 empties selected coord1, coord2, coord3 = get_tri_coords(context.selected_objects) # measure angle between angle1 = [coord3, coord1, coord2] angle2 = [coord1, coord2, coord3] angle3 = [coord2, coord3, coord1] edge1 = (coord1-coord2).length edge2 = (coord2-coord3).length edge3 = (coord3-coord1).length shortest_edge = min(edge1, edge2, edge3) radial_d = shortest_edge / n def make_fan_poly_from_edges(angle_object, radius): coordinate_1, shared_co, coordinate_2 = angle_object # get length of edge, lerp it , place a point at radial distance (pointN) len1 = (coordinate_1-shared_co).length len2 = (coordinate_2-shared_co).length tlerp1 = 1/(len1/radius) tlerp2 = 1/(len2/radius) point1 = shared_co.lerp(coordinate_1, tlerp1) point2 = shared_co.lerp(coordinate_2, tlerp2) # place imaginary line between (point1, point2) radial_collection = [] radial_collection.append(shared_co) # start from point1, place temp point (1/24)*i # collect points. check all points for distance to angle_point. rate = 1/divs for notch in range(divs+1): new_vec = point1.lerp(point2, rate*notch) # move new vec away from shared point until the distance is radius. new_vec_len = (new_vec-shared_co).length lerp_distance = radius/new_vec_len radial_point = shared_co.lerp(new_vec, lerp_distance) radial_collection.append(radial_point) radial_collection.append(shared_co) # make polygon return radial_collection bgl.glEnable(bgl.GL_BLEND) # enable blending bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) angle_list = [angle1, angle2, angle3] for item in angle_list: polyline = make_fan_poly_from_edges(item, radial_d) #can be modified per polyline bgl.glColor4f(0.103, 0.3, 0.6, 0.4) bgl.glBegin(bgl.GL_POLYGON) for segment in polyline: scr_pixel = loc3d2d(region, rv3d, segment) bgl.glVertex2f(*scr_pixel) bgl.glEnd() # get text. for item in angle_list: bgl.glColor4f(0.83, 0.8, 0.9, 0.7) angrad, angdeg = get_angle_rad(item) polyline = make_fan_poly_from_edges(item, radial_d) # find coordinate to place the text cpoint1 = polyline[0] midpoint = floor(len(polyline)/2) cpoint2 = polyline[midpoint] cmidway = cpoint1.lerp(cpoint2, 0.5) scr_coord = loc3d2d(region, rv3d, cmidway) # round both text angrad_round = round(angrad, ANG_ROUND) angdeg_round = round(angdeg, DEG_ROUND) str_angrad = str(angrad_round) str_angdeg = str(angdeg_round) combined_string = str_angrad + " , " + str_angdeg # get length of text, place text .5 of length to the left of the coord. font_id = 0 blf.size(font_id, 12, 72) text_width, text_height = blf.dimensions(font_id, combined_string) x_pos = text_width/2 blf.position(font_id, scr_coord[0]-x_pos, scr_coord[1], 0) blf.draw(font_id, combined_string) return