Refactor: GEO: Mesh selection header file
Share code of geometry processing of mesh selection. For now, `mesh_copy_selection` is only user of this code, but in #115142 this will also be used. Pull Request: https://projects.blender.org/blender/blender/pulls/115376
This commit is contained in:
parent
42ddc13033
commit
361174b588
|
@ -26,6 +26,7 @@ set(SRC
|
|||
intern/mesh_primitive_grid.cc
|
||||
intern/mesh_primitive_line.cc
|
||||
intern/mesh_primitive_uv_sphere.cc
|
||||
intern/mesh_selection.cc
|
||||
intern/mesh_split_edges.cc
|
||||
intern/mesh_to_curve_convert.cc
|
||||
intern/mesh_to_volume.cc
|
||||
|
@ -52,6 +53,7 @@ set(SRC
|
|||
GEO_mesh_primitive_grid.hh
|
||||
GEO_mesh_primitive_line.hh
|
||||
GEO_mesh_primitive_uv_sphere.hh
|
||||
GEO_mesh_selection.hh
|
||||
GEO_mesh_split_edges.hh
|
||||
GEO_mesh_to_curve.hh
|
||||
GEO_mesh_to_volume.hh
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_index_mask.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_offset_indices.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
namespace blender::geometry {
|
||||
|
||||
/** A vertex is selected if it's used by a selected edge. */
|
||||
IndexMask vert_selection_from_edge(Span<int2> edges,
|
||||
const IndexMask &edge_mask,
|
||||
int verts_num,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
/** A vertex is selected if it is used by a selected face. */
|
||||
IndexMask vert_selection_from_face(OffsetIndices<int> faces,
|
||||
const IndexMask &face_mask,
|
||||
Span<int> corner_verts,
|
||||
int verts_num,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
/** An edge is selected if it is used by a selected face. */
|
||||
IndexMask edge_selection_from_face(OffsetIndices<int> faces,
|
||||
const IndexMask &face_mask,
|
||||
Span<int> corner_edges,
|
||||
int edges_num,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
/** An edge is selected if both of its vertices are selected. */
|
||||
IndexMask edge_selection_from_vert(Span<int2> edges,
|
||||
Span<bool> vert_selection,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
/** A face is selected if all of its vertices are selected. */
|
||||
IndexMask face_selection_from_vert(OffsetIndices<int> faces,
|
||||
Span<int> corner_verts,
|
||||
Span<bool> vert_selection,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
/** A face is selected if all of its edges are selected. */
|
||||
IndexMask face_selection_from_edge(OffsetIndices<int> faces,
|
||||
Span<int> corner_edges,
|
||||
Span<bool> edge_mask,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
} // namespace blender::geometry
|
|
@ -13,6 +13,7 @@
|
|||
#include "BKE_mesh.hh"
|
||||
|
||||
#include "GEO_mesh_copy_selection.hh"
|
||||
#include "GEO_mesh_selection.hh"
|
||||
|
||||
namespace blender::geometry {
|
||||
|
||||
|
@ -76,97 +77,6 @@ static void remap_edges(const OffsetIndices<int> src_faces,
|
|||
});
|
||||
}
|
||||
|
||||
/** A vertex is selected if it's used by a selected edge. */
|
||||
static IndexMask vert_selection_from_edge(const Span<int2> edges,
|
||||
const IndexMask &edge_mask,
|
||||
const int verts_num,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
Array<bool> array(verts_num, false);
|
||||
edge_mask.foreach_index_optimized<int>(GrainSize(4096), [&](const int i) {
|
||||
array[edges[i][0]] = true;
|
||||
array[edges[i][1]] = true;
|
||||
});
|
||||
return IndexMask::from_bools(array, memory);
|
||||
}
|
||||
|
||||
static IndexMask mapped_corner_selection_from_face(const OffsetIndices<int> faces,
|
||||
const IndexMask &face_mask,
|
||||
const Span<int> corner_verts_or_edges,
|
||||
const int verts_or_edges_num,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
Array<bool> array(verts_or_edges_num, false);
|
||||
face_mask.foreach_index(GrainSize(512), [&](const int64_t i) {
|
||||
array.as_mutable_span().fill_indices(corner_verts_or_edges.slice(faces[i]), true);
|
||||
});
|
||||
return IndexMask::from_bools(array, memory);
|
||||
}
|
||||
|
||||
/** A vertex is selected if it is used by a selected face. */
|
||||
static IndexMask vert_selection_from_face(const OffsetIndices<int> faces,
|
||||
const IndexMask &face_mask,
|
||||
const Span<int> corner_verts,
|
||||
const int verts_num,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return mapped_corner_selection_from_face(faces, face_mask, corner_verts, verts_num, memory);
|
||||
}
|
||||
|
||||
/** An edge is selected if it is used by a selected face. */
|
||||
static IndexMask edge_selection_from_face(const OffsetIndices<int> faces,
|
||||
const IndexMask &face_mask,
|
||||
const Span<int> corner_edges,
|
||||
const int edges_num,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return mapped_corner_selection_from_face(faces, face_mask, corner_edges, edges_num, memory);
|
||||
}
|
||||
|
||||
/** An edge is selected if both of its vertices are selected. */
|
||||
static IndexMask edge_selection_from_vert(const Span<int2> edges,
|
||||
const Span<bool> vert_selection,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return IndexMask::from_predicate(
|
||||
edges.index_range(), GrainSize(1024), memory, [&](const int64_t i) {
|
||||
const int2 edge = edges[i];
|
||||
return vert_selection[edge[0]] && vert_selection[edge[1]];
|
||||
});
|
||||
}
|
||||
|
||||
static IndexMask face_selection_from_mapped_corner(const OffsetIndices<int> faces,
|
||||
const Span<int> corner_verts_or_edges,
|
||||
const Span<bool> vert_or_edge_selection,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return IndexMask::from_predicate(
|
||||
faces.index_range(), GrainSize(1024), memory, [&](const int64_t i) {
|
||||
const Span<int> indices = corner_verts_or_edges.slice(faces[i]);
|
||||
return std::all_of(indices.begin(), indices.end(), [&](const int i) {
|
||||
return vert_or_edge_selection[i];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** A face is selected if all of its vertices are selected. */
|
||||
static IndexMask face_selection_from_vert(const OffsetIndices<int> faces,
|
||||
const Span<int> corner_verts,
|
||||
const Span<bool> vert_selection,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return face_selection_from_mapped_corner(faces, corner_verts, vert_selection, memory);
|
||||
}
|
||||
|
||||
/** A face is selected if all of its edges are selected. */
|
||||
static IndexMask face_selection_from_edge(const OffsetIndices<int> faces,
|
||||
const Span<int> corner_edges,
|
||||
const Span<bool> edge_mask,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return face_selection_from_mapped_corner(faces, corner_edges, edge_mask, memory);
|
||||
}
|
||||
|
||||
/** Create a mesh with no built-in attributes. */
|
||||
static Mesh *create_mesh_no_attributes(const Mesh ¶ms_mesh,
|
||||
const int verts_num,
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_index_mask.hh"
|
||||
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
namespace blender::geometry {
|
||||
|
||||
IndexMask vert_selection_from_edge(const Span<int2> edges,
|
||||
const IndexMask &edge_mask,
|
||||
const int verts_num,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
Array<bool> array(verts_num, false);
|
||||
edge_mask.foreach_index_optimized<int>(GrainSize(4096), [&](const int i) {
|
||||
array[edges[i][0]] = true;
|
||||
array[edges[i][1]] = true;
|
||||
});
|
||||
return IndexMask::from_bools(array, memory);
|
||||
}
|
||||
|
||||
static IndexMask mapped_corner_selection_from_face(const OffsetIndices<int> faces,
|
||||
const IndexMask &face_mask,
|
||||
const Span<int> corner_verts_or_edges,
|
||||
const int verts_or_edges_num,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
Array<bool> array(verts_or_edges_num, false);
|
||||
face_mask.foreach_index(GrainSize(512), [&](const int64_t i) {
|
||||
array.as_mutable_span().fill_indices(corner_verts_or_edges.slice(faces[i]), true);
|
||||
});
|
||||
return IndexMask::from_bools(array, memory);
|
||||
}
|
||||
|
||||
IndexMask vert_selection_from_face(const OffsetIndices<int> faces,
|
||||
const IndexMask &face_mask,
|
||||
const Span<int> corner_verts,
|
||||
const int verts_num,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return mapped_corner_selection_from_face(faces, face_mask, corner_verts, verts_num, memory);
|
||||
}
|
||||
|
||||
IndexMask edge_selection_from_face(const OffsetIndices<int> faces,
|
||||
const IndexMask &face_mask,
|
||||
const Span<int> corner_edges,
|
||||
const int edges_num,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return mapped_corner_selection_from_face(faces, face_mask, corner_edges, edges_num, memory);
|
||||
}
|
||||
|
||||
IndexMask edge_selection_from_vert(const Span<int2> edges,
|
||||
const Span<bool> vert_selection,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return IndexMask::from_predicate(
|
||||
edges.index_range(), GrainSize(1024), memory, [&](const int64_t i) {
|
||||
const int2 edge = edges[i];
|
||||
return vert_selection[edge[0]] && vert_selection[edge[1]];
|
||||
});
|
||||
}
|
||||
|
||||
static IndexMask face_selection_from_mapped_corner(const OffsetIndices<int> faces,
|
||||
const Span<int> corner_verts_or_edges,
|
||||
const Span<bool> vert_or_edge_selection,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return IndexMask::from_predicate(
|
||||
faces.index_range(), GrainSize(1024), memory, [&](const int64_t i) {
|
||||
const Span<int> indices = corner_verts_or_edges.slice(faces[i]);
|
||||
return std::all_of(indices.begin(), indices.end(), [&](const int i) {
|
||||
return vert_or_edge_selection[i];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
IndexMask face_selection_from_vert(const OffsetIndices<int> faces,
|
||||
const Span<int> corner_verts,
|
||||
const Span<bool> vert_selection,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return face_selection_from_mapped_corner(faces, corner_verts, vert_selection, memory);
|
||||
}
|
||||
|
||||
IndexMask face_selection_from_edge(const OffsetIndices<int> faces,
|
||||
const Span<int> corner_edges,
|
||||
const Span<bool> edge_mask,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return face_selection_from_mapped_corner(faces, corner_edges, edge_mask, memory);
|
||||
}
|
||||
|
||||
} // namespace blender::geometry
|
Loading…
Reference in New Issue