Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
igl::copyleft::cgal::points_inside_component_helper Namespace Reference

Typedefs

typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel
 
typedef Kernel::Ray_3 Ray_3
 
typedef Kernel::Point_3 Point_3
 
typedef Kernel::Vector_3 Vector_3
 
typedef Kernel::Triangle_3 Triangle
 
typedef Kernel::Plane_3 Plane_3
 
typedef std::vector< Triangle >::iterator Iterator
 
typedef CGAL::AABB_triangle_primitive< Kernel, IteratorPrimitive
 
typedef CGAL::AABB_traits< Kernel, PrimitiveAABB_triangle_traits
 
typedef CGAL::AABB_tree< AABB_triangle_traitsTree
 

Functions

template<typename DerivedF , typename DerivedI >
void extract_adj_faces (const Eigen::PlainObjectBase< DerivedF > &F, const Eigen::PlainObjectBase< DerivedI > &I, const size_t s, const size_t d, std::vector< int > &adj_faces)
 
template<typename DerivedF , typename DerivedI >
void extract_adj_vertices (const Eigen::PlainObjectBase< DerivedF > &F, const Eigen::PlainObjectBase< DerivedI > &I, const size_t v, std::vector< int > &adj_vertices)
 
template<typename DerivedV , typename DerivedF , typename DerivedI >
bool determine_point_edge_orientation (const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &F, const Eigen::PlainObjectBase< DerivedI > &I, const Point_3 &query, size_t s, size_t d)
 
template<typename DerivedV , typename DerivedF , typename DerivedI >
bool determine_point_vertex_orientation (const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &F, const Eigen::PlainObjectBase< DerivedI > &I, const Point_3 &query, size_t s)
 
template<typename DerivedV , typename DerivedF , typename DerivedI >
bool determine_point_face_orientation (const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &F, const Eigen::PlainObjectBase< DerivedI > &I, const Point_3 &query, size_t fid)
 

Typedef Documentation

◆ AABB_triangle_traits

◆ Iterator

◆ Kernel

typedef CGAL::Exact_predicates_exact_constructions_kernel igl::copyleft::cgal::points_inside_component_helper::Kernel

◆ Plane_3

◆ Point_3

◆ Primitive

◆ Ray_3

◆ Tree

◆ Triangle

◆ Vector_3

Function Documentation

◆ determine_point_edge_orientation()

template<typename DerivedV , typename DerivedF , typename DerivedI >
bool igl::copyleft::cgal::points_inside_component_helper::determine_point_edge_orientation ( const Eigen::PlainObjectBase< DerivedV > &  V,
const Eigen::PlainObjectBase< DerivedF > &  F,
const Eigen::PlainObjectBase< DerivedI > &  I,
const Point_3 query,
size_t  s,
size_t  d 
)
95 {
96 // Algorithm:
97 //
98 // Order the adj faces around the edge (s,d) clockwise using
99 // query point as pivot. (i.e. The first face of the ordering
100 // is directly after the pivot point, and the last face is
101 // directly before the pivot.)
102 //
103 // The point is outside if the first and last faces of the
104 // ordering forms a convex angle. This check can be done
105 // without any construction by looking at the orientation of the
106 // faces. The angle is convex iff the first face contains (s,d)
107 // as an edge and the last face contains (d,s) as an edge.
108 //
109 // The point is inside if the first and last faces of the
110 // ordering forms a concave angle. That is the first face
111 // contains (d,s) as an edge and the last face contains (s,d) as
112 // an edge.
113 //
114 // In the special case of duplicated faces. I.e. multiple faces
115 // sharing the same 3 corners, but not necessarily the same
116 // orientation. The ordering will always rank faces containing
117 // edge (s,d) before faces containing edge (d,s).
118 //
119 // Therefore, if there are any duplicates of the first faces,
120 // the ordering will always choose the one with edge (s,d) if
121 // possible. The same for the last face.
122 //
123 // In the very degenerated case where the first and last face
124 // are duplicates, but with different orientations, it is
125 // equally valid to think the angle formed by them is either 0
126 // or 360 degrees. By default, 0 degree is used, and thus the
127 // query point is outside.
128
129 std::vector<int> adj_faces;
130 extract_adj_faces(F, I, s, d, adj_faces);
131 const size_t num_adj_faces = adj_faces.size();
132 assert(num_adj_faces > 0);
133
134 DerivedV pivot_point(1, 3);
135 igl::copyleft::cgal::assign_scalar(query.x(), pivot_point(0, 0));
136 igl::copyleft::cgal::assign_scalar(query.y(), pivot_point(0, 1));
137 igl::copyleft::cgal::assign_scalar(query.z(), pivot_point(0, 2));
138 Eigen::VectorXi order;
139 order_facets_around_edge(V, F, s, d,
140 adj_faces, pivot_point, order);
141 assert((size_t)order.size() == num_adj_faces);
142 if (adj_faces[order[0]] > 0 &&
143 adj_faces[order[num_adj_faces-1] < 0]) {
144 return true;
145 } else if (adj_faces[order[0]] < 0 &&
146 adj_faces[order[num_adj_faces-1] > 0]) {
147 return false;
148 } else {
149 throw "The input mesh does not represent a valid volume";
150 }
151 throw "The input mesh does not represent a valid volume";
152 return false;
153 }
void extract_adj_faces(const Eigen::PlainObjectBase< DerivedF > &F, const Eigen::PlainObjectBase< DerivedI > &I, const size_t s, const size_t d, std::vector< int > &adj_faces)
Definition points_inside_component.cpp:41
IGL_INLINE void order_facets_around_edge(const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &F, size_t s, size_t d, const std::vector< int > &adj_faces, Eigen::PlainObjectBase< DerivedI > &order, bool debug=false)
IGL_INLINE void assign_scalar(const CGAL::Epeck::FT &cgal, CGAL::Epeck::FT &d)
Definition assign_scalar.cpp:10

References igl::copyleft::cgal::assign_scalar(), extract_adj_faces(), and igl::copyleft::cgal::order_facets_around_edge().

Referenced by determine_point_vertex_orientation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ determine_point_face_orientation()

template<typename DerivedV , typename DerivedF , typename DerivedI >
bool igl::copyleft::cgal::points_inside_component_helper::determine_point_face_orientation ( const Eigen::PlainObjectBase< DerivedV > &  V,
const Eigen::PlainObjectBase< DerivedF > &  F,
const Eigen::PlainObjectBase< DerivedI > &  I,
const Point_3 query,
size_t  fid 
)
229 {
230 // Algorithm: A point is on the inside of a face if the
231 // tetrahedron formed by them is negatively oriented.
232
233 Eigen::Vector3i f = F.row(I(fid, 0));
234 const Point_3 v0(V(f[0], 0), V(f[0], 1), V(f[0], 2));
235 const Point_3 v1(V(f[1], 0), V(f[1], 1), V(f[1], 2));
236 const Point_3 v2(V(f[2], 0), V(f[2], 1), V(f[2], 2));
237 auto result = CGAL::orientation(v0, v1, v2, query);
238 if (result == CGAL::COPLANAR) {
239 throw "Cannot determine inside/outside because query point lies exactly on the input surface.";
240 }
241 return result == CGAL::NEGATIVE;
242 }
Kernel::Point_3 Point_3
Definition points_inside_component.cpp:31

◆ determine_point_vertex_orientation()

template<typename DerivedV , typename DerivedF , typename DerivedI >
bool igl::copyleft::cgal::points_inside_component_helper::determine_point_vertex_orientation ( const Eigen::PlainObjectBase< DerivedV > &  V,
const Eigen::PlainObjectBase< DerivedF > &  F,
const Eigen::PlainObjectBase< DerivedI > &  I,
const Point_3 query,
size_t  s 
)
160 {
161 std::vector<int> adj_vertices;
162 extract_adj_vertices(F, I, s, adj_vertices);
163 const size_t num_adj_vertices = adj_vertices.size();
164
165 std::vector<Point_3> adj_points;
166 for (size_t i=0; i<num_adj_vertices; i++) {
167 const size_t vi = adj_vertices[i];
168 adj_points.emplace_back(V(vi,0), V(vi,1), V(vi,2));
169 }
170
171 // A plane is on the exterior if all adj_points lies on or to
172 // one side of the plane.
173 auto is_on_exterior = [&](const Plane_3& separator) -> bool{
174 size_t positive=0;
175 size_t negative=0;
176 size_t coplanar=0;
177 for (const auto& point : adj_points) {
178 switch(separator.oriented_side(point)) {
179 case CGAL::ON_POSITIVE_SIDE:
180 positive++;
181 break;
182 case CGAL::ON_NEGATIVE_SIDE:
183 negative++;
184 break;
185 case CGAL::ON_ORIENTED_BOUNDARY:
186 coplanar++;
187 break;
188 default:
189 throw "Unknown plane-point orientation";
190 }
191 }
192 auto query_orientation = separator.oriented_side(query);
193 bool r =
194 (positive == 0 && query_orientation == CGAL::POSITIVE)
195 ||
196 (negative == 0 && query_orientation == CGAL::NEGATIVE);
197 return r;
198 };
199
200 size_t d = std::numeric_limits<size_t>::max();
201 Point_3 p(V(s,0), V(s,1), V(s,2));
202 for (size_t i=0; i<num_adj_vertices; i++) {
203 const size_t vi = adj_vertices[i];
204 for (size_t j=i+1; j<num_adj_vertices; j++) {
205 Plane_3 separator(p, adj_points[i], adj_points[j]);
206 if (separator.is_degenerate()) {
207 throw "Input mesh contains degenerated faces";
208 }
209 if (is_on_exterior(separator)) {
210 d = vi;
211 assert(!CGAL::collinear(p, adj_points[i], query));
212 break;
213 }
214 }
215 if (d < (size_t)V.rows()) break;
216 }
217 if (d > (size_t)V.rows()) {
218 // All adj faces are coplanar, use the first edge.
219 d = adj_vertices[0];
220 }
221 return determine_point_edge_orientation(V, F, I, query, s, d);
222 }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const
Definition PlainObjectBase.h:151
void extract_adj_vertices(const Eigen::PlainObjectBase< DerivedF > &F, const Eigen::PlainObjectBase< DerivedI > &I, const size_t v, std::vector< int > &adj_vertices)
Definition points_inside_component.cpp:65
bool determine_point_edge_orientation(const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &F, const Eigen::PlainObjectBase< DerivedI > &I, const Point_3 &query, size_t s, size_t d)
Definition points_inside_component.cpp:91

References determine_point_edge_orientation(), extract_adj_vertices(), and Eigen::PlainObjectBase< Derived >::rows().

+ Here is the call graph for this function:

◆ extract_adj_faces()

template<typename DerivedF , typename DerivedI >
void igl::copyleft::cgal::points_inside_component_helper::extract_adj_faces ( const Eigen::PlainObjectBase< DerivedF > &  F,
const Eigen::PlainObjectBase< DerivedI > &  I,
const size_t  s,
const size_t  d,
std::vector< int > &  adj_faces 
)
45 {
46 const size_t num_faces = I.rows();
47 for (size_t i=0; i<num_faces; i++) {
48 Eigen::Vector3i f = F.row(I(i, 0));
49 if (((size_t)f[0] == s && (size_t)f[1] == d) ||
50 ((size_t)f[1] == s && (size_t)f[2] == d) ||
51 ((size_t)f[2] == s && (size_t)f[0] == d)) {
52 adj_faces.push_back((I(i, 0)+1) * -1);
53 continue;
54 }
55 if (((size_t)f[0] == d && (size_t)f[1] == s) ||
56 ((size_t)f[1] == d && (size_t)f[2] == s) ||
57 ((size_t)f[2] == d && (size_t)f[0] == s)) {
58 adj_faces.push_back(I(i, 0)+1);
59 continue;
60 }
61 }
62 }

References Eigen::PlainObjectBase< Derived >::rows().

Referenced by determine_point_edge_orientation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ extract_adj_vertices()

template<typename DerivedF , typename DerivedI >
void igl::copyleft::cgal::points_inside_component_helper::extract_adj_vertices ( const Eigen::PlainObjectBase< DerivedF > &  F,
const Eigen::PlainObjectBase< DerivedI > &  I,
const size_t  v,
std::vector< int > &  adj_vertices 
)
68 {
69 std::set<size_t> unique_adj_vertices;
70 const size_t num_faces = I.rows();
71 for (size_t i=0; i<num_faces; i++) {
72 Eigen::Vector3i f = F.row(I(i, 0));
73 if ((size_t)f[0] == v) {
74 unique_adj_vertices.insert(f[1]);
75 unique_adj_vertices.insert(f[2]);
76 } else if ((size_t)f[1] == v) {
77 unique_adj_vertices.insert(f[0]);
78 unique_adj_vertices.insert(f[2]);
79 } else if ((size_t)f[2] == v) {
80 unique_adj_vertices.insert(f[0]);
81 unique_adj_vertices.insert(f[1]);
82 }
83 }
84 adj_vertices.resize(unique_adj_vertices.size());
85 std::copy(unique_adj_vertices.begin(),
86 unique_adj_vertices.end(),
87 adj_vertices.begin());
88 }

References Eigen::PlainObjectBase< Derived >::rows().

Referenced by determine_point_vertex_orientation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: