import bpy import bmesh from mathutils import Vector, Matrix from bpy_extras import mesh_utils from .geometry_utils import bound_box_center from .addon_utils import get_object_color def border_over_shape(border,verts,loops): for loop in loops: for i,p in enumerate(loop): a = Vector(verts[loop[i-1]]) b = Vector(verts[p]) for j in range(0,4): c = border[j-1] d = border[j] if intersect_line_line_2d(a,b,c,d): return True for point in verts: if point_inside_rectangle(point,border): return True for point in border: if point_over_shape(point,verts,loops): return True def border_loop(vert, loop): border_edge =[e for e in vert.link_edges if e.is_boundary] if border_edge: for edge in border_edge: other_vert = edge.other_vert(vert) if not other_vert in loop: loop.append(other_vert) border_loop(other_vert, loop) return loop else: return [vert] def contour_loops(bm, vert_index=0, loops=None, vert_indices=None): loops = loops or [] vert_indices = vert_indices or [v.index for v in bm.verts] bm.verts.ensure_lookup_table() loop = border_loop(bm.verts[vert_index], [bm.verts[vert_index]]) if len(loop) >1: loops.append(loop) for v in loop: vert_indices.remove(v.index) if len(vert_indices): contour_loops(bm, vert_indices[0], loops, vert_indices) return loops def get_picker_datas(objects, canvas, rig): picker_datas = [] gamma = 1 / 2.2 if canvas.type =='CURVE': canvas_points = canvas.data.splines[0].points else: canvas_points = canvas.data.vertices canvas_coords = [canvas.matrix_world@Vector((p.co)) for p in canvas_points] canvas_x = [p[0] for p in canvas_coords] canvas_y = [p[1] for p in canvas_coords] canvas_center = sum(canvas_coords, Vector()) / len(canvas_coords) canvas_scale_fac = 4096 / (max(canvas_y) - min(canvas_y))# Reference height for the canvas objects.append(canvas) dg = bpy.context.evaluated_depsgraph_get() #sorted by their z axes for ob in sorted(objects, key=lambda x: bound_box_center(x)[2]): print('Storing shape', ob.name) mesh = bpy.data.meshes.new_from_object(ob.evaluated_get(dg)) bm = bmesh.new() bm.from_mesh(mesh) bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.002) bmesh.ops.dissolve_limit(bm, angle_limit=0.001745, verts=bm.verts, edges=bm.edges) bmesh.ops.connect_verts_concave(bm, faces=bm.faces) bmesh.ops.triangulate(bm, faces=bm.faces) #bm_loops = contour_loops(bm) #loops = [[l.index for l in loop] for loop in bm_loops] loops = [] edges = [[v.index for v in e.verts] for e in bm.edges if len(e.link_faces)<=1] bm.to_mesh(mesh) mesh.update() bm.clear() points = [] #edges = [] polygons = [] for p in mesh.vertices: point = ob.matrix_world@Vector((p.co)) point = (point - canvas_center) * canvas_scale_fac points.append([round(point[0]), round(point[1])]) for f in mesh.polygons: polygons.append([v for v in f.vertices]) #for e in mesh.edges: # # edges.append([v for v in e.vertices]) color = get_object_color(ob) if color: color = [round(pow(c, gamma), 4) for c in color] else: color = [0.5, 0.5, 0.5] shape = { 'source_name': ob.name, 'tooltip': ob.rig_picker.name, 'points': points, 'polygons': polygons, 'edges': edges, 'loops': loops, 'color': color, 'type': 'CANVAS' if ob == canvas else ob.rig_picker.shape_type } if shape['type'] =='OPERATOR': shape['operator'] = ob.rig_picker.operator #if ob.rig_picker.arguments: #shape['arguments'] = ob.rig_picker.arguments #if ob.rig_picker.shortcut: shape['shortcut'] = ob.rig_picker.shortcut elif shape['type'] =='BONE': shape['bone'] = ob.rig_picker.name picker_datas.append(shape) #print(picker_datas) return picker_datas #rig.data.rig_picker['shapes'] = picker_datas