Example #1
0
def normal_offset(v_pols, normal_displace, random_normal):

    if normal_displace == 0:
        return face_perimeter(v_pols)[:, np.newaxis] * np_faces_normals(v_pols) * (2*random_normal-random_normal) * random(len(v_pols))[:, np.newaxis]

    if random_normal == 0:
        return face_perimeter(v_pols)[:, np.newaxis] * np_faces_normals(v_pols) * (normal_displace)

    return face_perimeter(v_pols)[:, np.newaxis] * np_faces_normals(v_pols) * (normal_displace + (2*random_normal-random_normal) * random(len(v_pols))[:, np.newaxis])
Example #2
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 #3
0
def matrix_mode_inset(v_pols, matrices, use_custom_normals, custom_normals):
    pol_sides = v_pols.shape[1]
    average = np.sum(v_pols, axis=1) / pol_sides
    if use_custom_normals:
        normals = custom_normals
    else:
        normals = np_faces_normals(v_pols)

    pol_matrix = np.repeat(IDENTITY_MATRIX[np.newaxis, :, :],
                           len(v_pols),
                           axis=0)

    mask = np.all([normals[:, 0] == 0, normals[:, 1] == 0], axis=0)
    mask2 = normals[:, 2] <= 0
    mask4 = mask * mask2
    r_mask = np.invert(mask)

    x_axis = np.zeros(normals.shape, dtype=float)
    x_axis[:, 0] = normals[:, 1] * -1
    x_axis[:, 1] = normals[:, 0]
    y_axis = np.cross(normals, x_axis, axis=1)

    pol_matrix[r_mask, :3, 2] = normals[r_mask, :]
    pol_matrix[r_mask, :3, 1] = y_axis[r_mask, :]
    pol_matrix[r_mask, :3, 0] = x_axis[r_mask, :]
    pol_matrix[mask4, :, :] = INVERSE_IDENTITY_MATRIX[np.newaxis, :]
    pol_matrix[:, :3, 3] = average

    inverted_mat = np.linalg.inv(pol_matrix)

    matrices = np.matmul(matrices, inverted_mat)
    matrices = np.matmul(pol_matrix, matrices)

    return apply_matrices_to_v_pols(v_pols, matrices)
Example #4
0
def sides_mode_inset(v_pols, np_inset_rate, np_distances, concave_support,
                     proportional, use_custom_normals, custom_normals):
    pol_sides = v_pols.shape[1]
    dirs = np.zeros(v_pols.shape, dtype=float)

    if concave_support:
        normals = custom_normals if use_custom_normals else np_faces_normals(
            v_pols)
        for i in range(pol_sides):
            side1 = normalize_v3(v_pols[:, (i + 1) % pol_sides] - v_pols[:, i])
            side2 = normalize_v3(v_pols[:, i - 1] - v_pols[:, i])
            dirs[:, i] = normalize_or_calc(side1, side2, normals)
            dirs[:, i] *= (
                np_inset_rate /
                (np.sqrt(1 - np.clip(np_dot(side1, dirs[:, i]), -1.0, 1.0)**2))
            )[:, np_newaxis]

        average = np.sum(v_pols, axis=1) / pol_sides
        concave_mask = np_dot(average[:, np_newaxis, :] - v_pols, dirs,
                              axis=2) < 0

        dirs[concave_mask] *= -1
    else:
        for i in range(pol_sides):
            side1 = normalize_v3(v_pols[:, (i + 1) % pol_sides] - v_pols[:, i])
            side2 = normalize_v3(v_pols[:, i - 1] - v_pols[:, i])
            dirs[:, i] = normalize_v3(
                normalize_v3(v_pols[:, (i + 1) % pol_sides] - v_pols[:, i]) +
                normalize_v3(v_pols[:, i - 1] - v_pols[:, i]))

            dirs[:, i] *= (
                np_inset_rate /
                (np.sqrt(1 - np.clip(np_dot(side1, dirs[:, i]), -1.0, 1.0)**2))
            )[:, np_newaxis]

    if proportional:
        dirs *= face_perimeter(v_pols)[:, np_newaxis, np_newaxis]
    if any(np_distances != 0):
        if not concave_support:
            normals = custom_normals if use_custom_normals else np_faces_normals(
                v_pols)
        z_offset = normals * np_distances[:, np_newaxis]
        inner_points = dirs + v_pols + z_offset[:, np_newaxis, :]
    else:
        inner_points = dirs + v_pols
    return inner_points
Example #5
0
def fan_regular_pols(np_verts,
                     np_pols,
                     np_distances,
                     np_faces_id,
                     custom_normals,
                     index_offset=0,
                     use_custom_normals=False,
                     output_old_v_id=True,
                     output_old_face_id=True,
                     output_pols_groups=True):

    pols_number = np_pols.shape[0]
    pol_sides = np_pols.shape[1]
    v_pols = np_verts[np_pols]  #shape [num_pols, num_corners, 3]

    if (len(np_distances) > 1
            and np.any(np_distances != 0)) or np_distances != 0:
        if use_custom_normals:
            normals = custom_normals
        else:
            normals = np_faces_normals(v_pols)
        average = np.sum(
            v_pols, axis=1
        ) / pol_sides + normals * np_distances[:,
                                               np_newaxis]  #shape [num_pols, 3]
    else:
        average = np.sum(v_pols, axis=1) / pol_sides

    idx_offset = len(np_verts) + index_offset
    new_idx = np_arange(idx_offset, pols_number + idx_offset)
    new_pols = np.zeros([pols_number, pol_sides, 3], dtype=int)
    new_pols[:, :, 0] = np_pols
    new_pols[:, :, 1] = np_roll(np_pols, -1, axis=1)
    new_pols[:, :, 2] = new_idx[:, np_newaxis]

    old_vert_id = np_pols[:, 0].tolist() if output_old_v_id else []

    if output_old_face_id:
        old_face_id = np_repeat(np_faces_id[:, np_newaxis], pol_sides,
                                axis=1).tolist()
    else:
        old_face_id = []

    if output_pols_groups:
        pols_groups = np_repeat(1, len(new_pols) * pol_sides).tolist()
    else:
        pols_groups = []

    return (
        average.tolist(),
        new_pols.reshape(-1, 3).tolist(),
        old_vert_id,
        old_face_id,
        pols_groups,
    )
Example #6
0
def inset_regular_pols(np_verts,
                       np_pols,
                       np_distances,
                       np_inset_rate,
                       np_make_inners,
                       np_faces_id,
                       custom_normals,
                       matrices,
                       offset_mode='CENTER',
                       proportional=False,
                       concave_support=True,
                       index_offset=0,
                       use_custom_normals=False,
                       output_old_face_id=True,
                       output_old_v_id=True,
                       output_pols_groups=True):

    pols_number = np_pols.shape[0]
    pol_sides = np_pols.shape[1]
    v_pols = np_verts[np_pols]  #shape [num_pols, num_corners, 3]
    if offset_mode == 'SIDES':
        inner_points = sides_mode_inset(v_pols, np_inset_rate, np_distances,
                                        concave_support, proportional,
                                        use_custom_normals, custom_normals)
    elif offset_mode == 'MATRIX':
        inner_points = matrix_mode_inset(v_pols, matrices, use_custom_normals,
                                         custom_normals)
    else:
        if any(np_distances != 0):
            if use_custom_normals:
                normals = custom_normals
            else:
                normals = np_faces_normals(v_pols)
            average = np.sum(
                v_pols, axis=1
            ) / pol_sides  #+ normals*np_distances[:, np_newaxis] #shape [num_pols, 3]
            inner_points = average[:, np_newaxis, :] + (
                v_pols - average[:, np_newaxis, :]
            ) * np_inset_rate[:, np_newaxis,
                              np_newaxis] + normals[:,
                                                    np_newaxis, :] * np_distances[:,
                                                                                  np_newaxis,
                                                                                  np_newaxis]
        else:
            average = np.sum(v_pols, axis=1) / pol_sides  #shape [num_pols, 3]
            inner_points = average[:, np_newaxis, :] + (
                v_pols - average[:, np_newaxis, :]
            ) * np_inset_rate[:, np_newaxis, np_newaxis]

    idx_offset = len(np_verts) + index_offset

    new_v_idx = np_arange(idx_offset,
                          pols_number * pol_sides + idx_offset).reshape(
                              pols_number, pol_sides)

    side_pols = np.zeros([pols_number, pol_sides, 4], dtype=int)
    side_pols[:, :, 0] = np_pols
    side_pols[:, :, 1] = np_roll(np_pols, -1, axis=1)
    side_pols[:, :, 2] = np_roll(new_v_idx, -1, axis=1)
    side_pols[:, :, 3] = new_v_idx

    side_faces = side_pols.reshape(-1, 4)

    new_insets = new_v_idx[np_make_inners]

    if pol_sides == 4:
        new_faces = np_concatenate([side_faces, new_insets]).tolist()
    else:
        new_faces = side_faces.tolist() + new_insets.tolist()

    old_v_id = np_pols.flatten().tolist() if output_old_v_id else []
    if output_old_face_id:
        side_ids = np.repeat(np_faces_id[:, np_newaxis], pol_sides, axis=1)
        inset_ids = np_faces_id[np_make_inners]
        old_face_id = np.concatenate((side_ids.flatten(), inset_ids)).tolist()
    else:
        old_face_id = []

    if output_pols_groups:
        pols_groups = np_repeat(
            [1, 2], [len(side_faces), len(new_insets)]).tolist()
    else:
        pols_groups = []

    return (inner_points.reshape(-1, 3).tolist(), new_faces,
            new_insets.tolist(), old_v_id, old_face_id, pols_groups)