def create_spline(self, curve_object, control_points, radiuses=None, tilts=None):
        curve_object.data.splines.clear()

        spline = curve_object.data.splines.new(type='BEZIER')
        spline.bezier_points.add(len(control_points))

        first_point = start_point = spline.bezier_points[0]
        for idx, segment in enumerate(control_points):
            end_point = spline.bezier_points[idx+1]

            start_point.co = Vector(segment[0])
            start_point.handle_right = Vector(segment[1])

            end_point.handle_left = Vector(segment[2])
            end_point.co = Vector(segment[3])

            start_point = end_point

        first_point.handle_left = first_point.co
        end_point.handle_right = end_point.co

        if radiuses is not None:
            spline.bezier_points.foreach_set('radius', numpy_full_list(radiuses, len(spline.bezier_points)))
        if tilts is not None:
            spline.bezier_points.foreach_set('tilt', numpy_full_list(tilts, len(spline.bezier_points)))

        spline.use_smooth = self.use_smooth

        return spline
示例#2
0
    def unit_generator(self, idx, geometry):
        verts, _, _, radiix, radiiy = geometry
        ntimes = len(verts)

        radiix = numpy_full_list(radiix, ntimes)
        radiiy = numpy_full_list(radiiy, ntimes)
        radiuses = [radiix, radiiy]

        obj, data_layers = make_bmesh_geometry(self, bpy.context, geometry,
                                               idx, radiuses)

        if data_layers and self.distance_doubles > 0.0:
            # This sets the modified geometry with radius x and radius y.
            f_r = list(itertools.chain(*zip(data_layers[0], data_layers[1])))
            f_r = [abs(f) for f in f_r]
            obj.data.skin_vertices[0].data.foreach_set('radius', f_r)
            all_yes = list(itertools.repeat(True, len(obj.data.vertices)))
            obj.data.skin_vertices[0].data.foreach_set('use_root', all_yes)

        elif len(radiix) == len(verts):
            f_r = list(itertools.chain(*zip(radiix, radiiy)))
            f_r = [abs(f) for f in f_r]
            obj.data.skin_vertices[0].data.foreach_set('radius', f_r)

        if self.use_root:
            # set all to root
            all_yes = list(itertools.repeat(True, ntimes))
            obj.data.skin_vertices[0].data.foreach_set('use_root', all_yes)
        elif self.use_slow_root:
            process_mesh_into_features(obj.data.skin_vertices[0].data,
                                       obj.data.edge_keys)
示例#3
0
def live_curve(obj_index, node, verts, radii, twist):

    obj, cu = node.get_obj_curve(obj_index)

    obj.show_wire = node.show_wire
    cu.bevel_depth = node.depth
    cu.bevel_resolution = node.resolution
    cu.dimensions = node.curve_dimensions
    cu.resolution_u = node.preview_resolution_u

    if cu.dimensions == '2D':
        cu.fill_mode = 'FRONT'
    else:
        cu.fill_mode = 'FULL'

    set_bevel_object(node, cu, obj_index)

    kind = ["POLY", "NURBS"][bool(node.bspline)]

    if node.selected_mode == 'Multi':
        verts = [verts]
        radii = [radii]
        twist = [twist]

    for idx, (VERTS, RADII, TWIST) in enumerate(zip(verts, radii, twist)):

        full_flat = []
        for v in VERTS:
            full_flat.extend([v[0], v[1], v[2], 1.0])

        polyline = cu.splines.new(kind)
        polyline.points.add(len(VERTS) - 1)
        polyline.points.foreach_set('co', full_flat)

        if len(RADII) > 0:
            rad = numpy_full_list(RADII, len(VERTS))
            polyline.points.foreach_set('radius', rad)

        if len(TWIST) > 0:
            twist = numpy_full_list(TWIST, len(VERTS))
            polyline.points.foreach_set('tilt', twist)

        if node.close:
            cu.splines[idx].use_cyclic_u = True

        if node.bspline:
            polyline.order_u = len(polyline.points) - 1

        polyline.use_smooth = node.use_smooth

    return obj
 def calc_full_mask(mask, index, filter_method, invert, length):
     if filter_method == 'INDEX':
         if invert:
             full_mask = np.zeros(length, dtype='bool')
             full_mask[np.array(index)] = True
         else:
             full_mask = np.ones(length, dtype='bool')
             full_mask[np.array(index)] = False
     else:
         if invert:
             full_mask = numpy_full_list(
                 np.array(mask).astype(bool), length)
         else:
             full_mask = numpy_full_list(
                 np.invert(np.array(mask).astype(bool)), length)
     return full_mask
示例#5
0
def get_weights(edges_dir, input_weights, proportional):
    if proportional:
        edge_length = np.linalg.norm(edges_dir, axis=1)
        if len(input_weights) > 0:
            edges_weights = numpy_full_list(input_weights,
                                            len(edges_dir)) * edge_length
            weights = edges_weights / np.sum(edges_weights)
        else:
            weights = edge_length / np.sum(edge_length)

    else:
        if len(input_weights) > 0:
            edges_weights = numpy_full_list(input_weights, len(edges_dir))
            weights = edges_weights / np.sum(edges_weights)
        else:
            weights = None

    return weights
示例#6
0
def set_loops(loop_count, obj, index_socket, indices, input_colors, colors):
    if index_socket.is_linked:
        for idx, color in zip(indices, input_colors):
            colors[idx] = color
    else:
        if len(input_colors) < loop_count:
            colors[:] = numpy_full_list(input_colors, loop_count)
        elif len(input_colors) >= loop_count:
            colors[:] = input_colors[:loop_count]
示例#7
0
def get_selected_edges(use_mask, masks, bm_edges):
    if use_mask:
        if isinstance(masks, ndarray):
            mask_matched = numpy_full_list(masks, len(bm_edges)).tolist()
        else:
            mask_matched = repeat_last_for_length(masks, len(bm_edges))
        edge_id = bm_edges.layers.int.get("initial_index")
        return [edge for edge in bm_edges if mask_matched[edge[edge_id]]]

    return bm_edges
示例#8
0
    def _regenerate_spline(spline: bpy.types.Spline,
                           vertices: np.ndarray,
                           spline_type: str = 'POLY',
                           vertices_radius: np.ndarray = None,
                           tilt: np.ndarray = None,
                           close_spline: bool = False,
                           use_smooth: bool = True):
        spline.type = spline_type
        spline.use_cyclic_u = close_spline
        spline.use_smooth = use_smooth

        # flatten vertices array and add W component (X, Y, Z, W), W is responsible for drawing NURBS curves
        w_vertices = np.concatenate((vertices, np.ones((len(vertices), 1), dtype=np.float32)), axis=1)
        flatten_vertices = np.ravel(w_vertices)
        spline.points.foreach_set('co', flatten_vertices)
        if vertices_radius is not None:
            spline.points.foreach_set('radius', numpy_full_list(vertices_radius, len(vertices)))
        if tilt is not None:
            spline.points.foreach_set('tilt', numpy_full_list(tilt, len(vertices)))
示例#9
0
def subdiv_mesh_to_quads_np(vertices, polygons,
                            iterations, normal_displace,
                            random_f, random_normal, random_seed,
                            smooth_f,
                            vert_data, face_data,
                            output_edges=True,
                            output_vert_map=True):
    np.random.seed(int(random_seed))
    np_verts = vertices if isinstance(vertices, np.ndarray) else np.array(vertices)
    if output_vert_map:
        vert_map = np.zeros(np_verts.shape[0], dtype=int)
    else:
        vert_map = np.array([], dtype=int)

    matched_vert_data = dict()
    if vert_data:
        for key in vert_data:
            matched_vert_data[key] = numpy_full_list(vert_data[key], np_verts.shape[0])

    matched_face_data = dict()
    if face_data:
        for key in face_data:
            data = face_data[key]
            if isinstance(data, np.ndarray):
                matched_face_data[key] = numpy_full_list(data, len(polygons))
            else:
                matched_face_data[key] = repeat_last_for_length(data, len(polygons))


    flat_pols, pol_len, pol_end = np_pols(polygons)
    edges, unique_edges, eds_inverse_idx = pols_to_edges(flat_pols, pol_len, pol_end)
    return subdiv_mesh_to_quads_inner(
        np_verts, polygons,
        pol_len, pol_end,
        edges, unique_edges, eds_inverse_idx,
        iterations, normal_displace,
        random_f, random_normal,
        smooth_f,
        vert_map, matched_vert_data, matched_face_data,
        output_edges=output_edges,
        max_iterations=iterations)
示例#10
0
def set_vertices(loop_count, obj, index_socket, indices, input_colors, colors):
    vertex_index = np.zeros(loop_count, dtype=int)
    loops = obj.data.loops
    loops.foreach_get("vertex_index", vertex_index)
    if index_socket.is_linked:
        idx_lookup = collections.defaultdict(list)
        for idx, v_idx in enumerate(vertex_index):
            idx_lookup[v_idx].append(idx)
        for idx, col in zip(indices, input_colors):
            colors[idx_lookup[idx]] = col
    else:
        if len(obj.data.vertices) > len(input_colors):
            colors[:] = numpy_full_list(input_colors,
                                        len(obj.data.vertices))[vertex_index]
        else:
            if isinstance(input_colors, np.ndarray):
                colors[:] = input_colors[vertex_index]
            else:
                colors[:] = np.array(input_colors)[vertex_index]
示例#11
0
    def process(self):
        inputs, outputs = self.inputs, self.outputs

        if self.dont_process():
            return

        result_vertices, result_edges, result_faces, result_face_data = [], [], [], []
        r_inner_vertices, r_inner_edges, r_inner_faces = [], [], []
        r_split_vertices, r_split_edges, r_split_faces = [], [], []

        use_mask = inputs['EdgeMask'].is_linked
        show_new = self.show_new and any(s.is_linked for s in outputs[4:7])
        show_old = self.show_old and any(s.is_linked for s in outputs[7:])
        use_face_data = inputs['FaceData'].is_linked and outputs['FaceData'].is_linked
        output_numpy = any(self.out_np)

        meshes = self.get_data()

        for vertices, edges, faces, face_data, masks, cuts, smooth, fractal, along_normal, seed in zip(*meshes):
            if cuts < 1:
                result_vertices.append(vertices)
                result_edges.append(edges)
                result_faces.append(faces)
                result_face_data.append(face_data)
                r_inner_vertices.append(vertices)
                r_inner_edges.append(edges)
                r_inner_faces.append(faces)
                r_split_vertices.append(vertices)
                r_split_edges.append(edges)
                r_split_faces.append(faces)
                continue

            if use_face_data and len(face_data) > 0:
                if isinstance(face_data, ndarray):
                    face_data_matched = numpy_full_list(face_data, len(faces)).tolist()
                else:
                    face_data_matched = repeat_last_for_length(face_data, len(faces))
            else:
                face_data_matched =[]

            bm = bmesh_from_pydata(
                vertices, edges, faces,
                markup_face_data=use_face_data,
                markup_edge_data=use_mask,
                normal_update=True)

            selected_edges = get_selected_edges(use_mask, masks, bm.edges)

            geom = subdivide_edges(
                bm,
                edges=selected_edges,
                smooth=smooth,
                smooth_falloff=self.falloff_type,
                fractal=fractal,
                along_normal=along_normal,
                cuts=cuts,
                seed=seed,
                quad_corner_type=self.corner_type,
                use_grid_fill=self.grid_fill,
                use_single_edge=self.single_edge,
                use_only_quads=self.only_quads,
                use_smooth_even=self.smooth_even)

            if output_numpy:
                new_verts, new_edges, new_faces, new_face_data = numpy_data_from_bmesh(bm, self.out_np, face_data_matched)
            else:
                if use_face_data and len(face_data) > 0:
                    new_verts, new_edges, new_faces, new_face_data = pydata_from_bmesh(bm, face_data_matched)
                else:
                    new_verts, new_edges, new_faces = pydata_from_bmesh(bm)
                    new_face_data = []

            result_vertices.append(new_verts)
            result_edges.append(new_edges)
            result_faces.append(new_faces)
            result_face_data.append(new_face_data)

            if show_new:
                inner_verts, inner_edges, inner_faces = get_partial_result_pydata(geom['geom_inner'])
                r_inner_vertices.append(inner_verts)
                r_inner_edges.append(inner_edges)
                r_inner_faces.append(inner_faces)

            if show_old:
                split_verts, split_edges, split_faces = get_partial_result_pydata(geom['geom_split'])
                r_split_vertices.append(split_verts)
                r_split_edges.append(split_edges)
                r_split_faces.append(split_faces)

            bm.free()


        outputs['Vertices'].sv_set(result_vertices)
        outputs['Edges'].sv_set(result_edges)
        outputs['Faces'].sv_set(result_faces)
        outputs['FaceData'].sv_set(result_face_data)

        outputs['NewVertices'].sv_set(r_inner_vertices)
        outputs['NewEdges'].sv_set(r_inner_edges)
        outputs['NewFaces'].sv_set(r_inner_faces)

        outputs['OldVertices'].sv_set(r_split_vertices)
        outputs['OldEdges'].sv_set(r_split_edges)
        outputs['OldFaces'].sv_set(r_split_faces)
示例#12
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)
示例#13
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))
                )