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
def by_side(verts, direction, percent): np_verts = np.array(verts) np_dir = np.array(direction) np_dir, np_percent = numpy_match_long_repeat([np_dir, np.array(percent)]) values = np_dot(np_verts[:, np.newaxis], np_dir[np.newaxis, :], axis=2) threshold = map_percent(values, np_percent) out_verts_mask = np.any(values >= threshold, axis=1) return out_verts_mask
def by_normal(vertices, edges, faces, percent, direction): face_normals = pols_normals(vertices, faces, output_numpy=True) np_dir, np_percent = numpy_match_long_repeat( [np.array(direction), np.array(percent)]) values = np_dot(face_normals[:, np.newaxis], np_dir[np.newaxis, :], axis=2) threshold = map_percent(values, np_percent) out_face_mask = np.any(values >= threshold, axis=1) return out_face_mask
def by_normal(vertices, edges, faces, percent, direction): face_normals, _ = calc_mesh_normals(vertices, edges, faces) np_verts = np.array(face_normals) np_dir = np.array(direction) np_dir, np_percent = numpy_match_long_repeat([np_dir, np.array(percent)]) values = np_dot(np_verts[:, np.newaxis], np_dir[np.newaxis, :], axis=2) threshold = map_percent(values, np_percent) out_face_mask = np.any(values >= threshold, axis=1) return out_face_mask
def evaluate_grid(self, xs, ys, zs): direction = self.direction direction2 = np.dot(direction, direction) points = np.stack((xs, ys, zs)).T to_center = self.center[np.newaxis, :] - points projection = direction[np.newaxis, :] * (np_dot(to_center, direction[np.newaxis,:]) / direction2)[:, np.newaxis] vectors = np.cross(to_center - projection, direction) if self.falloff is not None: norms = np.linalg.norm(vectors, axis=1, keepdims=True) nonzero = (norms > 0)[:,0] lens = self.falloff(norms) vectors[nonzero] = vectors[nonzero] / norms[nonzero][:, 0][np.newaxis].T R = (lens * vectors).T return R[0], R[1], R[2] else: R = vectors.T return R[0], R[1], R[2]
def by_edge_dir(vertices, edges, percent, direction): np_verts = np.array(vertices) np_edges = np.array(edges) edges_v = np_verts[np_edges] edges_dir = edges_v[:, 1, :] - edges_v[:, 0, :] np_dir = np.array(direction) np_dir /= np.linalg.norm(np_dir, axis=1)[:, np.newaxis] edges_dir /= np.linalg.norm(edges_dir, axis=1)[:, np.newaxis] np_percent = np.array(percent) np_dir, np_percent = numpy_match_long_repeat([np_dir, np_percent]) values = np.abs( np_dot(edges_dir[:, np.newaxis], np_dir[np.newaxis, :], axis=2)) threshold = map_percent(values, np_percent) out_edges_mask = np.any(values >= threshold, axis=1) return out_edges_mask
def by_cylinder(vertices, center, radius, direction): np_vertices = np.array(vertices) np_location = np.array(center) np_direction = np.array(direction) np_direction = np_direction / np.linalg.norm(np_direction, axis=1)[:, np.newaxis] np_radius = np.array(radius) np_location, np_direction, np_radius = numpy_match_long_repeat( [np_location, np_direction, np_radius]) v_attract = np_vertices[np.newaxis, :, :] - np_location[:, np.newaxis, :] vect_proy = np_dot(v_attract, np_direction[:, np.newaxis, :], axis=2) closest_point = np_location[:, np. newaxis, :] + vect_proy[:, :, np. newaxis] * np_direction[:, np . newaxis, :] dif_v = closest_point - np_vertices[np.newaxis, :, :] dist_attract = np.linalg.norm(dif_v, axis=2) out_verts_mask = np.any(dist_attract < np_radius[:, np.newaxis], axis=0) return out_verts_mask
def vert_light_factor(vecs, polygons, light): return (np_dot(np_vertex_normals(vecs, polygons, output_numpy=True), light)*0.5+0.5).tolist()
def face_light_factor(vecs, polygons, light): return (np_dot(pols_normals(vecs, polygons, output_numpy=True), light)*0.5+0.5).tolist()