Example #1
0
def mean_weighted_unequally(np_faces, v_pols, v_normals, non_planar,
                            factor_mode):
    pol_sides = v_pols.shape[1]
    factor_func = VERTEX_NORMAL_FACTOR_METHODS[factor_mode]
    if non_planar:
        face_factor = np.zeros((len(v_pols), pol_sides), dtype=np.float64)
        f_normals = np.zeros((len(v_pols), 3), dtype=np.float64)
        for i in range(pol_sides - 1):
            side1 = v_pols[::, (1 + i) % pol_sides] - v_pols[::, i]
            side2 = v_pols[::, (i - 1) % pol_sides] - v_pols[::, i]
            cross = np.cross(side1, side2)
            face_factor[:, i] = factor_func(cross, side1, side2)
            f_normals += cross
    else:
        side1 = v_pols[::, 1] - v_pols[::, 0]
        side2 = v_pols[::, 2] - v_pols[::, 0]
        f_normals = np.cross(side1, side2)
        face_factor = factor_func(f_normals, side1, side2)

    if factor_mode in AREA_DEPENDENT_FACTORS:
        np_normalize_vectors(f_normals)

    for i in range(np_faces.shape[1]):
        np.add.at(v_normals, np_faces[:, i],
                  f_normals * face_factor[:, i, np.newaxis])

    if not factor_mode in AREA_DEPENDENT_FACTORS:
        np_normalize_vectors(f_normals)
    return f_normals, v_normals
Example #2
0
def np_vertex_normals(vertices, faces, algorithm='MWE', output_numpy=False):

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

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

    v_normals = np.zeros(np_verts.shape, dtype=np_verts.dtype)

    if np_faces.dtype == object:
        np_len = np.vectorize(len)
        lens = np_len(np_faces)
        pol_types = np.unique(lens)
        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]
            add_faces_normals(v_pols, np_faces_g, algorithm, pol_sides,
                              v_normals)

    else:
        pol_sides = np_faces.shape[1]
        v_pols = np_verts[np_faces]
        add_faces_normals(v_pols, np_faces, algorithm, pol_sides, v_normals)

    if output_numpy:
        return np_normalize_vectors(v_normals)
    return np_normalize_vectors(v_normals).tolist()
Example #3
0
def np_faces_normals(v_pols):
    pol_sides = v_pols.shape[1]
    if pol_sides > 3:
        f_normals = np.zeros((len(v_pols), 3), dtype=np.float64)
        for i in range(pol_sides - 2):
            f_normals += np.cross(v_pols[::, (1+i)%pol_sides] - v_pols[::, 0], v_pols[::, (2+i)%pol_sides] - v_pols[::, 0])
    else:
        f_normals = np.cross(v_pols[::, 1] - v_pols[::, 0], v_pols[::, 2] - v_pols[::, 0])
    np_normalize_vectors(f_normals)

    return f_normals
Example #4
0
def edges_direction(vertices, edges, out_numpy=False):
    '''
    calculate edges direction
    vertices: list as [vertex, vertex, ...], being each vertex [float, float, float]. Also accepts numpy arrays with two axis
    edges: list as [edge, edge,..], being each edge [int, int]. Also accept numpy arrays with one axis.
    out_numpy: boolean to determine if outputtig  np_array or regular python list
    returns edges direction as [vertex, vertex,...] or numpy array with two axis
    '''
    v_edges = get_v_edges(vertices, edges)
    if out_numpy:
        return np_normalize_vectors(v_edges[:, 1, :] - v_edges[:, 0, :])

    return np_normalize_vectors(v_edges[:, 1, :] - v_edges[:, 0, :]).tolist()
Example #5
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 [])
Example #6
0
def mean_weighted_equally(np_faces, v_pols, v_normals, non_planar, algorithm):
    pol_sides = v_pols.shape[1]
    if non_planar:
        f_normals = np.zeros((len(v_pols), 3), dtype=np.float64)
        for i in range(pol_sides - 1):
            f_normals += np.cross(v_pols[::, (1+i)%pol_sides] - v_pols[::, i],
                                  v_pols[::, (i-1)%pol_sides] - v_pols[::, i])
    else:
        f_normals = np.cross(v_pols[::, 1] - v_pols[::, 0],
                             v_pols[::, 2] - v_pols[::, 0])
    if algorithm == 'MWE':
        np_normalize_vectors(f_normals)

    for i in range(np_faces.shape[1]):
        np.add.at(v_normals, np_faces[:, i], f_normals)

    if algorithm == 'MWAT':
        np_normalize_vectors(f_normals)
    return f_normals, v_normals
Example #7
0
def add_faces_normals(v_pols, np_faces_g, algorithm, pol_sides, v_normals):
    if algorithm in ('MWE', 'MWAT'):
        if algorithm == 'MWE':  #weighted equally
            f_normal_g = np_normalize_vectors(np_faces_normals(v_pols))
        else:  #weighted by area of triangle
            f_normal_g = np_faces_normals(v_pols)
        for i in range(pol_sides):
            np.add.at(v_normals, np_faces_g[:, i], f_normal_g)
    else:
        if algorithm == 'MWELR':  #weighted edge length reciprocal
            f_normal_g = np_normalize_vectors(np_faces_normals(v_pols))
        else:  # algorithm == 'MWS': #weighted by sine
            f_normal_g = np_faces_normals(v_pols)
        edges_length = np.linalg.norm(v_pols - np.roll(v_pols, 1, axis=1),
                                      axis=2)
        factor = edges_length * np.roll(edges_length, -1, axis=1)

        for i in range(pol_sides):
            np.add.at(v_normals, np_faces_g[:, i],
                      f_normal_g * factor[:, i, np.newaxis])
Example #8
0
def np_tangent_center_orig(v_pols):
    return np_normalize_vectors(np_center_median(v_pols) - v_pols[:, 0, :])
Example #9
0
def np_tangent_longest_edge(v_pols):
    edges_dir = v_pols - np.roll(v_pols, 1, axis=1)
    ed_length = np.linalg.norm(edges_dir, axis=2)
    ed_idx = np.argmax(ed_length, axis=1)

    return np_normalize_vectors(edges_dir[np.arange(len(v_pols)), ed_idx, :])