def display_face(options, pol, data_vector, data_matrix, k, i): colo = options['face_colors'] shade = options['shading'] forced_tessellation = options['forced_tessellation'] num_verts = len(pol) dvk = data_vector[k] if shade: vectorlight = options['light_direction'] face_color = get_color_from_normal(dvk, pol, num_verts, vectorlight, colo) else: face_color = colo[:] glColor3f(*face_color) if (num_verts in {3, 4}) or (not forced_tessellation): glBegin(GL_POLYGON) for point in pol: vec = data_matrix[i] * dvk[point] glVertex3f(*vec) glEnd() else: ''' ngons, we tessellate ''' glBegin(GL_TRIANGLES) v = [dvk[i] for i in pol] for pol in tessellate([v]): for point in pol: vec = data_matrix[i] * v[point] glVertex3f(*vec) glEnd()
def ensure_triangles(coords, indices, handle_concave_quads): """ this fully tesselates the incoming topology into tris, not optimized for meshes that don't contain ngons """ new_indices = [] face_index = [] concat = new_indices.append concat2 = new_indices.extend for idf, idxset in enumerate(indices): num_verts = len(idxset) if num_verts == 3: concat(tuple(idxset)) face_index.append(idf) elif num_verts == 4 and not handle_concave_quads: # a b c d -> [a, b, c], [a, c, d] concat2([(idxset[0], idxset[1], idxset[2]), (idxset[0], idxset[2], idxset[3])]) face_index.extend([idf, idf]) else: subcoords = [Vector(coords[idx]) for idx in idxset] for pol in tessellate([subcoords]): concat([idxset[i] for i in pol]) face_index.append(idf) return new_indices, face_index
def areas_from_polygons(verts, polygons, sum_faces=False): ''' returns pols area as [float, float,...] vertices: list as [vertex, vertex, ...], being each vertex [float, float, float]. faces: list as [polygon, polygon,..], being each polygon [int, int, ...]. sum_faces if True it will return the sum of the areas as [float] ''' areas = [] concat_area = areas.append for polygon in polygons: num = len(polygon) if num == 3: concat_area( area(verts[polygon[0]], verts[polygon[1]], verts[polygon[2]])) elif num == 4: area_1 = area(verts[polygon[0]], verts[polygon[1]], verts[polygon[2]]) area_2 = area(verts[polygon[0]], verts[polygon[2]], verts[polygon[3]]) concat_area(area_1 + area_2) elif num > 4: ngon_area = 0.0 subcoords = [Vector(verts[idx]) for idx in polygon] for tri in tessellate([subcoords]): ngon_area += area(*[verts[polygon[i]] for i in tri]) concat_area(ngon_area) else: concat_area(0) if sum_faces: areas = [sum(areas)] return areas
def areas_from_polygons(verts, polygons, sum_faces=False): areas = [] concat_area = areas.append for polygon in polygons: num = len(polygon) if num == 3: concat_area( area(verts[polygon[0]], verts[polygon[1]], verts[polygon[2]])) elif num == 4: area_1 = area(verts[polygon[0]], verts[polygon[1]], verts[polygon[2]]) area_2 = area(verts[polygon[0]], verts[polygon[2]], verts[polygon[3]]) concat_area(area_1 + area_2) elif num > 4: ngon_area = 0.0 subcoords = [Vector(verts[idx]) for idx in polygon] for tri in tessellate([subcoords]): ngon_area += area(*[verts[polygon[i]] for i in tri]) concat_area(ngon_area) else: concat_area(0) if sum_faces: areas = [sum(areas)] return areas
def process(self): inputs = self.inputs outputs = self.outputs if not (inputs['Vertices'].is_linked and inputs['Polygons'].is_linked): return named = ['Vertices', 'Edges', 'Polygons'] if not (any(outputs[name].is_linked for name in named)): return vertices_s = inputs['Vertices'].sv_get(default=[[]]) faces_s = inputs['Polygons'].sv_get(default=[[]]) result_vertices = [] result_edges = [] result_faces = [] meshes = match_long_repeat([vertices_s, faces_s]) for vertices, faces in zip(*meshes): bm = bmesh_from_pydata(vertices, [], faces) new_edges = [] new_faces = [] for f in bm.faces: coords = [v.co for v in f.verts] indices = [v.index for v in f.verts] if len(coords) > 3: for pol in tessellate([coords]): new_faces.append([indices[i] for i in pol]) else: new_faces.append([v.index for v in f.verts]) result_vertices.append([v.co[:] for v in bm.verts]) result_edges.append(new_edges) result_faces.append(new_faces) output_list = [ ['Vertices', result_vertices], ['Edges', result_edges], ['Polygons', result_faces] ] for output_name, output_data in output_list: if outputs[output_name].is_linked: outputs[output_name].sv_set(output_data)
def process(self): inputs = self.inputs outputs = self.outputs if not (inputs['Vertices'].is_linked and inputs['Polygons'].is_linked): return named = ['Vertices', 'Edges', 'Polygons'] if not (any(outputs[name].is_linked for name in named)): return vertices_s = inputs['Vertices'].sv_get(default=[[]]) faces_s = inputs['Polygons'].sv_get(default=[[]]) result_vertices = [] result_edges = [] result_faces = [] meshes = match_long_repeat([vertices_s, faces_s]) for vertices, faces in zip(*meshes): bm = bmesh_from_pydata(vertices, [], faces) new_edges = [] new_faces = [] for f in bm.faces: coords = [v.co for v in f.verts] indices = [v.index for v in f.verts] if len(coords) > 3: for pol in tessellate([coords]): new_faces.append([indices[i] for i in pol]) else: new_faces.append([v.index for v in f.verts]) result_vertices.append([v.co[:] for v in bm.verts]) result_edges.append(new_edges) result_faces.append(new_faces) output_list = [['Vertices', result_vertices], ['Edges', result_edges], ['Polygons', result_faces]] for output_name, output_data in output_list: if outputs[output_name].is_linked: outputs[output_name].sv_set(output_data)
def ensure_triangles(coords, indices): """ this fully tesselates the incoming topology into tris, not optimized for meshes that don't contain ngons """ new_indices = [] concat = new_indices.append concat2 = new_indices.extend for idxset in indices: num_verts = len(idxset) if num_verts == 3: concat(tuple(idxset)) elif num_verts == 4: # a b c d -> [a, b, c], [a, c, d] concat2([(idxset[0], idxset[1], idxset[2]), (idxset[0], idxset[2], idxset[3])]) else: subcoords = [Vector(coords[idx]) for idx in idxset] for pol in tessellate([subcoords]): concat([idxset[i] for i in reversed(pol)]) return new_indices
def draw_callback(): obj = bpy.context.object check = bpy.context.scene.check is_show_color = check.is_show_color if obj and obj.type == 'MESH': # if draw_enabled[0]:s mesh = obj.data matrix_world = obj.matrix_world glLineWidth(edge_width[0]) if bpy.context.mode == 'EDIT_MESH': use_occlude = True if bm_old[0] is None or not bm_old[0].is_valid: bm = bm_old[0] = bmesh.from_edit_mesh(mesh) bm = bmesh.from_edit_mesh(mesh) else: bm = bm_old[0] obfaces = bm.faces obedges = bm.edges obverts = bm.verts info = report.info() myverts_list = [] my_edges = [] my_faces_vertices = [] my_edges_vertices = [] for i, (text, data) in enumerate(info): bm_type, bm_array, custom_rgb = data rgba = (custom_rgb[0], custom_rgb[1], custom_rgb[2], 1.0) if bm_type == bmesh.types.BMVert: if check.loose_points and text.startswith("Loose_Points"): myverts_list.append((bm_array, rgba)) elif check.doubles and text.startswith("Double Verts"): myverts_list.append((bm_array, rgba)) elif check.use_verts and text.startswith("Use Verts"): myverts_list.append((bm_array, rgba)) if bm_type == bmesh.types.BMEdge: if (check.use_multi_face and text.startswith("Use Mult Face") or (check.use_boundary and text.startswith("Use Boundary")) or (check.loose_edges and text.startswith("Loose_Edges"))): if len(bm_array) > 0: for e in bm_array: my_edges_vertices.append((e, [ (obedges[e].verts[i].co) for i in range(len(obedges[e].verts)) ], rgba)) if bm_type == bmesh.types.BMFace: rgba = (custom_rgb[0], custom_rgb[1], custom_rgb[2], 0.4) if (check.triangles and text.startswith("Triangles") or check.ngons and text.startswith("Ngons") or check.distort and text.startswith("Non-Flat Faces") or check.intersect and text.startswith("Intersect Face") or check.degenerate and text.startswith("Zero Faces") or check.loose_faces and text.startswith("Loose Faces")): if len(bm_array) > 0: for f in bm_array: my_faces_vertices.append((f, [ (obfaces[f].verts[i].co) for i in range(len(obfaces[f].verts)) ], rgba)) if len(myverts_list) > 0: for i, (bm_array, rgba) in enumerate(myverts_list): verts = [ tuple((matrix_world @ obverts[i].co).to_3d()) for i in bm_array ] #color = myverts_list[i][1] #rgba = (color[0], color[1], color[2], 1.0) draw_points(verts, rgba) # if len(my_edges) > 0: # for j in range(len(my_edges)): # #print(my_edges) # for i in my_edges[j][0]: # #edge = obedges[i] # edges = [tuple((matrix_world @ vert.co).to_3d()) for vert in obedges[i].verts] # color = my_edges[j][1] # rgba = (color[0], color[1], color[2], 1.0) # draw_line(edges,rgba) if len(my_edges_vertices) > 0: for i, (f, verts, rgba) in enumerate(my_edges_vertices): edges = [ tuple((matrix_world @ vert).to_3d()) for vert in verts ] draw_line(edges, rgba) if len(my_faces_vertices) > 0: for i, (f, verts, rgba) in enumerate(my_faces_vertices): if len(verts) == 3: # faces = [tuple((matrix_world @ vert.co).to_3d()) for i in range(len(obfaces)) for vert in obfaces[i].verts] # draw_poly(faces,COLOR_LINE) faces = [ tuple((matrix_world @ vert).to_3d()) for vert in verts ] draw_poly(faces, rgba) for edge in obfaces[f].edges: if edge.is_valid: edges = [ tuple((matrix_world @ vert.co).to_3d()) for vert in edge.verts ] draw_line(edges, COLOR_LINE) elif len(verts) >= 4: new_faces = [] faces = [] face = obfaces[f] indices = [v.index for v in face.verts] for pol in tessellate([verts]): new_faces.append([indices[i] for i in pol]) for f in new_faces: faces.append([((matrix_world @ bm.verts[i].co)[0] + face.normal.x * 0.001, (matrix_world @ bm.verts[i].co)[1] + face.normal.y * 0.001, (matrix_world @ bm.verts[i].co)[2] + face.normal.z * 0.001) for i in f]) for f in faces: draw_poly(f, rgba) for edge in face.edges: if edge.is_valid: edges = [ matrix_world @ vert.co for vert in edge.verts ] draw_line(edges, COLOR_LINE) glDisable(GL_BLEND) glLineWidth(edge_width[0]) glEnable(GL_DEPTH_TEST)
def mesh_check_draw_callback(): obj = bpy.context.object if obj and obj.type == 'MESH': if draw_enabled[0]: mesh = obj.data matrix_world = obj.matrix_world glLineWidth(edge_width[0]) if bpy.context.mode == 'EDIT_MESH': use_occlude = True if bm_old[0] is None or not bm_old[0].is_valid: bm = bm_old[0] = bmesh.from_edit_mesh(mesh) else: bm = bm_old[0] no_depth = not bpy.context.space_data.use_occlude_geometry if no_depth: glDisable(GL_DEPTH_TEST) use_occlude = False if finer_lines[0]: glLineWidth(edge_width[0] / 4.0) use_occlude = True for face in bm.faces: if len([verts for verts in face.verts]) == 3: faces = [matrix_world * vert.co for vert in face.verts] glColor4f(*faces_tri_color[0]) glEnable(GL_BLEND) glBegin(GL_POLYGON) draw_poly(faces) glEnd() for edge in face.edges: if edge.is_valid: edges = [matrix_world * vert.co for vert in edge.verts] glColor4f(*edges_tri_color[0]) glBegin(GL_LINES) draw_poly(edges) glEnd() elif len([verts for verts in face.verts]) > 4: new_faces = [] faces = [] coords = [v.co for v in face.verts] indices = [v.index for v in face.verts] for pol in tessellate([coords]): new_faces.append([indices[i] for i in pol]) for f in new_faces: faces.append( [((matrix_world * bm.verts[i].co)[0] + face.normal.x * 0.001, (matrix_world * bm.verts[i].co)[1] + face.normal.y * 0.001, (matrix_world * bm.verts[i].co)[2] + face.normal.z * 0.001) for i in f] ) for f in faces: glColor4f(*faces_ngons_color[0]) glEnable(GL_BLEND) glBegin(GL_POLYGON) draw_poly(f) glEnd() for edge in face.edges: if edge.is_valid: edges = [matrix_world * vert.co for vert in edge.verts] glColor4f(*edges_ngons_color[0]) glBegin(GL_LINES) draw_poly(edges) glEnd() glDisable(GL_BLEND) glColor4f(0.0, 0.0, 0.0, 1.0) glLineWidth(edge_width[0]) glEnable(GL_DEPTH_TEST) if use_occlude: for face in bm.faces: if len([verts for verts in face.verts]) == 3: faces = [] for vert in face.verts: vert_face = matrix_world * vert.co faces.append( (vert_face[0] + face.normal.x * 0.001, vert_face[1] + face.normal.y * 0.001, vert_face[2] + face.normal.z * 0.001) ) glColor4f(*faces_tri_color[0]) glEnable(GL_BLEND) glBegin(GL_POLYGON) draw_poly(faces) glEnd() for edge in face.edges: if edge.is_valid: edges = [] for vert in edge.verts: vert_edge = matrix_world * vert.co edges.append( (vert_edge[0] + face.normal.x * 0.001, vert_edge[1] + face.normal.y * 0.001, vert_edge[2] + face.normal.z * 0.001) ) glColor4f(*edges_tri_color[0]) glBegin(GL_LINES) draw_poly(edges) glEnd() elif len([verts for verts in face.verts]) > 4: new_faces = [] faces = [] coords = [v.co for v in face.verts] indices = [v.index for v in face.verts] for pol in tessellate([coords]): new_faces.append([indices[i] for i in pol]) for f in new_faces: faces.append([ ((matrix_world * bm.verts[i].co)[0] + face.normal.x * 0.001, (matrix_world * bm.verts[i].co)[1] + face.normal.y * 0.001, (matrix_world * bm.verts[i].co)[2] + face.normal.z * 0.001) for i in f] ) for f in faces: glColor4f(*faces_ngons_color[0]) glEnable(GL_BLEND) glBegin(GL_POLYGON) draw_poly(f) glEnd() for edge in face.edges: if edge.is_valid: edges = [] for vert in edge.verts: vert_edge = matrix_world * vert.co edges.append( (vert_edge[0] + face.normal.x * 0.001, vert_edge[1] + face.normal.y * 0.001, vert_edge[2] + face.normal.z * 0.001) ) glColor4f(*edges_ngons_color[0]) glBegin(GL_LINES) draw_poly(edges) glEnd() glDisable(GL_BLEND) glColor4f(0.0, 0.0, 0.0, 1.0)
def mesh_check_draw_callback(): obj = bpy.context.object # shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') if obj and obj.type == 'MESH': key = __package__.split(".")[0] prefs = bpy.context.preferences.addons[key].preferences if draw_enabled[0]: mesh = obj.data matrix_world = obj.matrix_world glLineWidth(prefs.edge_width) if bpy.context.mode == 'EDIT_MESH': use_occlude = True if bm_old[0] is None or not bm_old[0].is_valid: bm = bm_old[0] = bmesh.from_edit_mesh(mesh) else: bm = bm_old[0] # no_depth = not bpy.context.space_data.use_occlude_geometry no_depth = not bpy.context.space_data.overlay.show_occlude_wire if no_depth: glDisable(GL_DEPTH_TEST) if prefs.finer_lines_behind_use: glLineWidth(prefs.edge_width / 2.0) if prefs.display_non_manifold: for edge in bm.edges: if edge.is_valid and not edge.is_manifold: edges = [ matrix_world @ vert.co for vert in edge.verts ] glColor4f(*prefs.non_manifold) glBegin(GL_LINES) draw_poly(edges) glEnd() if prefs.display_e_pole or prefs.display_n_pole or prefs.display_more_pole or prefs.display_isolated_verts: pole_dict = {0: [], 3: [], 5: [], 6: []} pole_attributs = { 'display_isolated_verts': [prefs.isolated_verts, pole_dict[0]], 'display_n_pole': [prefs.n_pole_color, pole_dict[3]], 'display_e_pole': [prefs.e_pole_color, pole_dict[5]], 'display_more_pole': [prefs.more_pole_color, pole_dict[6]], } for vert in bm.verts: pole = len(vert.link_edges) if pole in [0, 3, 5] or pole > 5: verts_co = ((matrix_world @ vert.co)[0] + vert.normal.x * 0.008, (matrix_world @ vert.co)[1] + vert.normal.y * 0.008, (matrix_world @ vert.co)[2] + vert.normal.z * 0.008) if pole > 5: pole_dict[6].append(verts_co) else: pole_dict[pole].append(verts_co) for attr, options in pole_attributs.items(): if getattr(prefs, attr) and options[1]: draw_poles(options[0], prefs.point_size, options[1]) for face in bm.faces: if not face.hide: verts_count = len([verts for verts in face.verts]) tris = [] if prefs.display_tris and verts_count == 3: for vert in face.verts: tris.append( matrix_world @ vert.co) # 頂点のグローバル位置を保存? batch3 = batch_for_shader(shader3D, 'TRIS', {"pos": tris}) shader3D.uniform_float("color", prefs.tri_color) batch3.draw(shader3D) # glEnable(GL_BLEND) # glBegin(GL_POLYGON) # draw_poly(faces) # glEnd() # for edge in face.edges: # if edge.is_valid: # edges = [] # for vert in edge.verts: # vert_edge = matrix_world @ vert.co # edges.append((vert_edge[ # 0] + face.normal.x * get_offset( # obj), # vert_edge[ # 1] + face.normal.y * get_offset( # obj), # vert_edge[ # 2] + face.normal.z * get_offset( # obj)) # ) # glColor3f(*prefs.tri_color[:3]) # glBegin(GL_LINES) # draw_poly(edges) # glEnd() if prefs.display_ngons and verts_count > 4: new_faces = [] faces = [] coords = [v.co for v in face.verts] indices = [v.index for v in face.verts] ngons = [] for vert in face.verts: ngons.append( matrix_world @ vert.co) # 頂点のグローバル位置を保存? batch5 = batch_for_shader(shader3D, 'TRIS', {"pos": ngons}) shader3D.bind() shader3D.uniform_float("color", prefs.ngons_color) batch5.draw(shader3D) for pol in tessellate([coords]): new_faces.append([indices[i] for i in pol]) for f in new_faces: faces.append([ ((matrix_world * bm.verts[i].co)[0] + face.normal.x * get_offset(obj), (matrix_world * bm.verts[i].co)[1] + face.normal.y * get_offset(obj), (matrix_world * bm.verts[i].co)[2] + face.normal.z * get_offset(obj)) for i in f ]) # for f in faces: # glColor4f(*prefs.ngons_color) # glEnable(GL_BLEND) # glBegin(GL_POLYGON) # draw_poly(f) # glEnd() for edge in face.edges: if edge.is_valid: edges = [] for vert in edge.verts: vert_edge = matrix_world @ vert.co edges.append( (vert_edge[0] + face.normal.x * get_offset(obj), vert_edge[1] + face.normal.y * get_offset(obj), vert_edge[2] + face.normal.z * get_offset(obj))) # glColor3f(*prefs.ngons_color[:3]) # glBegin(GL_LINES) # draw_poly(edges) # glEnd() glDisable(GL_BLEND)
def mesh_check_draw_callback(): obj = bpy.context.object if obj and obj.type == 'MESH': key = __package__.split(".")[0] prefs = bpy.context.user_preferences.addons[key].preferences if draw_enabled[0]: mesh = obj.data matrix_world = obj.matrix_world glLineWidth(prefs.edge_width) if bpy.context.mode == 'EDIT_MESH': use_occlude = True if bm_old[0] is None or not bm_old[0].is_valid: bm = bm_old[0] = bmesh.from_edit_mesh(mesh) else: bm = bm_old[0] no_depth = not bpy.context.space_data.use_occlude_geometry if no_depth: glDisable(GL_DEPTH_TEST) if prefs.finer_lines_behind_use: glLineWidth(prefs.edge_width / 2.0) if prefs.display_non_manifold: for edge in bm.edges: if edge.is_valid and not edge.is_manifold: edges = [ matrix_world * vert.co for vert in edge.verts ] glColor4f(*prefs.non_manifold) glBegin(GL_LINES) draw_poly(edges) glEnd() if prefs.display_e_pole or prefs.display_n_pole or prefs.display_more_pole or prefs.display_isolated_verts: pole_dict = {0: [], 3: [], 5: [], 6: []} pole_attributs = { 'display_isolated_verts': [prefs.isolated_verts, pole_dict[0]], 'display_n_pole': [prefs.n_pole_color, pole_dict[3]], 'display_e_pole': [prefs.e_pole_color, pole_dict[5]], 'display_more_pole': [prefs.more_pole_color, pole_dict[6]], } for vert in bm.verts: pole = len(vert.link_edges) if pole in [0, 3, 5] or pole > 5: verts_co = ((matrix_world * vert.co)[0] + vert.normal.x * 0.008, (matrix_world * vert.co)[1] + vert.normal.y * 0.008, (matrix_world * vert.co)[2] + vert.normal.z * 0.008) if pole > 5: pole_dict[6].append(verts_co) else: pole_dict[pole].append(verts_co) for attr, options in pole_attributs.items(): if getattr(prefs, attr) and options[1]: draw_poles(options[0], prefs.point_size, options[1]) for face in bm.faces: if not face.hide: verts_count = len([verts for verts in face.verts]) if prefs.display_tris and verts_count == 3: faces = [] for vert in face.verts: vert_face = matrix_world * vert.co faces.append((vert_face[0] + face.normal.x * get_offset(obj), vert_face[1] + face.normal.y * get_offset(obj), vert_face[2] + face.normal.z * get_offset(obj))) glColor4f(*prefs.tri_color) glEnable(GL_BLEND) glBegin(GL_POLYGON) draw_poly(faces) glEnd() for edge in face.edges: if edge.is_valid: edges = [] for vert in edge.verts: vert_edge = matrix_world * vert.co edges.append( (vert_edge[0] + face.normal.x * get_offset(obj), vert_edge[1] + face.normal.y * get_offset(obj), vert_edge[2] + face.normal.z * get_offset(obj))) glColor3f(*prefs.tri_color[:3]) glBegin(GL_LINES) draw_poly(edges) glEnd() if prefs.display_ngons and verts_count > 4: new_faces = [] faces = [] coords = [v.co for v in face.verts] indices = [v.index for v in face.verts] for pol in tessellate([coords]): new_faces.append([indices[i] for i in pol]) for f in new_faces: faces.append([ ((matrix_world * bm.verts[i].co)[0] + face.normal.x * get_offset(obj), (matrix_world * bm.verts[i].co)[1] + face.normal.y * get_offset(obj), (matrix_world * bm.verts[i].co)[2] + face.normal.z * get_offset(obj)) for i in f ]) for f in faces: glColor4f(*prefs.ngons_color) glEnable(GL_BLEND) glBegin(GL_POLYGON) draw_poly(f) glEnd() for edge in face.edges: if edge.is_valid: edges = [] for vert in edge.verts: vert_edge = matrix_world * vert.co edges.append( (vert_edge[0] + face.normal.x * get_offset(obj), vert_edge[1] + face.normal.y * get_offset(obj), vert_edge[2] + face.normal.z * get_offset(obj))) glColor3f(*prefs.ngons_color[:3]) glBegin(GL_LINES) draw_poly(edges) glEnd() glDisable(GL_BLEND) glColor4f(0.0, 0.0, 0.0, 1.0)
def triangulated(face): return tessellate([[v.co for v in face.verts]])