def inset_faces_region_one_value(verts, faces, thickness, depth, edges=None, face_mask=None, props=None): # It inserts faces in region mode with one value of thickness and depth for all mesh if props is None: props = {'use_even_offset', 'use_boundary'} if not face_mask: face_mask = cycle([True]) else: face_mask = chain(face_mask, cycle([face_mask[-1]])) bm = bmesh_from_sv(verts, faces, edges, face_int_layers={ 'sv': list(range(len(faces))), 'mask': None }) mask = bm.faces.layers.int.get('mask') if thickness or depth: # use_interpolate: Interpolate mesh data: e.g. UV’s, vertex colors, weights, etc. ins_faces = [] for f, m in zip(list(bm.faces), face_mask): if m: ins_faces.append(f) else: f[mask] = 2 res = inset_region(bm, faces=ins_faces, thickness=thickness, depth=depth, use_interpolate=True, **{k: True for k in props}) for rf in res['faces']: rf[mask] = 1 return bm
def inset_faces_region_multiple_values(verts, faces, thicknesses, depths, edges=None, face_mask=None, props=None): # It split mesh into islands, calculate average value of thickness and depth per island, # inserts faces into island and merge mesh into output mesh if props is None: props = {'use_even_offset', 'use_boundary'} if not face_mask: iter_face_mask = cycle([True]) else: iter_face_mask = chain(face_mask, cycle([face_mask[-1]])) face_mask = [m for _, m in zip(range(len(faces)), iter_face_mask)] thicknesses = [ t for _, t in zip(range(len(faces)), chain(thicknesses, cycle([thicknesses[-1]]))) ] depths = [ d for _, d in zip(range(len(faces)), chain(depths, cycle([depths[-1]]))) ] bm = bmesh_from_sv(verts, faces, edges, face_int_layers={ 'sv': list(range(len(faces))), 'mask': None }) sv = bm.faces.layers.int.get('sv') mask = bm.faces.layers.int.get('mask') # Split mesh to islands islands = [] ignored_faces = [] used = set() for face in bm.faces: if face in used: continue if not face_mask[face[sv]]: ignored_faces.append(face) used.add(face) continue elif not any([thicknesses[face[sv]], depths[face[sv]]]): ignored_faces.append(face) used.add(face) continue island = [] next_faces = [face] while next_faces: nf = next_faces.pop() if nf in used: continue island.append(nf) used.add(nf) for edge in nf.edges: for twin_face in edge.link_faces: if twin_face not in used: if not face_mask[twin_face[sv]]: ignored_faces.append(twin_face) used.add(twin_face) elif not any([ thicknesses[twin_face[sv]], depths[twin_face[sv]] ]): ignored_faces.append(twin_face) used.add(twin_face) else: next_faces.append(twin_face) islands.append(island) # Regenerate mesh from islands verts_number = 0 bm_out = bmesh.new() sv_out = bm_out.faces.layers.int.new('sv') mask_out = bm_out.faces.layers.int.new('mask') for island_faces in islands: # each instance of bmesh get a lot of operative memory, they should be illuminated as fast as possible bm_isl = bmesh.new() sv_isl = bm_isl.faces.layers.int.new('sv') mask_isl = bm_isl.faces.layers.int.new('mask') used_verts = dict() for face in island_faces: face_verts = [] for v in face.verts: if v not in used_verts: v_new = bm_isl.verts.new(v.co) used_verts[v] = v_new face_verts.append(v_new) else: face_verts.append(used_verts[v]) face_new = bm_isl.faces.new(face_verts) face_new[sv_isl] = face[sv] face_new[mask_isl] = face[mask] bm_isl.normal_update() thick_isl = sum([thicknesses[f[sv_isl]] for f in bm_isl.faces]) / len(island_faces) depth_isl = sum([depths[f[sv_isl]] for f in bm_isl.faces]) / len(island_faces) res = inset_region(bm_isl, faces=bm_isl.faces, thickness=thick_isl, depth=depth_isl, use_interpolate=True, **{k: True for k in props}) for rf in res['faces']: rf[mask_isl] = 1 verts_number += merge_bmeshes(bm_out, verts_number, bm_isl) bm_isl.free() for face in ignored_faces: v_news = [] for v in face.verts: v_news.append(bm_out.verts.new(v.co)) f = bm_out.faces.new(v_news) f[sv_out] = face[sv] f[mask_out] = 2 bm.free() remove_doubles(bm_out, verts=bm_out.verts, dist=1e-6) return bm_out