23#ifndef VCL_ALGORITHMS_MESH_FILTER_H
24#define VCL_ALGORITHMS_MESH_FILTER_H
26#include <vclib/mesh.h>
34template<MeshConcept OutMeshType, u
int ELEM_ID, MeshConcept InMeshType>
35OutMeshType perElementMeshFilter(
37 Range
auto&& elemFilterRng,
38 bool saveBirthIndicesInCustomComponent =
true)
40 using OutElemType = OutMeshType::template ElementType<ELEM_ID>;
42 std::string ccname =
"birth" + elementEnumString<ELEM_ID>();
45 res.enableSameOptionalComponentsOf(m);
48 if constexpr (comp::HasCustomComponents<OutElemType>) {
49 if (saveBirthIndicesInCustomComponent) {
50 res.template addPerElementCustomComponent<ELEM_ID, uint>(ccname);
54 for (
const auto& [birthV, filter] :
55 std::views::zip(m.template elements<ELEM_ID>(), elemFilterRng)) {
57 uint v = res.template add<ELEM_ID>();
59 res.template element<ELEM_ID>(v).importFrom(birthV,
false);
61 if constexpr (comp::HasCustomComponents<OutElemType>) {
62 if (saveBirthIndicesInCustomComponent) {
63 res.template element<ELEM_ID>(v)
64 .template customComponent<uint>(ccname) =
74template<MeshConcept OutMeshType, u
int ELEM_ID, MeshConcept InMeshType>
75OutMeshType perElementMeshFilter(
77 const std::function<
bool(
78 const typename InMeshType::template ElementType<ELEM_ID>&)>& elemFilter,
79 bool saveBirthIndicesInCustomComponent =
true)
82 m.template elements<ELEM_ID>() | std::views::transform(elemFilter);
84 return perElementMeshFilter<OutMeshType, ELEM_ID, InMeshType>(
85 m, view, saveBirthIndicesInCustomComponent);
88template<MeshConcept OutMeshType, u
int ELEM_ID, MeshConcept InMeshType>
89OutMeshType perElementMeshFilterWithVRefs(
91 Range
auto&& elemFilterRng,
92 bool saveBirthIndicesInCustomComponent =
true)
94 using InVertexType = InMeshType::VertexType;
95 using OutElemType = OutMeshType::template ElementType<ELEM_ID>;
97 std::string ccname =
"birth" + elementEnumString<ELEM_ID>();
100 res.enableSameOptionalComponentsOf(m);
103 if constexpr (HasPerVertexCustomComponents<OutMeshType>) {
104 if (saveBirthIndicesInCustomComponent) {
105 res.template addPerVertexCustomComponent<uint>(
"birthVertex");
110 if constexpr (comp::HasCustomComponents<OutElemType>) {
111 if (saveBirthIndicesInCustomComponent) {
112 res.template addPerElementCustomComponent<ELEM_ID, uint>(ccname);
116 std::vector<uint> vertexMapping(m.vertexContainerSize(),
UINT_NULL);
118 for (
const auto& [birthF, filter] :
119 std::views::zip(m.template elements<ELEM_ID>(), elemFilterRng)) {
121 std::vector<uint> verts(birthF.vertexNumber(),
UINT_NULL);
130 for (
const InVertexType* v : birthF.
vertices()) {
132 if (vertexMapping[m.index(v)] ==
UINT_NULL) {
134 uint ov = res.addVertex();
136 res.vertex(ov).importFrom(*v,
false);
137 if constexpr (HasPerVertexCustomComponents<OutMeshType>) {
139 if (saveBirthIndicesInCustomComponent) {
140 res.vertex(ov).template customComponent<uint>(
141 "birthVertex") = m.index(v);
144 vertexMapping[m.index(v)] = ov;
148 verts[vi] = vertexMapping[m.index(v)];
155 uint f = res.template add<ELEM_ID>();
157 res.template element<ELEM_ID>(f).importFrom(birthF,
false);
159 if constexpr (OutElemType::VERTEX_NUMBER < 0) {
160 res.template element<ELEM_ID>(f).resizeVertices(verts.size());
163 res.template element<ELEM_ID>(f).setVertices(verts);
165 if constexpr (comp::HasCustomComponents<OutElemType>) {
167 if (saveBirthIndicesInCustomComponent) {
168 res.template element<ELEM_ID>(f)
169 .template customComponent<uint>(ccname) =
178template<MeshConcept OutMeshType, u
int ELEM_ID, MeshConcept InMeshType>
179OutMeshType perElementMeshFilterWithVRefs(
181 const std::function<
bool(
182 const typename InMeshType::template ElementType<ELEM_ID>&)>& elemFilter,
183 bool saveBirthIndicesInCustomComponent =
true)
186 m.template elements<ELEM_ID>() | std::views::transform(elemFilter);
188 return perElementMeshFilterWithVRefs<OutMeshType, ELEM_ID, InMeshType>(
189 m, view, saveBirthIndicesInCustomComponent);
221template<MeshConcept InMeshType, MeshConcept OutMeshType = InMeshType>
222OutMeshType perVertexMeshFilter(
224 const std::function<
bool(
const typename InMeshType::VertexType&)>&
226 bool saveBirthIndicesInCustomComponent =
true)
229 perElementMeshFilter<OutMeshType, ElemId::VERTEX, InMeshType>(
230 m, vertexFilter, saveBirthIndicesInCustomComponent);
261template<MeshConcept InMeshType, MeshConcept OutMeshType = InMeshType>
262OutMeshType perVertexMeshFilter(
264 Range
auto&& vertexFilterRng,
265 bool saveBirthIndicesInCustomComponent =
true)
268 perElementMeshFilter<OutMeshType, ElemId::VERTEX, InMeshType>(
269 m, vertexFilterRng, saveBirthIndicesInCustomComponent);
297template<MeshConcept InMeshType, MeshConcept OutMeshType = InMeshType>
298OutMeshType perVertexSelectionMeshFilter(
300 bool saveBirthIndicesInCustomComponent =
true)
302 auto selView = m.vertices() | views::selection;
305 perElementMeshFilter<OutMeshType, ElemId::VERTEX, InMeshType>(
306 m, selView, saveBirthIndicesInCustomComponent);
339template<FaceMeshConcept InMeshType, FaceMeshConcept OutMeshType = InMeshType>
340OutMeshType perFaceMeshFilter(
342 const std::function<
bool(
const typename InMeshType::FaceType&)>& faceFilter,
343 bool saveBirthIndicesInCustomComponent =
true)
346 perElementMeshFilterWithVRefs<OutMeshType, ElemId::FACE, InMeshType>(
347 m, faceFilter, saveBirthIndicesInCustomComponent);
380template<FaceMeshConcept InMeshType, FaceMeshConcept OutMeshType = InMeshType>
381OutMeshType perFaceMeshFilter(
383 Range
auto&& faceFilterRng,
384 bool saveBirthIndicesInCustomComponent =
true)
387 perElementMeshFilterWithVRefs<OutMeshType, ElemId::FACE, InMeshType>(
388 m, faceFilterRng, saveBirthIndicesInCustomComponent);
418template<FaceMeshConcept InMeshType, FaceMeshConcept OutMeshType = InMeshType>
419OutMeshType perFaceSelectionMeshFilter(
421 bool saveBirthIndicesInCustomComponent =
true)
423 auto selView = m.faces() | views::selection;
426 perElementMeshFilterWithVRefs<OutMeshType, ElemId::FACE, InMeshType>(
427 m, selView, saveBirthIndicesInCustomComponent);
460template<EdgeMeshConcept InMeshType, EdgeMeshConcept OutMeshType = InMeshType>
461OutMeshType perEdgeMeshFilter(
463 const std::function<
bool(
const typename InMeshType::EdgeType&)>& edgeFilter,
464 bool saveBirthIndicesInCustomComponent =
true)
467 perElementMeshFilterWithVRefs<OutMeshType, ElemId::EDGE, InMeshType>(
468 m, edgeFilter, saveBirthIndicesInCustomComponent);
501template<EdgeMeshConcept InMeshType, EdgeMeshConcept OutMeshType = InMeshType>
502OutMeshType perEdgeMeshFilter(
504 Range
auto&& edgeFilterRng,
505 bool saveBirthIndicesInCustomComponent =
true)
508 perElementMeshFilterWithVRefs<OutMeshType, ElemId::EDGE, InMeshType>(
509 m, edgeFilterRng, saveBirthIndicesInCustomComponent);
539template<EdgeMeshConcept InMeshType, EdgeMeshConcept OutMeshType = InMeshType>
540OutMeshType perEdgeSelectionMeshFilter(
542 bool saveBirthIndicesInCustomComponent =
true)
544 auto selView = m.edges() | views::selection;
547 perElementMeshFilterWithVRefs<OutMeshType, ElemId::EDGE, InMeshType>(
548 m, selView, saveBirthIndicesInCustomComponent);
579template<EdgeMeshConcept OutMeshType, FaceMeshConcept InMeshType>
580OutMeshType perFaceEdgeMeshFilter(
582 const std::function<
bool(
const typename InMeshType::FaceType&, uint)>&
584 bool dontDuplicateEdges =
true,
585 bool saveBirthIndicesInCustomComponent =
true)
587 using InVertexType = InMeshType::VertexType;
588 using OutEdgeType = OutMeshType::EdgeType;
592 res.enableSameOptionalComponentsOf(m);
595 if constexpr (HasPerVertexCustomComponents<OutMeshType>) {
596 if (saveBirthIndicesInCustomComponent) {
597 res.template addPerVertexCustomComponent<uint>(
"birthVertex");
601 std::vector<uint> vertexMapping(m.vertexContainerSize(),
UINT_NULL);
603 std::set<std::pair<uint, uint>, UnorderedPairComparator<uint>>
606 for (
const auto& f : m.
faces()) {
607 for (uint ei = 0; ei < f.vertexNumber(); ++ei) {
608 if (faceEdgeFilter(f, ei)) {
610 for (uint i = 0; i < 2; ++i) {
611 const InVertexType* v = f.vertexMod(ei + i);
612 if (vertexMapping[m.index(v)] ==
UINT_NULL) {
613 uint ov = res.addVertex();
614 res.vertex(ov).importFrom(*v,
false);
615 if constexpr (HasPerVertexCustomComponents<
617 if (saveBirthIndicesInCustomComponent) {
618 res.vertex(ov).template customComponent<uint>(
619 "birthVertex") = m.index(v);
622 vertexMapping[m.index(v)] = ov;
626 verts[i] = vertexMapping[m.index(v)];
630 std::pair<uint, uint> ep {verts[0], verts[1]};
631 if (!dontDuplicateEdges || !unorderedEdges.contains(ep)) {
632 uint e = res.addEdge(verts[0], verts[1]);
633 unorderedEdges.insert(ep);
670template<EdgeMeshConcept OutMeshType, FaceMeshConcept InMeshType>
671OutMeshType perFaceEdgeMeshFilter(
673 const std::function<
bool(uint, uint)>& faceEdgeFilter,
674 bool dontDuplicateEdges =
true,
675 bool saveBirthIndicesInCustomComponent =
true)
677 auto filter = [&](
const typename InMeshType::FaceType& f, uint ei) {
678 return faceEdgeFilter(m.index(f), ei);
681 return perFaceEdgeMeshFilter<OutMeshType, InMeshType>(
682 m, filter, dontDuplicateEdges, saveBirthIndicesInCustomComponent);
709template<EdgeMeshConcept OutMeshType, FaceMeshConcept InMeshType>
710OutMeshType perFaceEdgeSelectionMeshFilter(
712 bool dontDuplicateEdges =
true,
713 bool saveBirthIndicesInCustomComponent =
true)
715 auto filter = [&](
const typename InMeshType::FaceType& f, uint ei) {
716 return f.edgeSelected(ei);
719 return perFaceEdgeMeshFilter<OutMeshType, InMeshType>(
720 m, filter, dontDuplicateEdges, saveBirthIndicesInCustomComponent);
constexpr uint UINT_NULL
The UINT_NULL value represent a null value of uint that is the maximum value that can be represented ...
Definition base.h:48
constexpr detail::FacesView faces
A view that allows to iterate overt the Face elements of an object.
Definition face.h:84
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:92