34 , m_coordinate_handle(coordinate)
35 , m_envelope_size(envelope_size)
37 const auto& envelope_mesh = envelope_mesh_coordinate.
mesh();
39 assert(envelope_mesh_coordinate.
holds<
Rational>() || envelope_mesh_coordinate.
holds<
double>());
44 envelope_mesh.create_const_accessor(envelope_mesh_coordinate.
as<
Rational>());
48 std::vector<Eigen::Vector3d> vertices;
49 std::vector<Eigen::Vector3i> faces;
55 for (
const auto& f : facest) {
64 faces.emplace_back(count, count + 1, count + 2);
65 vertices.push_back(p0);
66 vertices.push_back(p1);
67 vertices.push_back(p2);
73 std::make_shared<fastEnvelope::FastEnvelope>(vertices, faces, envelope_size);
76 logger().warn(
"Envelope for edge mesh is using sampling");
83 Eigen::MatrixXd vertices(2 * edgest.size(), accessor.dimension());
84 Eigen::MatrixXi edges(edgest.size(), 2);
86 for (
const auto& e : edgest) {
87 auto p0 = accessor.const_vector_attribute(e).cast<
double>();
88 auto p1 = accessor.const_vector_attribute(envelope_mesh.switch_tuple(e,
PV))
91 edges.row(index) << count, count + 1;
92 vertices.row(2 * index) = p0;
93 vertices.row(2 * index + 1) = p1;
99 m_bvh = std::make_shared<SimpleBVH::BVH>();
100 m_bvh->init(vertices, edges, 1e-10);
102 throw std::runtime_error(
"Envelope works only for tri/edges meshes");
104 }
else if (envelope_mesh_coordinate.holds<
double>()) {
107 envelope_mesh.create_const_accessor(envelope_mesh_coordinate.as<
double>());
111 std::vector<Eigen::Vector3d> vertices;
112 std::vector<Eigen::Vector3i> faces;
118 for (
const auto& f : facest) {
125 faces.emplace_back(count, count + 1, count + 2);
126 vertices.push_back(p0);
127 vertices.push_back(p1);
128 vertices.push_back(p2);
134 std::make_shared<fastEnvelope::FastEnvelope>(vertices, faces, envelope_size);
137 logger().warn(
"Envelope for edge mesh is using sampling");
144 Eigen::MatrixXd vertices(2 * edgest.size(), accessor.
dimension());
145 Eigen::MatrixXi edges(edgest.size(), 2);
147 for (
const auto& e : edgest) {
151 edges.row(index) << count, count + 1;
152 vertices.row(2 * index) = p0;
153 vertices.row(2 * index + 1) = p1;
159 m_bvh = std::make_shared<SimpleBVH::BVH>();
160 m_bvh->init(vertices, edges, 1e-10);
162 throw std::runtime_error(
"Envelope works only for tri/edges meshes");
165 throw std::runtime_error(
"Envelope mesh handle type invlid");
169bool EnvelopeInvariant::after(
170 const std::vector<Tuple>& top_dimension_tuples_before,
171 const std::vector<Tuple>& top_dimension_tuples_after)
const
173 if (top_dimension_tuples_after.empty())
return true;
175 assert(m_coordinate_handle.holds<
Rational>() || m_coordinate_handle.holds<
double>());
177 if (m_coordinate_handle.holds<
Rational>()) {
179 mesh().create_const_accessor(m_coordinate_handle.as<
Rational>());
185 std::vector<Tuple> faces;
188 std::array<Eigen::Vector3d, 3> triangle;
190 for (
const Tuple& tuple : top_dimension_tuples_after) {
191 faces = faces_single_dimension_tuples(
200 if (m_envelope->is_outside(triangle)) {
208 for (
const Tuple& tuple : top_dimension_tuples_after) {
209 faces = faces_single_dimension_tuples(
217 if (m_envelope->is_outside(p0, p1)) {
225 for (
const Tuple& tuple : top_dimension_tuples_after) {
228 if (m_envelope->is_outside(p)) {
236 throw std::runtime_error(
"Invalid mesh type");
242 SimpleBVH::VectorMax3d nearest_point;
245 const double d = m_envelope_size;
246 const double real_envelope = m_envelope_size - d / sqrt(accessor.
dimension());
247 const double real_envelope_2 = real_envelope * real_envelope;
250 std::vector<SimpleBVH::VectorMax3d> pts;
252 for (
const Tuple& tuple : top_dimension_tuples_after) {
258 const int64_t N = (p0 - p1).norm() / d + 1;
259 pts.reserve(pts.size() + N);
261 for (int64_t n = 0; n <= N; n++) {
262 auto tmp = p0 * (double(n) / N) + p1 * (N -
double(n)) / N;
267 auto current_point = pts[0];
269 int prev_facet = m_bvh->nearest_facet(current_point, nearest_point, sq_dist);
270 if (sq_dist > real_envelope_2) {
275 for (
const auto& v : pts) {
276 sq_dist = (v - nearest_point).squaredNorm();
277 m_bvh->nearest_facet_with_hint(v, prev_facet, nearest_point, sq_dist);
278 if (sq_dist > real_envelope_2) {
286 for (
const Tuple& tuple : top_dimension_tuples_after) {
288 m_bvh->nearest_facet(p, nearest_point, sq_dist);
289 if (sq_dist > m_envelope_size * m_envelope_size) {
297 throw std::runtime_error(
"Invalid mesh type");
301 }
else if (m_coordinate_handle.holds<
double>()) {
303 mesh().create_const_accessor(m_coordinate_handle.as<
double>());
304 const auto type = mesh().top_simplex_type();
309 std::vector<Tuple> faces;
312 std::array<Eigen::Vector3d, 3> triangle;
314 for (
const Tuple& tuple : top_dimension_tuples_after) {
315 faces = faces_single_dimension_tuples(
324 if (m_envelope->is_outside(triangle)) {
332 for (
const Tuple& tuple : top_dimension_tuples_after) {
333 faces = faces_single_dimension_tuples(
341 if (m_envelope->is_outside(p0, p1)) {
349 for (
const Tuple& tuple : top_dimension_tuples_after) {
352 if (m_envelope->is_outside(p)) {
360 throw std::runtime_error(
"Invalid mesh type");
366 SimpleBVH::VectorMax3d nearest_point;
369 const double d = m_envelope_size;
370 const double real_envelope = m_envelope_size - d / sqrt(accessor.
dimension());
371 const double real_envelope_2 = real_envelope * real_envelope;
374 std::vector<SimpleBVH::VectorMax3d> pts;
376 for (
const Tuple& tuple : top_dimension_tuples_after) {
377 SimpleBVH::VectorMax3d p0 =
379 SimpleBVH::VectorMax3d p1 =
383 const int64_t N = (p0 - p1).norm() / d + 1;
384 pts.reserve(pts.size() + N);
386 for (int64_t n = 0; n <= N; n++) {
387 auto tmp = p0 * (double(n) / N) + p1 * (N -
double(n)) / N;
392 auto current_point = pts[0];
394 int prev_facet = m_bvh->nearest_facet(current_point, nearest_point, sq_dist);
395 if (sq_dist > real_envelope_2) {
400 for (
const auto& v : pts) {
401 sq_dist = (v - nearest_point).squaredNorm();
402 m_bvh->nearest_facet_with_hint(v, prev_facet, nearest_point, sq_dist);
403 if (sq_dist > real_envelope_2) {
411 for (
const Tuple& tuple : top_dimension_tuples_after) {
413 m_bvh->nearest_facet(p, nearest_point, sq_dist);
414 if (sq_dist > m_envelope_size * m_envelope_size) {
422 throw std::runtime_error(
"Invalid mesh type");
427 throw std::runtime_error(
"Envelope mesh handle type invlid");