Geogram Version 1.10.1
A programming library of geometric algorithms
Loading...
Searching...
No Matches
mesh_surface_intersection.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40#ifndef GEOGRAM_MESH_MESH_SURFACE_INTERSECTION
41#define GEOGRAM_MESH_MESH_SURFACE_INTERSECTION
42
44#include <geogram/mesh/mesh.h>
50#include <geogram/basic/debug_stream.h>
51#include <functional>
52#include <tuple>
53
60namespace GEO {
61
62 struct IsectInfo;
63
64 /********************************************************************/
65
70 class GEOGRAM_API MeshSurfaceIntersection {
71 public:
72
74
77
85 void intersect();
86
92
98
105
129 void classify(const std::string& expr);
130
139
147
156 index_t component, index_t v
157 );
158
165 void simplify_coplanar_facets(double angle_tolerance = 0.0);
166
171 void set_verbose(bool x) {
172 verbose_ = x;
173 if(!verbose_ && fine_verbose_) {
174 fine_verbose_ = false;
175 }
176 }
177
182 void set_fine_verbose(bool x) {
183 fine_verbose_ = x;
184 if(fine_verbose_ && !verbose_) {
185 verbose_ = true;
186 }
187 }
188
197 monster_threshold_ = nb;
198 }
199
205 void set_dry_run(bool x) {
206 dry_run_ = x;
207 }
208
215 void set_delaunay(bool x) {
216 delaunay_ = x;
217 }
218
225 detect_intersecting_neighbors_ = x;
226 }
227
235 void set_radial_sort(bool x) {
236 use_radial_sort_ = x;
237 }
238
248 void set_build_skeleton(Mesh* skeleton, bool trim_fins=false) {
249 skeleton_ = skeleton;
250 skeleton_trim_fins_ = trim_fins;
251 }
252
259 interpolate_attributes_ = x;
260 }
261
262 protected:
272
287
306
322 void intersect_epilogue(const vector<IsectInfo>& intersections);
323
324
333 void lock() {
334 Process::acquire_spinlock(lock_);
335 }
336
340 void unlock() {
341 Process::release_spinlock(lock_);
342 }
343
354
363 return (vertex_to_exact_point_[v] == nullptr);
364 }
365
377
384 return mesh_;
385 }
386
392 const Mesh& target_mesh() const {
393 return mesh_;
394 }
395
408 const Mesh& readonly_mesh() const {
409 return mesh_copy_;
410 }
411
412 class RadialSort;
413
424
428 void mark_external_shell(vector<index_t>& on_external_shell);
429
437 return original_facet_id_[f];
438 }
439
450 return !f_is_flipped_.is_bound() || f_is_flipped_[f];
451 }
452
463 std::tuple<vec3, vec3, vec3> get_initial_facet_vertices(index_t f) const {
464 // All facets are duplicated before radial sort. If f is one of
465 // the duplicated facets then its orientation is flipped as
466 // compared to initial facet.
467 index_t orig_f = original_facet_id_[f];
468 vec3 p1 = mesh_copy_.facets.point(orig_f,0);
469 vec3 p2 = mesh_copy_.facets.point(orig_f,1);
470 vec3 p3 = mesh_copy_.facets.point(orig_f,2);
471 if(initial_facet_is_flipped(f)) {
472 std::swap(p1,p3);
473 }
474 return std::make_tuple(p1,p2,p3);
475 }
476
477 protected:
478
482 class GEOGRAM_API RadialSort {
483 public:
489 I_(I),
490 mesh_(I_.target_mesh()),
491 h_ref_(NO_INDEX),
492 degenerate_(false)
493 {
494 }
495
500 void init(index_t h_ref);
501
508 bool operator()(index_t h1, index_t h2) const;
509
516 bool degenerate() const {
517 return degenerate_;
518 }
519
520 protected:
530
538
545
554 void report_problem(const char* message) const;
555
556 private:
557 const MeshSurfaceIntersection& I_;
558 const Mesh& mesh_;
559 index_t h_ref_; // reference halfedge
560 exact::vec3 N_ref_; // normal to reference triangle (exact)
561 mutable bool degenerate_;
562 };
563
564 protected:
565 Process::spinlock lock_;
566 Mesh& mesh_;
567 Mesh mesh_copy_;
568 Attribute<const ExactPoint*> vertex_to_exact_point_;
569 Attribute<index_t> original_facet_id_; // mesh_ facet to mesh_copy_ facet
570 Attribute<bool> f_is_flipped_; // mesh_ facet is flipped wrt mesh_copy_
571
572#if defined(GEOGRAM_USE_EXACT_NT) && defined(GEOGRAM_EXACT_NT_IS_MPF_NT)
573 // Exact points are canonicalized
574 // (by Numeric::optimize_number_representation(vec3HEx)) so
575 // we can use this comparator that makes the global vertex map
576 // much much faster.
577 typedef vec3HExLexicoCompareCanonical ExactPointCompare;
578#else
579 // Generic comparator for global vertex map.
581#endif
582 std::map<ExactPoint,index_t,ExactPointCompare> exact_point_to_vertex_;
583
584 bool verbose_;
585 bool fine_verbose_;
586 bool delaunay_;
587 bool detect_intersecting_neighbors_;
588 bool use_radial_sort_;
589
590 PCK::SOSMode SOS_bkp_;
591
592 index_t monster_threshold_;
593 bool dry_run_;
594 friend class MeshInTriangle;
595 friend class CoplanarFacets;
596
597 Mesh* skeleton_;
598 bool skeleton_trim_fins_;
599 bool interpolate_attributes_;
600
601 bool has_operand_bits_;
602 /***************************************************/
603
612 class Halfedges {
613 public:
614
619 Halfedges(MeshSurfaceIntersection& I) : mesh_(I.mesh_) {
620 }
621
626 // TODO: destroy alpha3 attribute (kept now for debugging
627 }
628
633 void initialize() {
634 facet_corner_alpha3_.bind(
635 mesh_.facet_corners.attributes(), "alpha3"
636 );
637 }
638
644 index_t nb() const {
645 return mesh_.facet_corners.nb();
646 }
647
653 return index_as_iterator(0);
654 }
655
661 return index_as_iterator(nb());
662 }
663
670 return h/3;
671 }
672
683 index_t t1 = facet(h);
684 index_t t2 = mesh_.facet_corners.adjacent_facet(h);
685 if(t2 == NO_INDEX) {
686 return NO_INDEX;
687 }
688 for(index_t h2: mesh_.facets.corners(t2)) {
689 if(mesh_.facet_corners.adjacent_facet(h2) == t1) {
690 return h2;
691 }
692 }
694 }
695
706 return facet_corner_alpha3_[h];
707 }
708
716 return alpha3(3*f)/3;
717 }
718
730 index_t f = h/3;
731 index_t lv = (h+dlv)%3;
732 return mesh_.facets.vertex(f,lv);
733 }
734
735
744 void sew2(index_t h1, index_t h2) {
745 geo_debug_assert(vertex(h1,0) == vertex(h2,1));
746 geo_debug_assert(vertex(h2,0) == vertex(h1,1));
747 index_t t1 = h1/3;
748 index_t t2 = h2/3;
749 mesh_.facet_corners.set_adjacent_facet(h1,t2);
750 mesh_.facet_corners.set_adjacent_facet(h2,t1);
751 }
752
761 void sew3(index_t h1, index_t h2) {
762 geo_debug_assert(vertex(h1,0) == vertex(h2,1));
763 geo_debug_assert(vertex(h2,0) == vertex(h1,1));
764 facet_corner_alpha3_[h1] = h2;
765 facet_corner_alpha3_[h2] = h1;
766 }
767
768 private:
769 Mesh& mesh_;
770 Attribute<index_t> facet_corner_alpha3_;
771 } halfedges_;
772
773 /***************************************************/
774
781 public:
782
787 RadialBundles(MeshSurfaceIntersection& I) : I_(I), mesh_(I.mesh_) {
788 }
789
795
799 index_t nb() const {
800 return bndl_start_.size() - 1;
801 }
802
808 return index_as_iterator(0);
809 }
810
816 return index_as_iterator(nb());
817 }
818
825 geo_debug_assert(bndl < nb());
826 return bndl_start_[bndl+1] - bndl_start_[bndl];
827 }
828
836 index_t halfedge(index_t bndl, index_t li) const {
837 geo_debug_assert(bndl < nb());
838 geo_debug_assert(li < nb_halfedges(bndl));
839 return H_[bndl_start_[bndl] + li];
840 }
841
850 geo_debug_assert(bndl < nb());
851 geo_debug_assert(li < nb_halfedges(bndl));
852 H_[bndl_start_[bndl] + li] = h;
853 }
854
861 return index_ptr_range(
862 H_, bndl_start_[bndl], bndl_start_[bndl+1]
863 );
864 }
865
873 H_, bndl_start_[bndl], bndl_start_[bndl+1]
874 );
875 }
876
884 index_t vertex(index_t bndl, index_t lv) const {
885 geo_debug_assert(bndl_start_[bndl+1] - bndl_start_[bndl] > 0);
886 index_t h = H_[bndl_start_[bndl]];
887 return I_.halfedges_.vertex(h,lv);
888 }
889
898 return v_first_bndl_[v];
899 }
900
909 return bndl_next_around_v_[bndl];
910 }
911
918 index_t result = 0;
919 for(
920 index_t bndl = vertex_first_bundle(v);
921 bndl != NO_INDEX;
922 bndl = next_around_vertex(bndl)
923 ) {
924 ++result;
925 }
926 return result;
927 }
928
936 geo_debug_assert(bndl < nb());
937 return (bndl >= nb()/2) ? (bndl-nb()/2) : (bndl+nb()/2);
938 }
939
946 index_t v = vertex(bndl,0);
947 if(nb_bundles_around_vertex(v) != 2) {
948 return NO_INDEX;
949 }
950 for(
951 index_t bndl2 = vertex_first_bundle(v);
952 bndl2 != NO_INDEX; bndl2 = next_around_vertex(bndl2)
953 ) {
954 if(bndl2 != bndl) {
955 return opposite(bndl2);
956 }
957 }
959 }
960
967 index_t v = vertex(bndl,1);
968 if(nb_bundles_around_vertex(v) != 2) {
969 return NO_INDEX;
970 }
971 for(
972 index_t bndl2 = vertex_first_bundle(v);
973 bndl2 != NO_INDEX; bndl2 = next_around_vertex(bndl2)
974 ) {
975 if(opposite(bndl2) != bndl) {
976 return bndl2;
977 }
978 }
980 }
981
991 geo_debug_assert(bndl < nb());
992 if(nb_halfedges(bndl) <= 2) {
993 return true;
994 }
995 auto b = H_.begin() + std::ptrdiff_t(bndl_start_[bndl]);
996 auto e = H_.begin() + std::ptrdiff_t(bndl_start_[bndl+1]);
997 RS.init(*b);
998 std::sort(
999 b, e, [&RS](index_t h1, index_t h2) {
1000 return RS(h1,h2);
1001 }
1002 );
1003 bool OK = !RS.degenerate();
1004 bndl_is_sorted_[bndl] = OK;
1005 return OK;
1006 }
1007
1017 index_t bndl, const vector<index_t>& halfedges
1018 ) {
1019 geo_debug_assert(halfedges.size() == nb_halfedges(bndl));
1020 for(index_t i=0; i<halfedges.size(); ++i) {
1021 set_halfedge(bndl, i, halfedges[i]);
1022 }
1023 bndl_is_sorted_[bndl] = true;
1024 }
1025
1031 typedef std::pair<index_t, index_t> ChartPos;
1032
1041 index_t bndl, vector<ChartPos>& chart_pos
1042 );
1043
1044 bool is_sorted(index_t bndl) const {
1045 geo_debug_assert(bndl < nb());
1046 return bndl_is_sorted_[bndl];
1047 }
1048
1049 // private:
1051 Mesh& mesh_;
1052 Attribute<index_t> facet_chart_;
1053 vector<index_t> H_;
1054 vector<index_t> bndl_start_;
1055 vector<index_t> v_first_bndl_;
1056 vector<index_t> bndl_next_around_v_;
1057 vector<char> bndl_is_sorted_; // not vector<bool>, multithread! (#308)
1058 } radial_bundles_;
1059
1060 /***************************************************/
1061
1063 public:
1068 RadialPolylines(MeshSurfaceIntersection& I) : I_(I), mesh_(I.mesh_) {
1069 }
1070
1076
1083
1087 index_t nb() const {
1088 return polyline_start_.size() - 1;
1089 }
1090
1096 return index_as_iterator(0);
1097 }
1098
1104 return index_as_iterator(nb());
1105 }
1106
1113 geo_debug_assert(polyline < nb());
1114 return const_index_ptr_range(
1115 B_, polyline_start_[polyline], polyline_start_[polyline+1]
1116 );
1117 }
1118
1119 index_t nb_bundles(index_t polyline) const {
1120 geo_debug_assert(polyline < nb());
1121 return polyline_start_[polyline+1] - polyline_start_[polyline];
1122 }
1123
1124 index_t bundle(index_t polyline, index_t li) const {
1125 geo_debug_assert(polyline < nb());
1126 geo_debug_assert(li < nb_bundles(polyline));
1127 return B_[polyline_start_[polyline] + li];
1128 }
1129
1137 void get_skeleton(Mesh& to, bool trim_fins=false);
1138
1139 private:
1141 Mesh& mesh_;
1142 vector<index_t> B_;
1143 vector<index_t> polyline_start_;
1144 } radial_polylines_;
1145 };
1146
1147 /********************************************************************/
1148
1149 enum MeshBooleanOperationFlags {
1150 MESH_BOOL_OPS_DEFAULT = 0,
1151 MESH_BOOL_OPS_VERBOSE = 1,
1152 MESH_BOOL_OPS_ATTRIBS = 2,
1153 MESH_BOOL_OPS_NO_SIMPLIFY = 4,
1154 MESH_BOOL_OPS_NO_CHECK_NEIGHBORS = 8
1155 };
1156
1172 void GEOGRAM_API mesh_boolean_operation(
1173 Mesh& result, const Mesh& A, const Mesh& B, const std::string& operation,
1174 MeshBooleanOperationFlags flags = MESH_BOOL_OPS_DEFAULT
1175 );
1176
1188 Mesh& result, const Mesh& A, const Mesh& B, const std::string& operation,
1189 bool verbose
1190 ) {
1192 result, A, B, operation,
1193 verbose ? MESH_BOOL_OPS_VERBOSE : MESH_BOOL_OPS_DEFAULT
1194 );
1195 }
1196
1211 inline void mesh_union(
1212 Mesh& result, const Mesh& A, const Mesh& B,
1213 MeshBooleanOperationFlags flags=MESH_BOOL_OPS_DEFAULT
1214 ) {
1215 mesh_boolean_operation(result, A, B, "A+B", flags);
1216 }
1217
1227 inline void mesh_union(
1228 Mesh& result, const Mesh& A, const Mesh& B, bool verbose
1229 ) {
1230 mesh_boolean_operation(result, A, B, "A+B", verbose);
1231 }
1232
1233
1249 Mesh& result, const Mesh& A, const Mesh& B,
1250 MeshBooleanOperationFlags flags=MESH_BOOL_OPS_DEFAULT
1251 ) {
1252 mesh_boolean_operation(result, A, B, "A*B", flags);
1253 }
1254
1265 Mesh& result, const Mesh& A, const Mesh& B, bool verbose
1266 ) {
1267 mesh_boolean_operation(result, A, B, "A*B", verbose);
1268 }
1269
1284 inline void mesh_difference(
1285 Mesh& result, const Mesh& A, const Mesh& B,
1286 MeshBooleanOperationFlags flags=MESH_BOOL_OPS_DEFAULT
1287 ) {
1288 mesh_boolean_operation(result, A, B, "A-B", flags);
1289 }
1290
1300 inline void mesh_difference(
1301 Mesh& result, const Mesh& A, const Mesh& B, bool verbose
1302 ) {
1303 mesh_boolean_operation(result, A, B, "A-B", verbose);
1304 }
1305
1313 Mesh& M, index_t max_iter = 3, bool verbose=false
1314 );
1315
1326 Mesh& M, index_t f1, index_t f2
1327 );
1328
1329 /**************************************************************************/
1330}
1331
1332#endif
#define geo_assert_not_reached
Sets a non reachable point in the program.
Definition assert.h:177
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition assert.h:196
Generic mechanism for attributes.
Manages an attribute attached to a set of object.
Detects and retriangulates a set of coplanar facets for MeshSurfaceIntersection.
index_t adjacent_facet(index_t c) const
Gets the facet that a corner is adjacent to.
Definition mesh.h:996
void set_adjacent_facet(index_t c, index_t f)
Sets the facet that a corner is adjacent to.
Definition mesh.h:1059
index_t vertex(index_t f, index_t lv) const
Gets a vertex by facet and local vertex index.
Definition mesh.h:1199
index_range corners(index_t f) const
Gets the corners of a facet.
Definition mesh.h:1594
Meshes a single triangle with the constraints that come from the intersections with the other triangl...
AttributesManager & attributes() const
Gets the attributes manager.
Definition mesh.h:109
index_t nb() const
Gets the number of (sub-)elements.
Definition mesh.h:98
Halfedfge-like API wrappers on top of a triangulated mesh.
index_t facet(index_t h) const
Gets the facet associated to a halfedge.
void sew2(index_t h1, index_t h2)
Creates a surfacic link between two halfedges.
void sew3(index_t h1, index_t h2)
Creates a volumetric link between two halfedges.
index_t alpha3(index_t h) const
gets the volumetric neighbor of a halfedge
index_t vertex(index_t h, index_t dlv) const
gets a vertex of an halfedge
index_t alpha2(index_t h) const
gets the surfacic neighbor of a halfedge
index_t facet_alpha3(index_t f) const
gets the volumetric neighbor of a facet
Halfedges(MeshSurfaceIntersection &I)
Halfedges constructor.
index_as_iterator begin() const
used by range-based for
index_t nb() const
Gets the number of halfedegs in the map.
index_as_iterator end() const
used by range-based for
Represents the set of radial halfedge bundles.
index_as_iterator begin() const
used by range-based for
index_t nb() const
Gets the number of bundles.
index_t vertex(index_t bndl, index_t lv) const
gets one of the vertices at the two extremities of a bundle
index_t vertex_first_bundle(index_t v) const
gets the first bundle starting from a vertex
void get_sorted_incident_charts(index_t bndl, vector< ChartPos > &chart_pos)
Gets the sorted list of charts around bundle.
index_as_iterator end() const
used by range-based for
const_index_ptr_range halfedges(index_t bndl) const
gets the halfedges in a bundle
index_t next_around_vertex(index_t bndl) const
gets the next bundle around a vertex
bool radial_sort(index_t bndl, RadialSort &RS)
Sorts the halfedges of the bundle in-place.
index_ptr_range halfedges(index_t bndl)
gets the halfedges in a bundle
index_t prev_along_polyline(index_t bndl)
gets the predecessor of a bundle along its polyline
index_t nb_halfedges(index_t bndl) const
Gets the number of halfedges in a bundle.
void initialize()
Initializes the structure.
index_t next_along_polyline(index_t bndl)
gets the successor of a bundle along its polyline
void set_sorted_halfedges(index_t bndl, const vector< index_t > &halfedges)
Sets the halfedges of a bundle.
std::pair< index_t, index_t > ChartPos
Indicates where to find a chart in a bundle.
index_t nb_bundles_around_vertex(index_t v) const
gets the bumber of bundles around a vertex
RadialBundles(MeshSurfaceIntersection &I)
RadialBundles constructor.
index_t opposite(index_t bndl)
gets the opposite bundle
index_t halfedge(index_t bndl, index_t li) const
Gets a halfedge in a bundle from local index.
void set_halfedge(index_t bndl, index_t li, index_t h)
Sets a halfedge in a bundle.
void radial_sort()
Sorts all the bundles of all polylines.
index_as_iterator begin() const
used by range-based for
const_index_ptr_range bundles(index_t polyline) const
gets the bundles in a polyline
void get_skeleton(Mesh &to, bool trim_fins=false)
Copies the set of polylines to a mesh.
void initialize()
Initializes the structure.
index_t nb() const
Gets the number of polylines.
index_as_iterator end() const
used by range-based for
RadialPolylines(MeshSurfaceIntersection &I)
RadialPolylines constructor.
Sign h_orient(index_t h1, index_t h2) const
Computes the relative orientations of two halfedges.
Sign h_refNorient(index_t h2) const
Computes the normal orientation of a halfedge relative to h_ref.
void init(index_t h_ref)
Initializes radial sorting around a given halfedge.
bool degenerate() const
Tests if a degeneracy was encountered.
RadialSort(const MeshSurfaceIntersection &I)
RadialSort constructor.
void report_problem(const char *message) const
This function is called whenever radial sort encounters a configuration not supposed to happen....
exact::vec3 normal(index_t h) const
Computes the normal to a facet with exact coordinates.
bool operator()(index_t h1, index_t h2) const
Compares two halfedges.
Computes surface intersections.
void remove_fins()
Not implemented yet.
void set_verbose(bool x)
Display information while computing the intersection. Default is unset.
void set_monster_threshold(index_t nb)
Sets the threshold from which triangle is considered to be a monster.
index_t compute_component_inclusion_bits(index_t component, index_t v)
Finds the operands in which a component is included.
void simplify_coplanar_facets(double angle_tolerance=0.0)
Merge coplanar facets and retriangulate them using a Constrained Delaunay triangulation.
void remove_internal_shells()
Removes all the facets that are not on the outer boundary.
index_t compute_component_inclusion_bits_exact(index_t component, index_t v)
Like compute_component_inclusion_bits(), but when v is not an original vertex.
void unlock()
Releases the lock associated with this mesh.
void set_detect_intersecting_neighbors(bool x)
detect and compute intersections between facets that share a facet or an edge. Set to false if input ...
void set_dry_run(bool x)
In dry run mode, the computed local triangulations are not inserted in the global mesh....
index_t find_or_create_exact_vertex(const ExactPoint &p)
Finds or creates a vertex in the mesh, by exact coordinates.
void set_fine_verbose(bool x)
Display detailed information while computing the intersection. Default is unset.
void intersect_prologue()
substep of intersect(), prepares the mesh
void remove_external_shell()
Removes all the facets that are on the outer boundary.
bool initial_facet_is_flipped(index_t f) const
Indicates whether the initial facet (in mesh_copy_) that supports a facet in the intersection mesh (i...
const Mesh & readonly_mesh() const
Gets a copy of the initial mesh passed to the constructor.
void set_build_skeleton(Mesh *skeleton, bool trim_fins=false)
Optionally save the skeleton (that is, the collection of non-manifold edges) to a given mesh....
const Mesh & target_mesh() const
Gets the target mesh.
ExactPoint exact_vertex(index_t v) const
Gets the exact point associated with a vertex.
void set_radial_sort(bool x)
Specifies whether surfaces should be duplicated and radial edges sorted in order to create the volume...
void intersect_epilogue(const vector< IsectInfo > &intersections)
subset of intersect(), cleans the resulting mesh and undoes optional geometric normalization.
void intersect_get_intersections(vector< IsectInfo > &intersections)
substep of intersect(), finds all the intersection points and segments.
void classify(const std::string &expr)
Classifies the facets and keep only the ones on the boundary of a combination of regions defined by a...
void lock()
Acquires a lock on this mesh.
bool is_original_vertex(index_t v) const
Tests whether a given vertex is an original mesh vertex or an intersection.
void intersect_remesh_intersections(vector< IsectInfo > &intersections)
substep of intersect(), inserts the intersection points and segments into the triangles.
index_t get_initial_facet(index_t f) const
Gets the vertices of the initial facet (in mesh_copy_) that supports a facet in the intersection mesh...
void mark_external_shell(vector< index_t > &on_external_shell)
Marks all the facets that are on the external shell.
void build_Weiler_model()
Builds the Weiler model.
void set_interpolate_attributes(bool x)
Specifies that attributes should be interpolated.
Mesh & target_mesh()
Gets the target mesh.
void set_delaunay(bool x)
If set, compute constrained Delaunay triangulation in the intersected triangles. If there are interse...
index_t compute_component_inclusion_bits_exact_exact(index_t component, index_t v)
Like compute_component_inclusion_bits(), but uses computed intersection mesh, and exact coordinates e...
std::tuple< vec3, vec3, vec3 > get_initial_facet_vertices(index_t f) const
Gets the vertices of the initial facet (in mesh_copy_) that supports a facet in the intersection mesh...
Represents a mesh.
Definition mesh.h:3169
Wraps an integer to be used with the range-based for construct.
Definition range.h:66
Comparator class for vec3Hg \detail Used to create maps indexed by vec3Hg or SOS symbolic perturbatio...
Definition vechg.h:303
3d vector with homogeneous coordinates
Definition vechg.h:190
Vector with aligned memory allocation.
Definition memory.h:703
index_t size() const
Gets the number of elements.
Definition memory.h:749
Exact predicates and constructs.
Common include file, providing basic definitions. Should be included before anything else by all head...
The class that represents a mesh.
Functions to load and save meshes.
SOSMode
Mode for symbolic perturbations.
Definition predicates.h:67
std::atomic_flag spinlock
A lightweight synchronization structure.
Global Vorpaline namespace.
Definition basic.h:55
bool mesh_facets_have_intersection(Mesh &M, index_t f1, index_t f2)
Tests whether two mesh facets have a non-degenerate intersection.
void mesh_intersection(Mesh &result, const Mesh &A, const Mesh &B, MeshBooleanOperationFlags flags=MESH_BOOL_OPS_DEFAULT)
Computes the intersection of two surface meshes.
void mesh_difference(Mesh &result, const Mesh &A, const Mesh &B, MeshBooleanOperationFlags flags=MESH_BOOL_OPS_DEFAULT)
Computes the difference of two surface meshes.
void mesh_boolean_operation(Mesh &result, const Mesh &A, const Mesh &B, const std::string &operation, MeshBooleanOperationFlags flags=MESH_BOOL_OPS_DEFAULT)
Computes a boolean operation with two surface meshes.
void mesh_union(Mesh &result, const Mesh &A, const Mesh &B, MeshBooleanOperationFlags flags=MESH_BOOL_OPS_DEFAULT)
Computes the union of two surface meshes.
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:340
Sign
Integer constants that represent the sign of a value.
Definition numeric.h:72
void mesh_remove_intersections(Mesh &M, index_t max_iter=3, bool verbose=false)
Attempts to make a surface mesh conformal by removing intersecting facets and re-triangulating the ho...
Filtered exact predicates for restricted Voronoi diagrams.
Function and classes for process manipulation.