14#ifdef LAGRANGE_ENABLE_LEGACY_FUNCTIONS
15 #include <lagrange/ExactPredicatesShewchuk.h>
16 #include <lagrange/Mesh.h>
17 #include <lagrange/mesh_cleanup/detect_degenerate_triangles.h>
18 #include <lagrange/primitive/legacy/generation_utils.h>
20 #include <catch2/catch_approx.hpp>
23#include <lagrange/SurfaceMesh.h>
24#include <lagrange/compute_components.h>
25#include <lagrange/extract_boundary_loops.h>
26#include <lagrange/mesh_cleanup/detect_degenerate_facets.h>
27#include <lagrange/testing/common.h>
28#include <lagrange/topology.h>
29#include <lagrange/uv_mesh.h>
32namespace primitive_test_utils {
34template <
typename Scalar,
typename Index>
35void validate_primitive(SurfaceMesh<Scalar, Index>& mesh,
int num_boundaries = 0)
45template <
typename Scalar,
typename Index>
46void check_degeneracy(SurfaceMesh<Scalar, Index>& mesh)
49 REQUIRE(degenerate_facets.empty());
56template <
typename Scalar,
typename Index>
57void check_UV(SurfaceMesh<Scalar, Index>& mesh)
60 uv_mesh.initialize_edges();
61 check_degeneracy(uv_mesh);
64#ifdef LAGRANGE_ENABLE_LEGACY_FUNCTIONS
65template <
typename MeshType>
66void validate_primitive(MeshType& mesh,
int num_boundaries = 0)
68 mesh.initialize_topology();
69 REQUIRE(mesh.is_vertex_manifold());
70 REQUIRE(mesh.is_edge_manifold());
72 mesh.initialize_components();
73 REQUIRE(mesh.get_num_components() == 1);
80template <
typename MeshType>
81void check_degeneracy(MeshType& mesh)
83 lagrange::detect_degenerate_triangles(mesh);
84 REQUIRE(mesh.has_facet_attribute(
"is_degenerate"));
85 REQUIRE(mesh.get_facet_attribute(
"is_degenerate").maxCoeff() == Catch::Approx(0.0));
87 if (!mesh.is_connectivity_initialized()) {
88 mesh.initialize_connectivity();
91 const auto adj_facets = mesh.get_facets_adjacent_to_vertex(i);
92 REQUIRE(adj_facets.size() > 0);
96template <
typename MeshType>
97void check_UV(MeshType& mesh)
99 REQUIRE(mesh.is_uv_initialized());
100 auto uv_mesh = mesh.get_uv_mesh();
101 lagrange::detect_degenerate_triangles(*uv_mesh);
102 REQUIRE(uv_mesh->has_facet_attribute(
"is_degenerate"));
103 REQUIRE(uv_mesh->get_facet_attribute(
"is_degenerate").maxCoeff() == Catch::Approx(0.0));
105 const auto& uvs = uv_mesh->get_vertices();
106 const auto& uv_indices = uv_mesh->get_facets();
107 ExactPredicatesShewchuk predicates;
108 for (
const auto f : uv_indices.rowwise()) {
109 Eigen::Matrix<double, 1, 2> p0 = uvs.row(f[0]).template
cast<double>();
110 Eigen::Matrix<double, 1, 2> p1 = uvs.row(f[1]).template
cast<double>();
111 Eigen::Matrix<double, 1, 2> p2 = uvs.row(f[2]).template
cast<double>();
113 REQUIRE(predicates.orient2D(p0.data(), p1.data(), p2.data()) == 1);
117template <
typename MeshType>
118void check_semantic_labels(
const MeshType& mesh)
120 REQUIRE(mesh.has_facet_attribute(
"semantic_label"));
122 const auto& labels = mesh.get_facet_attribute(
"semantic_label");
124 for (
auto i :
range(num_facets)) {
126 REQUIRE(l != PrimitiveSemanticLabel::UNKNOWN);
Index get_num_vertices() const
Retrieves the number of vertices.
Definition SurfaceMesh.h:680
Index count_num_corners_around_vertex(Index v) const
Count the number of corners incident to a given vertex.
Definition SurfaceMesh.cpp:2750
Index get_num_facets() const
Retrieves the number of facets.
Definition SurfaceMesh.h:687
bool is_edge_manifold(const SurfaceMesh< Scalar, Index > &mesh)
Check if a mesh is edge-manifold.
Definition topology.cpp:125
bool is_vertex_manifold(const SurfaceMesh< Scalar, Index > &mesh)
Check if a mesh is vertex-manifold.
Definition topology.cpp:98
std::vector< std::vector< Index > > extract_boundary_loops(const SurfaceMesh< Scalar, Index > &mesh)
Extract boundary loops from a surface mesh.
Definition extract_boundary_loops.cpp:24
SurfaceMesh< ToScalar, ToIndex > cast(const SurfaceMesh< FromScalar, FromIndex > &source_mesh, const AttributeFilter &convertible_attributes={}, std::vector< std::string > *converted_attributes_names=nullptr)
Cast a mesh to a mesh of different scalar and/or index type.
size_t compute_components(SurfaceMesh< Scalar, Index > &mesh, ComponentOptions options={})
Compute connected components of an input mesh.
Definition compute_components.cpp:99
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition range.h:176
constexpr T safe_cast_enum(const U u)
Casting an enum to scalar and vice versa.
Definition safe_cast.h:163
constexpr auto safe_cast(SourceType value) -> std::enable_if_t<!std::is_same< SourceType, TargetType >::value, TargetType >
Perform safe cast from SourceType to TargetType, where "safe" means:
Definition safe_cast.h:50
Main namespace for Lagrange.
SurfaceMesh< UVScalar, Index > uv_mesh_view(const SurfaceMesh< Scalar, Index > &mesh, const UVMeshOptions &options={})
Extract a UV mesh view from an input mesh.
Definition uv_mesh.cpp:52
std::vector< Index > detect_degenerate_facets(const SurfaceMesh< Scalar, Index > &mesh)
Detects degenerate facets in a mesh.
Definition detect_degenerate_facets.cpp:32