Easy3D 2.6.1
Loading...
Searching...
No Matches
self_intersection.h
1/********************************************************************
2 * Copyright (C) 2018-2021 by Liangliang Nan <liangliang.nan@gmail.com>
3 * Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
4 *
5 * The code in this file is partly from libigl (version 3 Mar 2016) with
6 * modifications and enhancement:
7 * https://libigl.github.io/
8 * The original code was distributed under the Mozilla Public License v2.
9 ********************************************************************/
10
11#ifndef EASY3D_ALGO_EXT_SELF_INTERSECTION_H
12#define EASY3D_ALGO_EXT_SELF_INTERSECTION_H
13
14#include <vector>
15#include <unordered_map>
16
17// Use this instead to mute errors resulting from bad CGAL assertions
18//#define CGAL_KERNEL_NO_ASSERTIONS
19
20#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
21#include <CGAL/intersections.h> // for triangle-triangle intersection
22#include <CGAL/box_intersection_d.h>
23#include <CGAL/Constrained_Delaunay_triangulation_2.h>
24#include <CGAL/Constrained_triangulation_plus_2.h>
25
26#include <easy3d/core/surface_mesh.h>
27
28namespace easy3d {
42 public:
51
58 std::vector<std::pair<SurfaceMesh::Face, SurfaceMesh::Face> >
59 detect(SurfaceMesh *mesh, bool construct = false);
60
68 bool remesh(SurfaceMesh *mesh, bool stitch);
69
70 private:
71
72 typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
73
74 // 3D Primitives
75 typedef CGAL::Point_3<Kernel> Point_3;
76 typedef CGAL::Vector_3<Kernel> Vector_3;
77 typedef CGAL::Triangle_3<Kernel> Triangle_3;
78 typedef CGAL::Segment_3<Kernel> Segment_3;
79 typedef CGAL::Plane_3<Kernel> Plane_3;
80
81 // Constrained Delaunay Triangulation
82 typedef CGAL::Triangulation_vertex_base_2<Kernel> TVB_2;
83 typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTFB_2;
84 typedef CGAL::Triangulation_data_structure_2<TVB_2, CTFB_2> TDS_2;
85 typedef CGAL::Exact_intersections_tag Itag;
86 typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS_2, Itag> CDT_2;
87 typedef CGAL::Constrained_triangulation_plus_2<CDT_2> CDT_plus_2;
88
89 typedef std::vector<std::pair<int, CGAL::Object> > ObjectList;
90
91 struct Triangle {
92 Triangle(const Point_3 &a, const Point_3 &b, const Point_3 &c, SurfaceMesh::Face f)
93 : triangle(a, b, c), face(f), index(-1) {}
94
95 Triangle_3 triangle;
97 int index; // face index
98 std::vector<SurfaceMesh::Vertex> vertices;
99 };
100
101 // Axis-align boxes for all-pairs self-intersection detection
102 typedef std::vector<Triangle> Triangles;
103 typedef Triangles::iterator TrianglesIterator;
104 typedef CGAL::Box_intersection_d::Box_with_handle_d<double, 3, TrianglesIterator> Box;
105
106 private:
111 void mesh_to_cgal_triangle_list(SurfaceMesh *mesh);
112
119 bool do_intersect(const Triangle &A, const Triangle &B);
120
121 // Given a list of objects (e.g., resulting from intersecting a triangle
122 // with many other triangles), construct a constrained Delaunay
123 // triangulation on a given plane (P), by inserting constraints for each
124 // object projected onto that plane.
125 // Inputs:
126 // objects list of objects. This should lie on the given plane (P),
127 // otherwise they are added to the cdt _after_ their non-trivial
128 // projection
129 // P plane upon which all objects lie and upon which the CDT is
130 // conducted
131 // Outputs:
132 // vertices list of vertices of the CDT mesh _back on the 3D plane_
133 // faces list of triangle indices into vertices
134 //
135 void projected_cdt(
136 const std::vector<CGAL::Object> &objects,
137 const Plane_3 &P,
138 std::vector<Point_3> &vertices,
139 std::vector<std::vector<int> > &faces
140 );
141
142 // Given a current 2D constrained Delaunay triangulation (cdt), insert a
143 // 3D "object" (e.g., resulting from intersecting two triangles) into the
144 // cdt, by projecting it via the given plane (P) and adding appropriate
145 // constraints.
146 // Inputs:
147 // obj CGAL::Object representing a vertex, segment, or (convex)
148 // polygon. All vertices should lie on the plane P. If not, then this
149 // adds the _projection_ of this object to the cdt and that might not
150 // be what you wanted to do.
151 // P plane obj lies on and upon which the cdt is being performed
152 // cdt current CDT, see output
153 // Outputs:
154 // cdt CDT updated to contain constraints for the given object
155 //
156 void insert_into_cdt(const CGAL::Object &obj, const Plane_3 &P, CDT_plus_2 &cdt);
157
158 private:
159 // Helper function to mark a face as offensive
160 // Inputs:
161 // f index of face in F
162 inline void mark_offensive(int f);
163
164 // Helper function to count intersections between faces
165 inline void count_intersection(int fa, int fb);
166
167 // Helper function for box_intersect. Intersect two triangles A and B,
168 // append the intersection object (point,segment,triangle) to a running
169 // list for A and B
170 // Inputs:
171 // A triangle in 3D
172 // B triangle in 3D
173 // Returns true only if A intersects B
174 inline bool intersect(const Triangle &A, const Triangle &B);
175
176 // Helper function for box_intersect. In the case where A and B have
177 // already been identified to share a vertex, then we only want to
178 // add possible segment intersections. Assumes truly duplicate
179 // triangles are not given as input
180 // Inputs:
181 // A triangle in 3D
182 // B triangle in 3D
183 // va shared vertex in A (and key into offending)
184 // vb shared vertex in B (and key into offending)
185 // Returns true if intersection (besides shared point)
186 inline bool single_shared_vertex(const Triangle &A, const Triangle &B, int va, int vb);
187
188 // Helper handling one direction
189 inline bool single_shared_vertex(const Triangle &A, const Triangle &B, int va);
190
191 // Helper function for box_intersect. In the case where A and B have
192 // already been identified to share two vertices, then we only want
193 // to add a possible coplanar (Triangle) intersection. Assumes truly
194 // degenerate facets are not given as input.
195 inline bool double_shared_vertex(
196 const Triangle &A,
197 const Triangle &B,
198 const std::vector<std::pair<int, int> > &shared
199 );
200
201 private:
202 SurfaceMesh* mesh_;
203
204 bool construct_intersection_;
205
206 Triangles triangle_faces_;
207
208 // index in 'triangle_faces_' (degenerate faces removed) -> original face
209 std::unordered_map<int, SurfaceMesh::Face> original_face;
210
211 // list of faces with intersections mapping to the order in
212 // which they were first found
213 std::unordered_map<int, ObjectList> offending_;
214
215 // statistics on duplicate faces (to offer the user some feedback)
216 int total_comb_duplicate_face_; // Combinatorial duplicate faces
217 int total_geom_duplicate_face_; // Geometrically duplicate faces
218 };
219
220} // namespace easy3d
221
222#endif // EASY3D_ALGO_EXT_SELF_INTERSECTION_H
std::vector< std::pair< SurfaceMesh::Face, SurfaceMesh::Face > > detect(SurfaceMesh *mesh, bool construct=false)
Detect intersecting face pairs.
Definition self_intersection.cpp:40
bool remesh(SurfaceMesh *mesh, bool stitch)
Detect and remesh the intersecting faces.
Definition self_intersection.cpp:427
~SelfIntersection()
Destructor for SelfIntersection.
Definition self_intersection.cpp:34
SelfIntersection()
Constructor for SelfIntersection.
Definition self_intersection.cpp:30
A halfedge data structure for polygonal meshes of 2-manifold.
Definition surface_mesh.h:51
Definition collider.cpp:182
Definition surface_mesh.h:191