Beispiel #1
0
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
Beispiel #2
0
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