Пример #1
0
        def process_data(self, params):

            point_clouds_out = []
            for vertices, normals, colors in zip(*params):
                pcd = o3d.geometry.PointCloud()
                pcd.points = o3d.utility.Vector3dVector(np.array(vertices))
                if has_element(normals):
                    pcd.normals = o3d.utility.Vector3dVector(np.array(normals))
                elif self.normal_method != 'NONE':
                    calc_point_cloud_normals(pcd, self.normal_quality,
                                             self.normal_method)

                if has_element(colors):
                    pcd.colors = o3d.utility.Vector3dVector(
                        np.array(colors)[:, :3])
                point_clouds_out.append(pcd)

            return point_clouds_out
Пример #2
0
def edges_length(vertices, edges, sum_length=False, out_numpy=False):
    '''
    calculate edges length using numpy
    vertices: list as [vertex, vertex, ...] being each vertex [float, float, float]. Also accept numpy arrays with two axis
    edges: list as [edge, edge,..] being each edge [int, int]. Also accept numpy arrays with one axis
    sum_length: boolean to determine if outputtig each length or the sum of all
    out_numpy: boolean to determine if outputtig  np_array or regular python list
    returns length of edges or sum of lengths
    '''
    if not has_element(vertices):
        return
    if not has_element(edges):
        edges = edges_aux(vertices)
    v_edges = get_v_edges(vertices, edges)
    vect = v_edges[:, 1, :] - v_edges[:, 0, :]
    length = np.linalg.norm(vect, axis=1)
    if sum_length:
        length = np.sum(length)[np.newaxis]

    return length if out_numpy else length.tolist()
Пример #3
0
        def process_data(self, params):

            mesh_out = []
            matched = numpy_full_list_cycle
            vec_3f = o3d.utility.Vector3dVector
            vec_3i = o3d.utility.Vector3iVector
            for base_mesh, vertices, verts_normals, verts_colors, faces, f_normals, uv_verts, uv_faces, material_id in zip(
                    *params):
                if base_mesh:
                    mesh = copy.deepcopy(base_mesh)
                else:
                    mesh = o3d.geometry.TriangleMesh()

                if has_element(vertices):
                    np_vertices = np.array(vertices)
                    mesh.vertices = vec_3f(np_vertices)

                if has_element(faces):
                    try:
                        np_triangles = np.array(faces).astype(np.int32)
                    except ValueError:
                        raise Exception('Only Triangular Faces Accepted')
                    if np_triangles.shape[1] != 3:
                        raise Exception('Only Triangular Faces Accepted')
                    mesh.triangles = vec_3i(np_triangles)

                vert_len = len(mesh.vertices)
                tri_len = len(mesh.triangles)
                if has_element(verts_normals):
                    mesh.vertex_normals = vec_3f(
                        matched(np.array(verts_normals), vert_len))

                if has_element(verts_colors):
                    mesh.vertex_colors = vec_3f(
                        matched(np.array(verts_colors)[:, :3], vert_len))

                if has_element(f_normals):
                    print(len(f_normals))
                    mesh.triangle_normals = vec_3f(
                        matched(np.array(f_normals), tri_len))

                if has_element(uv_verts) and has_element(uv_faces):
                    np_uv_faces = np.array(uv_faces)
                    np_uv_verts = np.array(uv_verts)
                    uvs_0 = np_uv_verts[np_uv_faces][:, :, :2]
                    uvs = o3d.utility.Vector2dVector(
                        matched(uvs_0, tri_len).reshape(-1, 2))
                    mesh.triangle_uvs = uvs

                if len(material_id) > 0:
                    mesh.triangle_material_ids = o3d.utility.IntVector(
                        matched(np.array(material_id), tri_len))
                mesh_out.append(mesh)

            return mesh_out
Пример #4
0
def calc_mesh_normals_np(vertices,
                         faces,
                         get_f_normals=True,
                         get_v_normals=True,
                         non_planar=True,
                         v_normal_alg='MWE',
                         output_numpy=True):
    if not has_element(faces):
        return [], vertices

    np_verts, np_faces = prepare_arrays(vertices, faces)

    if get_v_normals:
        v_normals = np.zeros(np_verts.shape, dtype=np_verts.dtype)
        if v_normal_alg in ('MWE', 'MWAT'):
            norm_func = mean_weighted_equally
        else:
            norm_func = mean_weighted_unequally

    if np_faces.dtype == object:
        np_len = np.vectorize(len)
        lens = np_len(np_faces)
        pol_types = np.unique(lens)
        f_normals = np.zeros((len(np_faces), 3), dtype=np.float64)
        for pol_sides in pol_types:
            mask = lens == pol_sides
            np_faces_g = np.array(np_faces[mask].tolist())
            v_pols = np_verts[np_faces_g]
            if get_v_normals:
                f_normal_g, v_normals = norm_func(np_faces_g, v_pols,
                                                  v_normals, non_planar,
                                                  v_normal_alg)
            else:
                f_normals = np_faces_normals(v_pols)

            f_normals[mask, :] = f_normal_g

    else:
        pol_sides = np_faces.shape[1]
        v_pols = np_verts[np_faces]
        if get_v_normals:
            f_normals, v_normals = norm_func(np_faces, v_pols, v_normals,
                                             non_planar, v_normal_alg)
        else:
            f_normals = np_faces_normals(v_pols)

    if output_numpy:
        return (f_normals if get_f_normals else [],
                np_normalize_vectors(v_normals) if get_v_normals else [])
    return (f_normals.tolist() if get_f_normals else [],
            np_normalize_vectors(v_normals).tolist() if get_v_normals else [])
Пример #5
0
def np_process_polygons(verts, faces, func=None, dims=3, output_numpy=False):
    if not func:
        return
    if not (has_element(verts) and has_element(faces)):
        return
    if isinstance(verts, np.ndarray):
        np_verts = verts
    else:
        np_verts = np.array(verts)

    if isinstance(faces, np.ndarray):
        np_faces = faces
    else:
        np_faces = np.array(faces)

    if np_faces.dtype == object:
        np_len = np.vectorize(len)
        lens = np_len(np_faces)
        pol_types = np.unique(lens)
        if dims == 1:
            vals = np.zeros(np_faces.shape[0], dtype=float)
        else:
            vals = np.zeros((np_faces.shape[0], dims), dtype=float)
        for p in pol_types:
            mask = lens == p
            np_faces_g = np.array(np_faces[mask].tolist())
            v_pols = np_verts[np_faces_g]
            if dims == 1:
                vals[mask] = func(v_pols)
            else:
                vals[mask, :] = func(v_pols)
    else:
        v_pols = np_verts[np_faces]  #num pols, num sides
        vals = func(v_pols)

    if output_numpy:
        return vals
    return vals.tolist()
Пример #6
0
 def is_triangles_only(faces):
     if has_element(faces): return all((len(f) == 3 for f in faces))
Пример #7
0
def inset_special_np(vertices,
                     faces,
                     inset_rates,
                     distances,
                     ignores,
                     make_inners,
                     custom_normals,
                     matrices,
                     zero_mode="SKIP",
                     offset_mode='CENTER',
                     proportional=False,
                     concave_support=True,
                     output_old_face_id=False,
                     output_old_v_id=False,
                     output_pols_groups=False,
                     output_new_verts_mask=False):

    if not has_element(faces):
        return
    new_faces, new_ignores, new_insets = [], [], []
    original_face_ids, original_vertex_id, new_pols_groups, new_verts_mask = [], [], [], []
    inset_faces_id, fan_faces_id, ignores_id, fan_faces = [], [], [], []
    np_distances, np_matrices = [], []

    np_verts = vertices if isinstance(vertices,
                                      np.ndarray) else np.array(vertices)

    invert_face_mask = numpy_full_list(np_array(ignores, dtype=bool),
                                       len(faces))
    np_faces_mask = np.invert(invert_face_mask)

    if not any(np_faces_mask):
        return

    np_faces = np_array(faces)
    np_faces_id = np.arange(len(faces)) if output_old_face_id else []
    np_inset_rate = numpy_full_list(inset_rates, len(faces))
    if has_element(custom_normals):
        np_custom_normals = numpy_full_list(custom_normals, len(faces))
        use_custom_normals = True
    else:
        np_custom_normals = []
        use_custom_normals = False

    if offset_mode == 'CENTER':
        zero_inset = np_inset_rate == 0
        if zero_mode == 'SKIP':
            np_faces_mask[zero_inset] = False
            invert_face_mask[zero_inset] = True

            inset_pols = np_faces[np_faces_mask]
            np_distances = numpy_full_list(distances,
                                           len(faces))[np_faces_mask]
            np_inset_rate = np_inset_rate[np_faces_mask]
            np_make_inners = numpy_full_list(
                make_inners, len(faces)).astype(bool)[np_faces_mask]
            new_ignores = np_faces[invert_face_mask].tolist()

            if output_old_face_id:
                ignores_id = np_faces_id[invert_face_mask].tolist()
                inset_faces_id = np_faces_id[np_faces_mask]

        else:  # FAN
            if output_old_face_id:
                ignores_maks = np.invert(np_faces_mask)
                ignores_id = np_faces_id[ignores_maks].tolist()
                new_ignores = np_faces[ignores_maks].tolist()
            else:
                new_ignores = np_faces[np.invert(np_faces_mask)].tolist()

            np_faces_mask[zero_inset] = False
            inset_pols = np_faces[np_faces_mask]
            np_make_inners = numpy_full_list(
                make_inners, len(faces)).astype(bool)[np_faces_mask]

            np_all_distances = numpy_full_list(distances, len(faces))
            np_distances = np_all_distances[np_faces_mask]
            np_inset_rate = np_inset_rate[np_faces_mask]
            fan_faces = np_faces[zero_inset]
            fan_distances = np_all_distances[zero_inset]
            if output_old_face_id:
                inset_faces_id = np_faces_id[np_faces_mask]
                fan_faces_id = np_faces_id[zero_inset]
    else:  #SIDES mode
        inset_pols = np_faces[np_faces_mask]
        if offset_mode == 'SIDES':
            np_distances = numpy_full_list(distances,
                                           len(faces))[np_faces_mask]
            np_inset_rate = np_inset_rate[np_faces_mask]
        else:  #MATRIX
            if len(matrices) == len(faces):
                np_matrices = np.array(matrices)[np_faces_mask]
            else:
                np_matrices = numpy_full_list(matrices, len(inset_pols))

        np_make_inners = numpy_full_list(
            make_inners, len(faces)).astype(bool)[np_faces_mask]
        new_ignores = np_faces[invert_face_mask].tolist()
        fan_faces = []
        if output_old_face_id:
            ignores_id = np_faces_id[invert_face_mask].tolist()
            inset_faces_id = np_faces_id[np_faces_mask]

    common_args = {
        'use_custom_normals': use_custom_normals,
        'output_old_v_id': output_old_v_id,
        'output_old_face_id': output_old_face_id,
        'output_pols_groups': output_pols_groups
    }
    new_verts = np_verts.tolist()
    if output_old_v_id:
        original_vertex_id = list(range(len(vertices)))
    if output_new_verts_mask:
        new_verts_mask.extend([0] * len(new_verts))

    variable_pols = inset_pols.dtype == 'object'
    np_len = np_vectorize(len)
    index_offset = 0

    if len(inset_pols) > 0:
        if variable_pols:
            lens = np_len(inset_pols)
            pol_types = np.unique(lens)

        else:
            pol_types = [inset_pols.shape[1]]

        for pol_sides in pol_types:
            if variable_pols:
                mask = lens == pol_sides
                pols_group = np_array(inset_pols[mask].tolist(), dtype=int)
                res = inset_regular_pols(
                    np_verts,
                    pols_group,
                    np_distances[mask] if offset_mode != 'MATRIX' else [],
                    np_inset_rate[mask] if offset_mode != 'MATRIX' else [],
                    np_make_inners[mask],
                    inset_faces_id[mask] if output_old_face_id else [],
                    np_custom_normals[mask] if use_custom_normals else [],
                    np_matrices[mask] if offset_mode == 'MATRIX' else [],
                    offset_mode=offset_mode,
                    proportional=proportional,
                    concave_support=concave_support,
                    index_offset=index_offset,
                    **common_args)

            else:
                res = inset_regular_pols(
                    np_verts,
                    inset_pols,
                    np_distances,
                    np_inset_rate,
                    np_make_inners,
                    inset_faces_id if output_old_face_id else [],
                    np_custom_normals if use_custom_normals else [],
                    np_matrices,
                    offset_mode=offset_mode,
                    proportional=proportional,
                    concave_support=concave_support,
                    index_offset=index_offset,
                    **common_args)
            index_offset += len(res[0])
            new_verts.extend(res[0])
            new_faces.extend(res[1])
            new_insets.extend(res[2])
            original_vertex_id.extend(res[3])
            original_face_ids.extend(res[4])
            new_pols_groups.extend(res[5])
            if output_new_verts_mask:
                new_verts_mask.extend([1] * len(res[0]))

    if zero_mode == 'FAN' and len(fan_faces) > 0:
        if variable_pols:
            lens = np_len(fan_faces)
            pol_types = np.unique(lens)
        else:
            pol_types = [inset_pols.shape[1]]
        for pol_sides in pol_types:
            if variable_pols:
                mask = lens == pol_sides
                pols_group = np_array(fan_faces[mask].tolist(), dtype=int)
                res = fan_regular_pols(
                    np_verts,
                    pols_group,
                    fan_distances[mask],
                    fan_faces_id[mask] if output_old_face_id else [],
                    np_custom_normals[mask] if use_custom_normals else [],
                    index_offset=index_offset,
                    **common_args)
            else:
                res = fan_regular_pols(
                    np_verts,
                    fan_faces,
                    fan_distances,
                    fan_faces_id if output_old_face_id else [],
                    np_custom_normals if use_custom_normals else [],
                    index_offset=index_offset,
                    **common_args)

            index_offset += len(res[0])
            new_verts.extend(res[0])
            new_faces.extend(res[1])
            original_vertex_id.extend(res[2])
            original_face_ids.extend(res[3])
            new_pols_groups.extend(res[4])
            if output_new_verts_mask:
                new_verts_mask.extend([1] * len(res[0]))

    return (new_verts, new_faces + new_ignores, new_ignores, new_insets,
            original_vertex_id, original_face_ids + ignores_id,
            new_pols_groups + [0] * len(new_ignores), new_verts_mask)
Пример #8
0
def bmesh_from_pydata(verts=None,
                      edges=[],
                      faces=[],
                      markup_face_data=False,
                      markup_edge_data=False,
                      markup_vert_data=False,
                      normal_update=False,
                      index_edges=False):
    """
    verts              : necessary
    edges / faces      : optional
    normal_update      : optional - will update verts/edges/faces normals at the end
    index_edges (bool) : optional - will make it possible for users of the bmesh to manually 
                         iterate over any edges or do index lookups
    """

    bm = bmesh.new()
    bm_verts = bm.verts
    add_vert = bm_verts.new

    py_verts = verts.tolist() if type(verts) == np.ndarray else verts

    for co in py_verts:
        add_vert(co)

    bm_verts.index_update()
    bm_verts.ensure_lookup_table()

    if has_element(faces):
        add_face = bm.faces.new
        py_faces = faces.tolist() if type(faces) == np.ndarray else faces
        for face in py_faces:
            add_face(tuple(bm_verts[i] for i in face))

        bm.faces.index_update()

    if has_element(edges):
        if markup_edge_data:
            initial_index_layer = bm.edges.layers.int.new("initial_index")

        add_edge = bm.edges.new
        get_edge = bm.edges.get
        py_faces = edges.tolist() if type(edges) == np.ndarray else edges
        for idx, edge in enumerate(edges):
            edge_seq = tuple(bm_verts[i] for i in edge)
            bm_edge = get_edge(edge_seq)
            if not bm_edge:
                bm_edge = add_edge(edge_seq)
            if markup_edge_data:
                bm_edge[initial_index_layer] = idx

    if has_element(edges) or index_edges:
        bm.edges.index_update()

    if markup_vert_data:
        bm_verts.ensure_lookup_table()
        layer = bm_verts.layers.int.new("initial_index")
        for idx, vert in enumerate(bm_verts):
            vert[layer] = idx

    if markup_face_data:
        bm.faces.ensure_lookup_table()
        layer = bm.faces.layers.int.new("initial_index")
        for idx, face in enumerate(bm.faces):
            face[layer] = idx

    if normal_update:
        bm.normal_update()
    return bm
Пример #9
0
def bmesh_from_pydata(verts=None,
                      edges=[],
                      faces=[],
                      markup_face_data=False,
                      markup_edge_data=False,
                      markup_vert_data=False,
                      normal_update=False):
    ''' verts is necessary, edges/faces are optional
        normal_update, will update verts/edges/faces normals at the end
    '''

    bm = bmesh.new()
    bm_verts = bm.verts
    add_vert = bm_verts.new

    py_verts = verts.tolist() if type(verts) == np.ndarray else verts

    for co in py_verts:
        add_vert(co)

    bm_verts.index_update()
    bm_verts.ensure_lookup_table()

    if has_element(faces):
        add_face = bm.faces.new
        py_faces = faces.tolist() if type(faces) == np.ndarray else faces
        for face in py_faces:
            add_face(tuple(bm_verts[i] for i in face))

        bm.faces.index_update()

    if has_element(edges):
        if markup_edge_data:
            initial_index_layer = bm.edges.layers.int.new("initial_index")

        add_edge = bm.edges.new
        get_edge = bm.edges.get
        py_faces = edges.tolist() if type(edges) == np.ndarray else edges
        for idx, edge in enumerate(edges):
            edge_seq = tuple(bm_verts[i] for i in edge)
            bm_edge = get_edge(edge_seq)
            if not bm_edge:
                bm_edge = add_edge(edge_seq)
            if markup_edge_data:
                bm_edge[initial_index_layer] = idx

        bm.edges.index_update()

    if markup_vert_data:
        bm_verts.ensure_lookup_table()
        layer = bm_verts.layers.int.new("initial_index")
        for idx, vert in enumerate(bm_verts):
            vert[layer] = idx

    if markup_face_data:
        bm.faces.ensure_lookup_table()
        layer = bm.faces.layers.int.new("initial_index")
        for idx, face in enumerate(bm.faces):
            face[layer] = idx

    if normal_update:
        bm.normal_update()
    return bm
Пример #10
0
    def triangle_mesh_poke(mesh, mask_in, offset_in, v_color, mat_id, relative_offset=False, deepcopy=True):
        if deepcopy:
            triangle_mesh = copy.deepcopy(mesh)
        else:
            triangle_mesh = mesh
        np_verts = np.asarray(triangle_mesh.vertices)

        mask = numpy_full_list(mask_in, len(triangle_mesh.triangles)).astype('bool')
        if len(offset_in) == np.sum(mask):
            offset = np.array(offset_in)[:, np.newaxis]
        elif len(offset_in) > 1:
            offset = numpy_full_list(offset_in, len(triangle_mesh.triangles))[mask, np.newaxis]
        else:
            offset = offset_in

        np_faces = np.asarray(triangle_mesh.triangles)
        faces_masked = np_faces[mask]
        v_pols = np_verts[np_faces[mask]]
        center = np.sum(v_pols, axis=1) / 3
        normals = get_normals(triangle_mesh, np_verts, np_faces, mask)
        faces_num = np_faces[mask].shape[0]
        if relative_offset:
            areas = calc_tris_areas(v_pols)
            new_vecs = center + normals * (offset* areas[:, np.newaxis])
        else:
            new_vecs = center + normals * offset
        all_vecs = np.concatenate([np_verts, new_vecs])

        new_faces = np.zeros((faces_num, 3, 3), dtype='int')

        new_faces[:, :, 2] = (np.arange(faces_num) + len(np_verts))[:, np.newaxis]
        for i in range(3):
            new_faces[:, i, 0] = np_faces[mask, i]
            new_faces[:, i, 1] = np_faces[mask, (i + 1) % 3]
        new_faces_shaped = new_faces.reshape(-1, 3)
        all_faces = np.concatenate([np_faces[np.invert(mask)], new_faces_shaped])
        if has_element(v_color):
            if triangle_mesh.has_vertex_colors():
                v_col = numpy_full_list(v_color, len(new_vecs))[:,:3]
                triangle_mesh.vertex_colors = vec_3f(np.concatenate([np.asarray(triangle_mesh.vertex_colors), v_col]))
        else:
            spread_vertex_attrib(triangle_mesh, faces_masked, 'vertex_colors')
        spread_vertex_attrib(triangle_mesh, faces_masked, 'vertex_normals')
        spread_face_attrib(triangle_mesh, mask, 'triangle_normals', 3, vec_3f)
        if len(mat_id) > 0:
            if triangle_mesh.has_triangle_material_ids():
                mat_id_shaped = numpy_full_list(mat_id, len(new_faces_shaped))
                triangle_mesh.triangle_material_ids = vec_1i(
                    np.concatenate(
                        [np.asarray(triangle_mesh.triangle_material_ids)[np.invert(mask)],
                         mat_id_shaped]
                    ))
            else:
                mat_id_shaped = numpy_full_list(mat_id, len(all_faces))
                triangle_mesh.triangle_material_ids = vec_1i(mat_id_shaped)
        else:
            spread_face_attrib(triangle_mesh, mask, 'triangle_material_ids', 1, vec_1i)
        poke_uvs(triangle_mesh, mask)
        triangle_mesh.vertices = vec_3f(all_vecs)
        triangle_mesh.triangles = vec_3i(all_faces)
        return (triangle_mesh,
                new_vecs,
                np.arange(len(np_verts), len(np_verts)+len(new_vecs)),
                np.arange(len(all_faces)-len(new_faces_shaped), len(all_faces))
                )