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
Exemple #2
0
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
Exemple #3
0
 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 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
Exemple #6
0
 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
Exemple #7
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 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)
Exemple #9
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
Exemple #10
0
 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()
Exemple #11
0
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)
Exemple #13
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 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()
Exemple #16
0
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
Exemple #24
0
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
Exemple #25
0
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
Exemple #26
0
    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