24 const int src_verts_num,
36 vert_mask.
size() > 1024,
38 face_mask.foreach_index(GrainSize(512), [&](const int64_t src_i, const int64_t dst_i) {
39 const IndexRange src_face = src_faces[src_i];
40 const IndexRange dst_face = dst_faces[dst_i];
41 for (const int i : src_face.index_range()) {
42 dst_corner_verts[dst_face[i]] = map[src_corner_verts[src_face[i]]];
48 dst_edges[dst_i][0] = map[src_edges[src_i][0]];
49 dst_edges[dst_i][1] = map[src_edges[src_i][1]];
56 const int src_edges_num,
68 dst_corner_edges[dst_face[i]] = map[src_corner_edges[src_face[i]]];
75 const auto &src_cache = src.
runtime->loose_verts_cache;
76 if (src_cache.is_cached() && src_cache.data().count == 0) {
77 dst.tag_loose_verts_none();
83 const auto &src_cache = src.
runtime->loose_edges_cache;
84 if (src_cache.is_cached() && src_cache.data().count == 0) {
85 dst.tag_loose_edges_none();
91 if (src.no_overlapping_topology()) {
92 dst.tag_overlapping_none();
104 vertex_group_names.
add(group->name);
118 mesh_dst.attributes_for_write());
126 const Span<int2> src_edges = src_mesh.edges();
128 const Span<int> src_corner_verts = src_mesh.corner_verts();
129 const Span<int> src_corner_edges = src_mesh.corner_edges();
135 if (
const std::optional<bool> single =
selection.get_if_single()) {
136 return *single ? std::nullopt : std::make_optional<Mesh *>(
nullptr);
143 switch (selection_domain) {
148 [&]() { vert_mask = IndexMask::from_bools(span, memory.local()); },
149 [&]() { edge_mask = edge_selection_from_vert(src_edges, span, memory.local()); },
151 face_mask = face_selection_from_vert(
152 src_faces, src_corner_verts, span, memory.local());
159 src_edges.
size() > 1024,
161 edge_mask = IndexMask::from_bools(span, memory.local());
162 vert_mask = vert_selection_from_edge(
163 src_edges, edge_mask, src_mesh.verts_num, memory.local());
166 face_mask = face_selection_from_edge(
167 src_faces, src_corner_edges, span, memory.local());
175 face_mask.
size() > 1024,
177 vert_mask = vert_selection_from_face(
178 src_faces, face_mask, src_corner_verts, src_mesh.verts_num, memory.local());
181 edge_mask = edge_selection_from_face(
182 src_faces, face_mask, src_corner_edges, src_mesh.edges_num, memory.local());
194 const bool same_verts = vert_mask.
size() == src_mesh.
verts_num;
195 const bool same_edges = edge_mask.
size() == src_mesh.
edges_num;
196 const bool same_faces = face_mask.
size() == src_mesh.
faces_num;
197 if (same_verts && same_edges && same_faces) {
202 vert_mask.
size(), edge_mask.
size(), face_mask.
size(), 0);
209 src_faces, face_mask, dst_mesh->face_offsets_for_write());
217 vert_mask.
size() > 1024,
219 remap_verts(src_faces,
231 remap_edges(src_faces,
240 gather_vert_attributes(src_mesh, attribute_filter, vert_mask, *dst_mesh);
241 bke::gather_attributes(
243 bke::AttrDomain::Edge,
244 bke::AttrDomain::Edge,
245 bke::attribute_filter_with_skip_ref(attribute_filter, {
".edge_verts"}),
259 {
".corner_edge",
".corner_vert"}),
269 else if (selection_domain == bke::AttrDomain::Face) {
283 const Span<int2> src_edges = src_mesh.edges();
285 const Span<int> src_corner_verts = src_mesh.corner_verts();
286 const Span<int> src_corner_edges = src_mesh.corner_edges();
296 switch (selection_domain) {
300 src_edges.
size() > 1024,
301 [&]() { edge_mask = edge_selection_from_vert(src_edges, span, memory.local()); },
303 face_mask = face_selection_from_vert(
304 src_faces, src_corner_verts, span, memory.local());
311 src_edges.
size() > 1024,
312 [&]() { edge_mask = IndexMask::from_bools(span, memory.local()); },
314 face_mask = face_selection_from_edge(
315 src_faces, src_corner_edges, span, memory.local());
323 src_faces, face_mask, src_corner_edges, src_edges.
size(), memory.
local());
331 const bool same_edges = edge_mask.
size() == src_mesh.
edges_num;
332 const bool same_faces = face_mask.
size() == src_mesh.
faces_num;
333 if (same_edges && same_faces) {
343 src_faces, face_mask, dst_mesh->face_offsets_for_write());
411 switch (selection_domain) {
428 const bool same_faces = face_mask.
size() == src_mesh.
faces_num;
439 src_faces, face_mask, dst_mesh->face_offsets_for_write());
CustomData interface, see also DNA_customdata_types.h.
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
Object is a sort of wrapper for general info.
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr IndexRange index_range() const
constexpr int64_t size() const
constexpr bool is_empty() const
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
void foreach_index(Fn &&fn) const
static void copy_loose_edge_hint(const Mesh &src, Mesh &dst)
static void copy_overlapping_hint(const Mesh &src, Mesh &dst)
static void copy_loose_vert_hint(const Mesh &src, Mesh &dst)
void copy_attributes(const AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, MutableAttributeAccessor dst_attributes)
void gather_attributes(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
auto attribute_filter_with_skip_ref(AttributeFilter filter, const Span< StringRef > skip)
Mesh * mesh_new_no_attributes(int verts_num, int edges_num, int faces_num, int corners_num)
void gather_deform_verts(Span< MDeformVert > src, Span< int > indices, MutableSpan< MDeformVert > dst)
void gather_attributes_group_to_group(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
static void gather_vert_attributes(const Mesh &mesh_src, const bke::AttributeFilter &attribute_filter, const IndexMask &vert_mask, Mesh &mesh_dst)
IndexMask edge_selection_from_face(OffsetIndices< int > faces, const IndexMask &face_mask, Span< int > corner_edges, int edges_num, IndexMaskMemory &memory)
std::optional< Mesh * > mesh_copy_selection_keep_edges(const Mesh &mesh, const VArray< bool > &selection, bke::AttrDomain selection_domain, const bke::AttributeFilter &attribute_filter={})
static void remap_verts(const OffsetIndices< int > src_faces, const OffsetIndices< int > dst_faces, const int src_verts_num, const IndexMask &vert_mask, const IndexMask &edge_mask, const IndexMask &face_mask, const Span< int2 > src_edges, const Span< int > src_corner_verts, MutableSpan< int2 > dst_edges, MutableSpan< int > dst_corner_verts)
static void remap_edges(const OffsetIndices< int > src_faces, const OffsetIndices< int > dst_faces, const int src_edges_num, const IndexMask &edge_mask, const IndexMask &face_mask, const Span< int > src_corner_edges, MutableSpan< int > dst_corner_edges)
std::optional< Mesh * > mesh_copy_selection_keep_verts(const Mesh &src_mesh, const VArray< bool > &selection, bke::AttrDomain selection_domain, const bke::AttributeFilter &attribute_filter={})
IndexMask face_selection_from_edge(OffsetIndices< int > faces, Span< int > corner_edges, Span< bool > edge_mask, IndexMaskMemory &memory)
IndexMask face_selection_from_vert(OffsetIndices< int > faces, Span< int > corner_verts, Span< bool > vert_selection, IndexMaskMemory &memory)
std::optional< Mesh * > mesh_copy_selection(const Mesh &src_mesh, const VArray< bool > &selection, bke::AttrDomain selection_domain, const bke::AttributeFilter &attribute_filter={})
void build_reverse_map(const IndexMask &mask, MutableSpan< T > r_map)
template void build_reverse_map< int >(const IndexMask &mask, MutableSpan< int > r_map)
OffsetIndices< int > gather_selected_offsets(OffsetIndices< int > src_offsets, const IndexMask &selection, int start_offset, MutableSpan< int > dst_offsets)
void parallel_invoke(Functions &&...functions)
VecBase< int32_t, 2 > int2
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
MeshRuntimeHandle * runtime
ListBase vertex_group_names