Exemplo n.º 1
0
def inset_faces_individual_multiple_values(verts, faces, thicknesses, depths, edges=None, face_mask=None, props=None):
    # It generate Bmesh per one face, inset face into it and merge the Bmesh to output Bmesh
    if props is None:
        props = set('use_even_offset')
    if not face_mask:
        iter_face_mask = cycle([True])
    else:
        iter_face_mask = chain(face_mask, cycle([face_mask[-1]]))

    verts_number = 0
    iter_thick = chain(thicknesses, cycle([thicknesses[-1]]))
    iter_depth = chain(depths, cycle([depths[-1]]))
    bm_out = bmesh.new()
    sv = bm_out.faces.layers.int.new('sv')
    mask = bm_out.faces.layers.int.new('mask')
    for i, (f, m, t, d) in enumerate(zip(faces, iter_face_mask, iter_thick, iter_depth)):
        # each instance of bmesh get a lot of operative memory, they should be illuminated as fast as possible
        bm = bmesh_from_sv([verts[i] for i in f], [list(range(len(f)))],
                           face_int_layers={'sv': [i], 'mask': None})
        mask = bm.faces.layers.int.get('mask')
        if m and (t or d):
            res = inset_individual(bm, faces=list(bm.faces), thickness=t, depth=d,
                                   use_even_offset='use_even_offset' in props, use_interpolate=True,
                                   use_relative_offset='use_relative_offset' in props)
            for rf in res['faces']:
                rf[mask] = 1
        else:
            for face in bm.faces:
                face[mask] = 2
        verts_number += merge_bmeshes(bm_out, verts_number, bm)
        bm.free()
    remove_doubles(bm_out, verts=bm_out.verts, dist=1e-6)
    return bm_out
Exemplo n.º 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