|
@@ -79,10 +79,82 @@ IGL_INLINE void igl::copyleft::cgal::outer_facet(
|
|
|
flipped = adj_faces[order[0]] > 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+template<
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedF,
|
|
|
+ typename DerivedN,
|
|
|
+ typename DerivedI,
|
|
|
+ typename IndexType
|
|
|
+ >
|
|
|
+IGL_INLINE void igl::copyleft::cgal::outer_facet(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::PlainObjectBase<DerivedF> & F,
|
|
|
+ const Eigen::PlainObjectBase<DerivedN> & N,
|
|
|
+ const Eigen::PlainObjectBase<DerivedI> & I,
|
|
|
+ IndexType & f,
|
|
|
+ bool & flipped) {
|
|
|
+ // Algorithm:
|
|
|
+ // Find an outer edge.
|
|
|
+ // Find the incident facet with the largest absolute X normal component.
|
|
|
+ // If there is a tie, keep the one with positive X component.
|
|
|
+ // If there is still a tie, pick the face with the larger signed index
|
|
|
+ // (flipped face has negative index).
|
|
|
+ typedef typename DerivedV::Scalar Scalar;
|
|
|
+ typedef typename DerivedV::Index Index;
|
|
|
+ const size_t INVALID = std::numeric_limits<size_t>::max();
|
|
|
+
|
|
|
+ Index v1,v2;
|
|
|
+ Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;
|
|
|
+ outer_edge(V, F, I, v1, v2, incident_faces);
|
|
|
+ assert(incident_faces.size() > 0);
|
|
|
+
|
|
|
+ auto generic_fabs = [&](const Scalar& val) -> const Scalar {
|
|
|
+ if (val >= 0) return val;
|
|
|
+ else return -val;
|
|
|
+ };
|
|
|
+
|
|
|
+ Scalar max_nx = 0;
|
|
|
+ size_t outer_fid = INVALID;
|
|
|
+ const size_t num_incident_faces = incident_faces.size();
|
|
|
+ for (size_t i=0; i<num_incident_faces; i++)
|
|
|
+ {
|
|
|
+ const auto& fid = incident_faces(i);
|
|
|
+ const Scalar nx = N(fid, 0);
|
|
|
+ if (outer_fid == INVALID) {
|
|
|
+ max_nx = nx;
|
|
|
+ outer_fid = fid;
|
|
|
+ } else {
|
|
|
+ if (generic_fabs(nx) > generic_fabs(max_nx)) {
|
|
|
+ max_nx = nx;
|
|
|
+ outer_fid = fid;
|
|
|
+ } else if (nx == -max_nx && nx > 0) {
|
|
|
+ max_nx = nx;
|
|
|
+ outer_fid = fid;
|
|
|
+ } else if (nx == max_nx) {
|
|
|
+ if ((max_nx >= 0 && outer_fid < fid) ||
|
|
|
+ (max_nx < 0 && outer_fid > fid)) {
|
|
|
+ max_nx = nx;
|
|
|
+ outer_fid = fid;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ assert(outer_fid != INVALID);
|
|
|
+ f = outer_fid;
|
|
|
+ flipped = max_nx < 0;
|
|
|
+}
|
|
|
+
|
|
|
#ifdef IGL_STATIC_LIBRARY
|
|
|
// Explicit template specialization
|
|
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
|
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
|
|
+template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
|
|
|
+template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, unsigned long>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1> > const&, unsigned long&, bool&);
|
|
|
+template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
|
|
|
+template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
|
|
|
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
|
|
|
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
|
|
|
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
|