Update eigen to v5.0.1 and libigl to v2.6.0. (#11311)

* Update eigen from v3.3.7 to v5.0.1.

This updates eigen from v3.3.7 released on  December 11, 2018-12-11 to v5.0.1
released on 2025-11-11. There have be a large number of bug-fixes,
optimizations, and improvements between these releases. See the details at;

https://gitlab.com/libeigen/eigen/-/releases

It retains the previous custom minimal `CMakeLists.txt`, and adds a
README-OrcaSlicer.md that explains what version and parts of the upstream
eigen release have been included, and where the full release can be found.

* Update libigl from v2.0.0 (or older) to v2.6.0.

This updates libigl from what was probably v2.0.0 released on 2018-10-16 to
v2.6.0 released on 2025-05-15. It's possible the old version was even older
than that but there is no version indicators in the code and I ran out of
patience identifying missing changes and only went back as far as v2.0.0.

There have been a large number of bug-fixes, optimizations, and improvements
between these versions. See the following for details;

https://github.com/libigl/libigl/releases

I retained the minimal custom `CMakeLists.txt`, added `README.md` from the
libigl distribution which identifies the version, and added a
README-OrcaSlicer.md that details the version and parts that have been
included.

* Update libslic3r for libigl v2.6.0 changes.

This updates libslic3r for all changes moving to eigen v5.0.1 and libigl
v2.6.0. Despite the large number of updates to both dependencies, no changes
were required for the eigen update, and only one change was required for the
libigl update.

For libigl, `igl::Hit` was changed to a template taking the Scalar type to
use. Previously it was hard-coded to `float`, so to minimize possible impact
I've updated all places it is used from `igl::Hit` to `igl::Hit<float>`.

* Add compiler option `-DNOMINMAX` for libigl with MSVC.

MSVC by default defines `min(()` and `max()` macros that break
`std::numeric_limits<>::max()`. The upstream cmake that we don't include
adds `-DNOMINMAX` for the libigl module when compiling with MSVC, so we need
to add the same thing here.

* Fix src/libslic3r/TriangleMeshDeal.cpp for the unmodified upstream libigl.

This fixes `TriangleMeshDeal.cpp` to work with the unmodified upstream
libigl v2.6.0. loop.{h,cpp} implementation.

This file and feature was added in PR "BBS Port: Mesh Subdivision" (#12150)
which included changes to `loop.{h,cpp}` in the old version of libigl. This PR
avoids modifying the included dependencies, and uses the updated upstream
versions of those files without any modifications, which requires fixing
TriangleMeshDeal.cpp to work with them.

In particular, the modifications made to `loop.{h,cpp}` included changing the
return type from void to bool, adding additional validation checking of the
input meshes, and returning false if they failed validation. These added
checks looked unnecessary and would only have caught problems if the input
mesh was very corrupt.

To make `TriangleMeshDeal.cpp` work without this built-in checking
functionality, I removed checking/handling of any `false` return value.

There was also a hell of a lot of redundant copying and casting back and forth
between float and double, so I cleaned that up. The input and output meshs use
floats for the vertexes, and there would be no accuracy benefits from casting
to and from doubles for the simple weighted average operations done by
igl::loop(). So this just uses `Eigen:Map` to use the original input mesh
vertex data directly without requiring any copy or casting.

* Move eigen from included `deps_src` to externaly fetched `deps`.

This copys what PrusaSlicer did and moved it from an included dependency under
`deps_src` to an externaly fetched dependency under `deps`. This requires
updating some `CMakeList.txt` configs and removing the old and obsolete
`cmake/modules/FindEigen3.cmake`. The details of when this was done in
PrusaSlicer and the followup fixes are at;

* 21116995d7
* https://github.com/prusa3d/PrusaSlicer/issues/13608
* https://github.com/prusa3d/PrusaSlicer/pull/13609
* e3c277b9ee

For some reason I don't fully understand this also required fixing
`src/slic3r/GUI/GUI_App.cpp` by adding `#include <boost/nowide/cstdio.hpp>` to
fix an `error: ‘remove’ is not a member of ‘boost::nowide'`. The main thing I
don't understand is how it worked before. Note that this include is in the
PrusaSlicer version of this file, but it also significantly deviates from what
is currently in OrcaSlicer in many other ways.

* Whups... I missed adding the deps/Eigen/Eigen.cmake file...

* Tidy some whitespace indenting in CMakeLists.txt.

* Ugh... tabs indenting needing fixes.

* Change the include order of deps/Eigen.

It turns out that although Boost includes some references to Eigen, Eigen also
includes some references to Boost for supporting some of it's additional
numeric types.

I don't think it matters much since we are not using these features, but I
think technically its more correct to say Eigen depends on Boost than the
other way around, so I've re-ordered them.

* Add source for Eigen 5.0.1 download to flatpak yml config.

* Add explicit `DEPENDS dep_Boost to deps/Eigen.

I missed this before. This ensures we don't rely on include orders to make
sure Boost is installed before we configure Eigen.

* Add `DEPENDS dep_Boost dep_GMP dep_MPFR` to deps/Eigen.

It turns out Eigen can also use GMP and MPFR for multi-precision and
multi-precision-rounded numeric types if they are available.

Again, I don't think we are using these so it doesn't really matter, but it is
technically correct and ensures they are there if we ever do need them.

* Fix deps DEPENDENCY ordering for GMP, MPFR, Eigen, and CGAL.

I think this is finally correct. Apparently CGAL also optionally depends on
Eigen, so the correct dependency order from lowest to highest is GMP, MPFR, Eigen, and CGAL.

---------

Co-authored-by: Donovan Baarda <dbaarda@google.com>
Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
This commit is contained in:
Donovan Baarda
2026-05-12 17:09:13 +10:00
committed by GitHub
parent 79f0ac6346
commit 239b61f821
1573 changed files with 63323 additions and 161343 deletions

View File

@ -26,23 +26,24 @@ namespace igl
{
namespace cgal
{
/// Binary winding number operations
template <igl::MeshBooleanType Op>
class BinaryWindingNumberOperations {
public:
template<typename DerivedW>
typename DerivedW::Scalar operator()(
const Eigen::PlainObjectBase<DerivedW>& /*win_nums*/) const {
const Eigen::MatrixBase<DerivedW>& /*win_nums*/) const {
throw (std::runtime_error("not implemented!"));
}
};
// A B ... Z
/// A B ... Z
template <>
class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_UNION> {
public:
template<typename DerivedW>
typename DerivedW::Scalar operator()(
const Eigen::PlainObjectBase<DerivedW>& win_nums) const
const Eigen::MatrixBase<DerivedW>& win_nums) const
{
for(int i = 0;i<win_nums.size();i++)
{
@ -52,13 +53,13 @@ namespace igl
}
};
// A ∩ B ∩ ... ∩ Z
/// A ∩ B ∩ ... ∩ Z
template <>
class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_INTERSECT> {
public:
template<typename DerivedW>
typename DerivedW::Scalar operator()(
const Eigen::PlainObjectBase<DerivedW>& win_nums) const
const Eigen::MatrixBase<DerivedW>& win_nums) const
{
for(int i = 0;i<win_nums.size();i++)
{
@ -68,13 +69,13 @@ namespace igl
}
};
// A \ B \ ... \ Z = A \ (B ... Z)
/// A \ B \ ... \ Z = A \ (B ... Z)
template <>
class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_MINUS> {
public:
template<typename DerivedW>
typename DerivedW::Scalar operator()(
const Eigen::PlainObjectBase<DerivedW>& win_nums) const
const Eigen::MatrixBase<DerivedW>& win_nums) const
{
assert(win_nums.size()>1);
// Union of objects 1 through n-1
@ -89,13 +90,13 @@ namespace igl
}
};
// A ∆ B ∆ ... ∆ Z (equivalent to set inside odd number of objects)
/// A ∆ B ∆ ... ∆ Z (equivalent to set inside odd number of objects)
template <>
class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_XOR> {
public:
template<typename DerivedW>
typename DerivedW::Scalar operator()(
const Eigen::PlainObjectBase<DerivedW>& win_nums) const
const Eigen::MatrixBase<DerivedW>& win_nums) const
{
// If inside an odd number of objects
int count = 0;
@ -107,12 +108,13 @@ namespace igl
}
};
/// Resolve all intersections without removing non-coplanar faces
template <>
class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_RESOLVE> {
public:
template<typename DerivedW>
typename DerivedW::Scalar operator()(
const Eigen::PlainObjectBase<DerivedW>& /*win_nums*/) const {
const Eigen::MatrixBase<DerivedW>& /*win_nums*/) const {
return true;
}
};
@ -123,21 +125,26 @@ namespace igl
typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_XOR> BinaryXor;
typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_RESOLVE> BinaryResolve;
/// Types of Keep policies
enum KeeperType {
/// Keep only inside
KEEP_INSIDE,
/// Keep everything
KEEP_ALL
};
/// Filter winding numbers according to keep policy
template<KeeperType T>
class WindingNumberFilter {
public:
template<typename DerivedW>
short operator()(
const Eigen::PlainObjectBase<DerivedW>& /*win_nums*/) const {
const Eigen::MatrixBase<DerivedW>& /*win_nums*/) const {
throw std::runtime_error("Not implemented");
}
};
/// Keep inside policy
template<>
class WindingNumberFilter<KEEP_INSIDE> {
public:
@ -149,6 +156,7 @@ namespace igl
}
};
/// Keep all policy
template<>
class WindingNumberFilter<KEEP_ALL> {
public:
@ -158,8 +166,8 @@ namespace igl
}
};
typedef WindingNumberFilter<KEEP_INSIDE> KeepInside;
typedef WindingNumberFilter<KEEP_ALL> KeepAll;
using KeepInside = WindingNumberFilter<KEEP_INSIDE>;
using KeepAll = WindingNumberFilter<KEEP_ALL>;
}
}
}

View File

@ -20,26 +20,26 @@ namespace igl
{
namespace cgal
{
// Class for defining and computing a constructive solid geometry result
// out of a tree of boolean operations on "solid" triangle meshes.
//
//template <typename DerivedF>
/// Class for defining and computing a constructive solid geometry result
/// out of a tree of boolean operations on "solid" triangle meshes.
///
class CSGTree
{
public:
typedef CGAL::Epeck::FT ExactScalar;
//typedef Eigen::PlainObjectBase<DerivedF> POBF;
typedef Eigen::MatrixXi POBF;
typedef POBF::Index FIndex;
typedef Eigen::Matrix<ExactScalar,Eigen::Dynamic,3> MatrixX3E;
typedef Eigen::Matrix<FIndex,Eigen::Dynamic,1> VectorJ;
typedef Eigen::VectorXi VectorJ;
private:
// Resulting mesh
/// Resulting mesh vertex positions
MatrixX3E m_V;
/// Resulting mesh face indices into V
POBF m_F;
/// Birth index of each face in resulting mesh. Birth index is the index
VectorJ m_J;
// Number of birth faces in A + those in B. I.e. sum of original "leaf"
// faces involved in result.
/// Number of birth faces in A + those in B. I.e. sum of original "leaf"
/// faces involved in result.
size_t m_number_of_birth_faces;
public:
CSGTree()
@ -83,12 +83,11 @@ namespace igl
{
swap(*this,other);
}
// Construct and compute a boolean operation on existing CSGTree nodes.
//
// Inputs:
// A Solid result of previous CSG operation (or identity, see below)
// B Solid result of previous CSG operation (or identity, see below)
// type type of mesh boolean to compute
/// Construct and compute a boolean operation on existing CSGTree nodes.
///
/// @param[in] A Solid result of previous CSG operation (or identity, see below)
/// @param[in] B Solid result of previous CSG operation (or identity, see below)
/// @param[in] type type of mesh boolean to compute
CSGTree(
const CSGTree & A,
const CSGTree & B,
@ -112,7 +111,7 @@ namespace igl
m_number_of_birth_faces =
A.number_of_birth_faces() + B.number_of_birth_faces();
}
// Overload using string for type
/// \overload
CSGTree(
const CSGTree & A,
const CSGTree & B,
@ -121,14 +120,13 @@ namespace igl
{
// do nothing (all done in constructor).
}
// "Leaf" node with identity operation on assumed "solid" mesh (V,F)
//
// Inputs:
// V #V by 3 list of mesh vertices (in any precision, will be
// converted to exact)
// F #F by 3 list of mesh face indices into V
/// "Leaf" node with identity operation on assumed "solid" mesh (V,F)
///
/// @param[in] V #V by 3 list of mesh vertices (in any precision, will be
/// converted to exact)
/// @param[in] F #F by 3 list of mesh face indices into V
template <typename DerivedV>
CSGTree(const Eigen::PlainObjectBase<DerivedV> & V, const POBF & F)//:
CSGTree(const Eigen::MatrixBase<DerivedV> & V, const POBF & F)//:
// Possible Eigen bug:
// https://forum.kde.org/viewtopic.php?f=74&t=128414
//m_V(V.template cast<ExactScalar>()),m_F(F)

View File

@ -14,20 +14,38 @@ namespace igl
{
namespace cgal
{
// Optional Parameters
// DetectOnly Only compute IF, leave VV and FF alone
/// Parameters for SelfIntersectMesh, remesh_self_intersections and
/// remesh_intersections, and intersect_other
///
struct RemeshSelfIntersectionsParam
{
/// avoid constructing intersections results when possible
bool detect_only;
/// return after detecting the first intersection (if first_only==true,
/// then detect_only should also be true)
bool first_only;
/// whether to stitch all resulting constructed elements into a
/// (non-manifold) mesh
bool stitch_all;
/// whether to use slow and more precise rounding (see assign_scalar)
bool slow_and_more_precise_rounding;
/// cutoff parameter for box_self_intersection_d (based on some casual
/// testing 1000 works better than 1,10,100,10000 etc. and better than
/// the recommended √n)
int cutoff;
inline RemeshSelfIntersectionsParam(
bool _detect_only=false,
bool _first_only=false,
bool _stitch_all=false):
bool _stitch_all=false,
bool _slow_and_more_precise_rounding=false,
int _cutoff=1000
):
detect_only(_detect_only),
first_only(_first_only),
stitch_all(_stitch_all){};
stitch_all(_stitch_all),
slow_and_more_precise_rounding(_slow_and_more_precise_rounding),
cutoff(_cutoff)
{};
};
}
}

View File

@ -1,6 +1,6 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
@ -11,6 +11,7 @@
#include "CGAL_includes.hpp"
#include "RemeshSelfIntersectionsParam.h"
#include "../../unique.h"
#include "../../default_num_threads.h"
#include <Eigen/Dense>
#include <list>
@ -18,8 +19,9 @@
#include <vector>
#include <thread>
#include <mutex>
#include <cstdio>
//#define IGL_SELFINTERSECTMESH_DEBUG
//#define IGL_SELFINTERSECTMESH_TIMING
#ifndef IGL_FIRST_HIT_EXCEPTION
#define IGL_FIRST_HIT_EXCEPTION 10
#endif
@ -32,11 +34,12 @@ namespace igl
{
namespace cgal
{
// Kernel is a CGAL kernel like:
// CGAL::Exact_predicates_inexact_constructions_kernel
// or
// CGAL::Exact_predicates_exact_constructions_kernel
/// Class for computing the self-intersections of a mesh
///
/// @tparam Kernel is a CGAL kernel like:
/// CGAL::Exact_predicates_inexact_constructions_kernel
/// or
/// CGAL::Exact_predicates_exact_constructions_kernel
template <
typename Kernel,
typename DerivedV,
@ -48,7 +51,7 @@ namespace igl
typename DerivedIM>
class SelfIntersectMesh
{
typedef
typedef
SelfIntersectMesh<
Kernel,
DerivedV,
@ -61,24 +64,24 @@ namespace igl
public:
// 3D Primitives
typedef CGAL::Point_3<Kernel> Point_3;
typedef CGAL::Segment_3<Kernel> Segment_3;
typedef CGAL::Triangle_3<Kernel> Triangle_3;
typedef CGAL::Segment_3<Kernel> Segment_3;
typedef CGAL::Triangle_3<Kernel> Triangle_3;
typedef CGAL::Plane_3<Kernel> Plane_3;
typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3;
typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3;
// 2D Primitives
typedef CGAL::Point_2<Kernel> Point_2;
typedef CGAL::Segment_2<Kernel> Segment_2;
typedef CGAL::Triangle_2<Kernel> Triangle_2;
typedef CGAL::Segment_2<Kernel> Segment_2;
typedef CGAL::Triangle_2<Kernel> Triangle_2;
// 2D Constrained Delaunay Triangulation types
typedef CGAL::Exact_intersections_tag Itag;
// Axis-align boxes for all-pairs self-intersection detection
typedef std::vector<Triangle_3> Triangles;
typedef typename Triangles::iterator TrianglesIterator;
typedef typename Triangles::const_iterator TrianglesConstIterator;
typedef
CGAL::Box_intersection_d::Box_with_handle_d<double,3,TrianglesIterator>
typedef
CGAL::Box_intersection_d::Box_with_handle_d<double,3,TrianglesIterator>
Box;
// Input mesh
const Eigen::MatrixBase<DerivedV> & V;
const Eigen::MatrixBase<DerivedF> & F;
@ -107,10 +110,20 @@ namespace igl
public:
RemeshSelfIntersectionsParam params;
public:
// Constructs (VV,FF) a new mesh with self-intersections of (V,F)
// subdivided
//
// See also: remesh_self_intersections.h
/// Constructs (VV,FF) a new mesh with self-intersections of (V,F)
/// subdivided
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @param[in] params parameters
/// @param[out] VV #VV by 3 list of vertex positions
/// @param[out] FF #FF by 3 list of triangle indices into VV
/// @param[out] IF #IF by 2 list of edge indices into VV
/// @param[out] J #F list of indices into FF of birth parents
/// @param[out] IM #VV list of indices into V of birth parents
///
///
/// \see remesh_self_intersections.h
inline SelfIntersectMesh(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
@ -121,47 +134,43 @@ namespace igl
Eigen::PlainObjectBase<DerivedJ> & J,
Eigen::PlainObjectBase<DerivedIM> & IM);
private:
// Helper function to mark a face as offensive
//
// Inputs:
// f index of face in F
/// Helper function to mark a face as offensive
///
/// @param[in] f index of face in F
inline void mark_offensive(const Index f);
// Helper function to count intersections between faces
//
// Input:
// fa index of face A in F
// fb index of face B in F
/// Helper function to count intersections between faces
///
/// @param[in] fa index of face A in F
/// @param[in] fb index of face B in F
inline void count_intersection( const Index fa, const Index fb);
// Helper function for box_intersect. Intersect two triangles A and B,
// append the intersection object (point,segment,triangle) to a running
// list for A and B
//
// Inputs:
// A triangle in 3D
// B triangle in 3D
// fa index of A in F (and key into offending)
// fb index of B in F (and key into offending)
// Returns true only if A intersects B
//
/// Helper function for box_intersect. Intersect two triangles A and B,
/// append the intersection object (point,segment,triangle) to a running
/// list for A and B
///
/// @param[in] A triangle in 3D
/// @param[in] B triangle in 3D
/// @param[in] fa index of A in F (and key into offending)
/// @param[in] fb index of B in F (and key into offending)
/// @return true only if A intersects B
///
inline bool intersect(
const Triangle_3 & A,
const Triangle_3 & B,
const Triangle_3 & A,
const Triangle_3 & B,
const Index fa,
const Index fb);
// Helper function for box_intersect. In the case where A and B have
// already been identified to share a vertex, then we only want to
// add possible segment intersections. Assumes truly duplicate
// triangles are not given as input
//
// Inputs:
// A triangle in 3D
// B triangle in 3D
// fa index of A in F (and key into offending)
// fb index of B in F (and key into offending)
// va index of shared vertex in A (and key into offending)
// vb index of shared vertex in B (and key into offending)
// Returns true if intersection (besides shared point)
//
/// Helper function for box_intersect. In the case where A and B have
/// already been identified to share a vertex, then we only want to
/// add possible segment intersections. Assumes truly duplicate
/// triangles are not given as input
///
/// @param[in] A triangle in 3D
/// @param[in] B triangle in 3D
/// @param[in] fa index of A in F (and key into offending)
/// @param[in] fb index of B in F (and key into offending)
/// @param[in] va index of shared vertex in A (and key into offending)
/// @param[in] vb index of shared vertex in B (and key into offending)
/// @return true if intersection (besides shared point)
///
inline bool single_shared_vertex(
const Triangle_3 & A,
const Triangle_3 & B,
@ -169,40 +178,59 @@ namespace igl
const Index fb,
const Index va,
const Index vb);
// Helper handling one direction
//// Helper handling one direction
///
/// @param[in] A triangle in 3D
/// @param[in] B triangle in 3D
/// @param[in] fa index of A in F (and key into offending)
/// @param[in] fb index of B in F (and key into offending)
/// @param[in] va index of shared vertex in A (and key into offending)
/// @return true if intersection (besides shared point)
inline bool single_shared_vertex(
const Triangle_3 & A,
const Triangle_3 & B,
const Index fa,
const Index fb,
const Index va);
// Helper function for box_intersect. In the case where A and B have
// already been identified to share two vertices, then we only want
// to add a possible coplanar (Triangle) intersection. Assumes truly
// degenerate facets are not givin as input.
/// Helper function for box_intersect. In the case where A and B have
/// already been identified to share two vertices, then we only want
/// to add a possible coplanar (Triangle) intersection. Assumes truly
/// degenerate facets are not givin as input.
///
/// @param[in] A triangle in 3D
/// @param[in] B triangle in 3D
/// @param[in] fa index of A in F (and key into offending)
/// @param[in] fb index of B in F (and key into offending)
/// @param[in] shared list of pairs of indices of shared vertices
/// @return true if intersection (besides shared point)
inline bool double_shared_vertex(
const Triangle_3 & A,
const Triangle_3 & B,
const Index fa,
const Index fb,
const std::vector<std::pair<Index,Index> > shared);
public:
// Callback function called during box self intersections test. Means
// boxes a and b intersect. This method then checks if the triangles
// in each box intersect and if so, then processes the intersections
//
// Inputs:
// a box containing a triangle
// b box containing a triangle
/// Callback function called during box self intersections test. Means
/// boxes a and b intersect. This method then checks if the triangles
/// in each box intersect and if so, then processes the intersections
///
/// @param[in] a box containing a triangle
/// @param[in] b box containing a triangle
inline void box_intersect(const Box& a, const Box& b);
/// Process all of the intersecting boxes
inline void process_intersecting_boxes();
public:
// Getters:
//const IndexList& get_lIF() const{ return lIF;}
/// Static function that captures a SelfIntersectMesh instance to pass
/// to cgal.
/// @param[in] SIM pointer to SelfIntersectMesh instance
/// @param[in] a box containing a triangle
/// @param[in] b box containing a triangle
static inline void box_intersect_static(
SelfIntersectMesh * SIM,
const Box &a,
SelfIntersectMesh * SIM,
const Box &a,
const Box &b);
private:
std::mutex m_offending_lock;
@ -216,7 +244,6 @@ namespace igl
#include "mesh_to_cgal_triangle_list.h"
#include "remesh_intersections.h"
#include "../../REDRUM.h"
#include "../../get_seconds.h"
#include "../../C_STR.h"
@ -225,7 +252,6 @@ namespace igl
#include <algorithm>
#include <exception>
#include <cassert>
#include <iostream>
// References:
// http://minregret.googlecode.com/svn/trunk/skyline/src/extern/CGAL-3.3.1/examples/Polyhedron/polyhedron_self_intersection.cpp
@ -245,7 +271,7 @@ namespace igl
// using boost:
// boost::function<void(const Box &a,const Box &b)> cb
// = boost::bind(&::box_intersect, this, _1,_2);
//
//
template <
typename Kernel,
typename DerivedV,
@ -264,8 +290,8 @@ inline void igl::copyleft::cgal::SelfIntersectMesh<
DerivedIF,
DerivedJ,
DerivedIM>::box_intersect_static(
Self * SIM,
const typename Self::Box &a,
Self * SIM,
const typename Self::Box &a,
const typename Self::Box &b)
{
SIM->box_intersect(a,b);
@ -308,7 +334,7 @@ inline igl::copyleft::cgal::SelfIntersectMesh<
using namespace std;
using namespace Eigen;
#ifdef IGL_SELFINTERSECTMESH_DEBUG
#ifdef IGL_SELFINTERSECTMESH_TIMING
const auto & tictoc = []() -> double
{
static double t_start = igl::get_seconds();
@ -317,24 +343,24 @@ inline igl::copyleft::cgal::SelfIntersectMesh<
return diff;
};
const auto log_time = [&](const std::string& label) -> void{
std::cout << "SelfIntersectMesh." << label << ": "
<< tictoc() << std::endl;
std::printf("%50s: %0.5lf\n",
C_STR("SelfIntersectMesh." << label),tictoc());
};
tictoc();
#endif
// Compute and process self intersections
mesh_to_cgal_triangle_list(V,F,T);
#ifdef IGL_SELFINTERSECTMESH_DEBUG
#ifdef IGL_SELFINTERSECTMESH_TIMING
log_time("convert_to_triangle_list");
#endif
// http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Box_intersection_d/Chapter_main.html#Section_63.5
// http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Box_intersection_d/Chapter_main.html#Section_63.5
// Create the corresponding vector of bounding boxes
std::vector<Box> boxes;
boxes.reserve(T.size());
for (
TrianglesIterator tit = T.begin();
tit != T.end();
for (
TrianglesIterator tit = T.begin();
tit != T.end();
++tit)
{
if (!tit->is_degenerate())
@ -343,18 +369,18 @@ inline igl::copyleft::cgal::SelfIntersectMesh<
}
}
// Leapfrog callback
std::function<void(const Box &a,const Box &b)> cb =
std::bind(&box_intersect_static, this,
std::function<void(const Box &a,const Box &b)> cb =
std::bind(&box_intersect_static, this,
// Explicitly use std namespace to avoid confusion with boost (who puts
// _1 etc. in global namespace)
std::placeholders::_1,
std::placeholders::_2);
#ifdef IGL_SELFINTERSECTMESH_DEBUG
#ifdef IGL_SELFINTERSECTMESH_TIMING
log_time("box_and_bind");
#endif
// Run the self intersection algorithm with all defaults
CGAL::box_self_intersection_d(boxes.begin(), boxes.end(),cb);
#ifdef IGL_SELFINTERSECTMESH_DEBUG
// Run the self intersection algorithm with given cutoff size
CGAL::box_self_intersection_d(boxes.begin(), boxes.end(),cb,std::ptrdiff_t(params.cutoff));
#ifdef IGL_SELFINTERSECTMESH_TIMING
log_time("box_intersection_d");
#endif
try{
@ -368,7 +394,7 @@ inline igl::copyleft::cgal::SelfIntersectMesh<
}
// Otherwise just fall through
}
#ifdef IGL_SELFINTERSECTMESH_DEBUG
#ifdef IGL_SELFINTERSECTMESH_TIMING
log_time("resolve_intersection");
#endif
@ -383,13 +409,13 @@ inline igl::copyleft::cgal::SelfIntersectMesh<
)
{
IF(i,0) = (*ifit);
ifit++;
ifit++;
IF(i,1) = (*ifit);
ifit++;
i++;
}
}
#ifdef IGL_SELFINTERSECTMESH_DEBUG
#ifdef IGL_SELFINTERSECTMESH_TIMING
log_time("store_intersecting_face_pairs");
#endif
@ -399,9 +425,10 @@ inline igl::copyleft::cgal::SelfIntersectMesh<
}
remesh_intersections(
V,F,T,offending,params.stitch_all,VV,FF,J,IM);
V,F,T,offending,
params.stitch_all,params.slow_and_more_precise_rounding,VV,FF,J,IM);
#ifdef IGL_SELFINTERSECTMESH_DEBUG
#ifdef IGL_SELFINTERSECTMESH_TIMING
log_time("remesh_intersection");
#endif
}
@ -486,8 +513,8 @@ inline bool igl::copyleft::cgal::SelfIntersectMesh<
DerivedIF,
DerivedJ,
DerivedIM>::intersect(
const Triangle_3 & A,
const Triangle_3 & B,
const Triangle_3 & A,
const Triangle_3 & B,
const Index fa,
const Index fb)
{
@ -501,6 +528,8 @@ inline bool igl::copyleft::cgal::SelfIntersectMesh<
{
// Construct intersection
CGAL::Object result = CGAL::intersection(A,B);
// Could avoid this mutex if `offending` was per-thread and passed as input
// reference.
std::lock_guard<std::mutex> guard(m_offending_lock);
offending[fa].push_back({fb, result});
offending[fb].push_back({fa, result});
@ -600,8 +629,8 @@ inline bool igl::copyleft::cgal::SelfIntersectMesh<
return true;
}else
{
cerr<<REDRUM("Segment ∩ triangle neither point nor segment?")<<endl;
assert(false);
// Should never happen.
assert(false && "Segment ∩ triangle neither point nor segment?");
}
}
@ -710,13 +739,13 @@ inline bool igl::copyleft::cgal::SelfIntersectMesh<
if(CGAL::object_cast<Segment_3 >(&result))
{
// not coplanar
assert(false &&
assert(false &&
"Co-planar non-degenerate triangles should intersect over triangle");
return false;
} else if(CGAL::object_cast<Point_3 >(&result))
{
// this "shouldn't" happen but does for inexact
assert(false &&
assert(false &&
"Co-planar non-degenerate triangles should intersect over triangle");
return false;
} else
@ -740,7 +769,7 @@ inline bool igl::copyleft::cgal::SelfIntersectMesh<
// Expression : is_finite(d)
// File : /opt/local/include/CGAL/GMP/Gmpq_type.h
// Line : 132
// Explanation:
// Explanation:
// But only if NDEBUG is not defined, otherwise there's an uncaught
// "Floating point exception: 8" SIGFPE
return false;
@ -767,7 +796,7 @@ inline void igl::copyleft::cgal::SelfIntersectMesh<
DerivedIF,
DerivedJ,
DerivedIM>::box_intersect(
const Box& a,
const Box& a,
const Box& b)
{
candidate_triangle_pairs.push_back({a.handle(), b.handle()});
@ -792,30 +821,25 @@ inline void igl::copyleft::cgal::SelfIntersectMesh<
DerivedJ,
DerivedIM>::process_intersecting_boxes()
{
std::vector<std::mutex> triangle_locks(T.size());
std::vector<std::mutex> vertex_locks(V.rows());
std::mutex index_lock;
std::mutex exception_mutex;
bool exception_fired = false;
int exception = -1;
auto process_chunk =
[&](
const size_t first,
const size_t last) -> void
// Eventually switching to igl::parallel_for would be good, but currently
// igl::parallel_for does not provide a way to catch exceptions fired on a
// spawned thread _outside_ of its loop-chunk which is the mechanism used here
// to bail out early when `first_only=true` to avoid
// O(#candidate_triangle_pairs) behavior.
auto process_chunk = [&]( const size_t first, const size_t last) -> void
{
try
{
assert(last >= first);
for (size_t i=first; i<last; i++)
for (size_t i=first; i<last; i++)
{
if(exception_fired) return;
Index fa=T.size(), fb=T.size();
{
// Before knowing which triangles are involved, we need to lock
// everything to prevent race condition in updating reference
// counters.
std::lock_guard<std::mutex> guard(index_lock);
const auto& tri_pair = candidate_triangle_pairs[i];
fa = tri_pair.first - T.begin();
fb = tri_pair.second - T.begin();
@ -823,22 +847,6 @@ inline void igl::copyleft::cgal::SelfIntersectMesh<
assert(fa < T.size());
assert(fb < T.size());
// Lock triangles
std::lock_guard<std::mutex> guard_A(triangle_locks[fa]);
std::lock_guard<std::mutex> guard_B(triangle_locks[fb]);
// Lock vertices
std::list<std::lock_guard<std::mutex> > guard_vertices;
{
std::vector<typename DerivedF::Scalar> unique_vertices;
std::vector<size_t> tmp1, tmp2;
igl::unique({F(fa,0), F(fa,1), F(fa,2), F(fb,0), F(fb,1), F(fb,2)},
unique_vertices, tmp1, tmp2);
std::for_each(unique_vertices.begin(), unique_vertices.end(),
[&](const typename DerivedF::Scalar& vi) {
guard_vertices.emplace_back(vertex_locks[vi]);
});
}
if(exception_fired) return;
const Triangle_3& A = T[fa];
@ -867,7 +875,7 @@ inline void igl::copyleft::cgal::SelfIntersectMesh<
}
}
}
const Index total_shared_vertices =
const Index total_shared_vertices =
comb_shared_vertices + geo_shared_vertices;
if(exception_fired) return;
@ -915,25 +923,18 @@ inline void igl::copyleft::cgal::SelfIntersectMesh<
exception = e;
}
};
size_t num_threads=0;
const size_t hardware_limit = std::thread::hardware_concurrency();
if (const char* igl_num_threads = std::getenv("LIBIGL_NUM_THREADS")) {
num_threads = atoi(igl_num_threads);
}
if (num_threads == 0 || num_threads > hardware_limit) {
num_threads = hardware_limit;
}
const size_t num_threads = default_num_threads();
assert(num_threads > 0);
const size_t num_pairs = candidate_triangle_pairs.size();
const size_t chunk_size = num_pairs / num_threads;
std::vector<std::thread> threads;
for (size_t i=0; i<num_threads-1; i++)
for (size_t i=0; i<num_threads-1; i++)
{
threads.emplace_back(process_chunk, i*chunk_size, (i+1)*chunk_size);
}
// Do some work in the master thread.
process_chunk((num_threads-1)*chunk_size, num_pairs);
for (auto& t : threads)
for (auto& t : threads)
{
if (t.joinable()) t.join();
}
@ -941,4 +942,4 @@ inline void igl::copyleft::cgal::SelfIntersectMesh<
//process_chunk(0, candidate_triangle_pairs.size());
}
#endif
#endif

View File

@ -1,46 +1,86 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "assign.h"
#include "../../parallel_for.h"
#include "assign_scalar.h"
#include <type_traits>
namespace igl { namespace copyleft { namespace cgal {
// Would be simpler with C++17 `if constexpr`
template <bool Simple> struct assign_Helper { };
template <> struct assign_Helper<false>
{
template <typename DerivedC, typename DerivedD>
static void run(
const Eigen::MatrixBase<DerivedC> & C,
const bool slow_and_more_precise,
Eigen::PlainObjectBase<DerivedD> & D)
{
D.resizeLike(C);
igl::parallel_for(C.size(),[&](Eigen::Index k)
{
const Eigen::Index i = k%C.rows();
const Eigen::Index j = k/C.rows();
assign_scalar(C(i,j),slow_and_more_precise,D(i,j));
},1000);
}
};
template <> struct assign_Helper<true>
{
template <typename DerivedC, typename DerivedD>
static void run(
const Eigen::MatrixBase<DerivedC> & C,
const bool /*slow_and_more_precise*/,
Eigen::PlainObjectBase<DerivedD> & D)
{
D = C.template cast<typename DerivedD::Scalar>();
}
};
} } }
template <typename DerivedC, typename DerivedD>
IGL_INLINE void igl::copyleft::cgal::assign(
const Eigen::MatrixBase<DerivedC> & C,
const bool slow_and_more_precise,
Eigen::PlainObjectBase<DerivedD> & D)
{
using CScalar = typename DerivedC::Scalar;
using DScalar = typename DerivedD::Scalar;
constexpr bool simple = std::is_assignable<DScalar,CScalar>::value;
assign_Helper<simple>::run(C,slow_and_more_precise,D);
}
template <typename DerivedC, typename DerivedD>
IGL_INLINE void igl::copyleft::cgal::assign(
const Eigen::MatrixBase<DerivedC> & C,
Eigen::PlainObjectBase<DerivedD> & D)
{
D.resizeLike(C);
for(int i = 0;i<C.rows();i++)
{
for(int j = 0;j<C.cols();j++)
{
assign_scalar(C(i,j),D(i,j));
}
}
const bool slow_and_more_precise = false;
return assign(C,slow_and_more_precise,D);
}
template <typename ReturnScalar, typename DerivedC>
IGL_INLINE
IGL_INLINE
Eigen::Matrix<
ReturnScalar,
DerivedC::RowsAtCompileTime,
DerivedC::ColsAtCompileTime,
DerivedC::RowsAtCompileTime,
DerivedC::ColsAtCompileTime,
1,
DerivedC::MaxRowsAtCompileTime,
DerivedC::MaxRowsAtCompileTime,
DerivedC::MaxColsAtCompileTime>
igl::copyleft::cgal::assign(
const Eigen::MatrixBase<DerivedC> & C)
{
Eigen::Matrix<
ReturnScalar,
DerivedC::RowsAtCompileTime,
DerivedC::ColsAtCompileTime,
DerivedC::RowsAtCompileTime,
DerivedC::ColsAtCompileTime,
1,
DerivedC::MaxRowsAtCompileTime,
DerivedC::MaxRowsAtCompileTime,
DerivedC::MaxColsAtCompileTime> D;
assign(C,D);
return D;
@ -49,32 +89,43 @@ igl::copyleft::cgal::assign(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 1, -1, 3> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, 1, -1, 1, 1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>, Eigen::Matrix<double, 8, 3, 0, 8, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 8, 3, 0, 8, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<double, 8, 3, 0, 8, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 8, 3, 0, 8, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&);
#endif

View File

@ -17,10 +17,24 @@ namespace igl
{
namespace cgal
{
/// Vector version of assign_scalar
///
/// @param[in] C matrix of scalars
/// @param[in] slow_and_more_precise see assign_scalar
/// @param[out] D matrix same size as C
///
/// \see assign_scalar
template <typename DerivedC, typename DerivedD>
IGL_INLINE void assign(
const Eigen::MatrixBase<DerivedC> & C,
const bool slow_and_more_precise,
Eigen::PlainObjectBase<DerivedD> & D);
/// \overload
template <typename DerivedC, typename DerivedD>
IGL_INLINE void assign(
const Eigen::MatrixBase<DerivedC> & C,
Eigen::PlainObjectBase<DerivedD> & D);
/// \overload
template <typename ReturnScalar, typename DerivedC>
IGL_INLINE
Eigen::Matrix<

View File

@ -7,6 +7,60 @@
// obtain one at http://mozilla.org/MPL/2.0/.
#include "assign_scalar.h"
#include <cmath>
template <>
IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const CGAL::Epeck::FT & rhs,
const bool & slow_and_more_precise,
double & lhs)
{
if(slow_and_more_precise)
{
return assign_scalar(rhs,lhs);
}else
{
// While this is significantly faster (100x), this does not guarantee that
// two equivalent rationals produce the same double (e.g.,
// CGAL::to_double(⅓) ≠ CGAL::to_double(1-⅔))
// https://github.com/CGAL/cgal/discussions/6000 For remesh_intersections,
// `unique` is called _after_ rounding to floats, avoiding more expensive
// rational equality tests. To operate correctly, we need that a=b ⇒
// double(a)=double(b). Alternatively, we could require that
// remesh_intersections conduct its `unique` operation on rationals. This is
// even more expensive (4x) and most of the time probably overkill, though
// it is argueably more correct in terms of producing the correct topology
// (despite degeneracies that appear during rounding). On the other hand,
// this rounding-before-unique only occurs if the requested output is float,
// so its a question of combinatorial vs geometric degeneracies. Argueably,
// combinatorial degeneracies are more reliably detected.
//
//lhs = CGAL::to_double(rhs);
lhs = CGAL::to_double(rhs.exact());
}
}
template <>
IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const CGAL::Epeck::FT & rhs,
const bool & slow_and_more_precise,
float & lhs)
{
double d;
igl::copyleft::cgal::assign_scalar(rhs,slow_and_more_precise,d);
lhs = float(d);
}
// If we haven't specialized the types then `slow_and_more_precise` doesn't make sense.
template <typename RHS, typename LHS>
IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const RHS & rhs,
const bool & /*slow_and_more_precise*/,
LHS & lhs)
{
return assign_scalar(rhs,lhs);
}
IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const CGAL::Epeck::FT & cgal,
CGAL::Epeck::FT & d)
@ -23,7 +77,7 @@ IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const auto interval = CGAL::to_interval(cgal);
d = interval.first;
do {
const double next = nextafter(d, interval.second);
const double next = std::nextafter(d, interval.second);
if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
d = next;
} while (d < interval.second);
@ -38,7 +92,7 @@ IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const auto interval = CGAL::to_interval(cgal);
d = interval.first;
do {
const float next = nextafter(d, float(interval.second));
const float next = std::nextafter(d, float(interval.second));
if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
d = next;
} while (d < float(interval.second));
@ -79,7 +133,7 @@ IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const auto interval = CGAL::to_interval(cgal);
d = interval.first;
do {
const double next = nextafter(d, interval.second);
const double next = std::nextafter(d, interval.second);
if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
d = next;
} while (d < interval.second);
@ -92,45 +146,19 @@ IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const auto interval = CGAL::to_interval(cgal);
d = interval.first;
do {
const float next = nextafter(d, float(interval.second));
const float next = std::nextafter(d, float(interval.second));
if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
d = next;
} while (d < float(interval.second));
}
#ifndef WIN32
IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
CGAL::Simple_cartesian<mpq_class>::FT & d)
{
d = cgal;
}
IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
double & d)
{
const auto interval = CGAL::to_interval(cgal);
d = interval.first;
do {
const double next = nextafter(d, interval.second);
if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
d = next;
} while (d < interval.second);
}
IGL_INLINE void igl::copyleft::cgal::assign_scalar(
const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
float& d)
{
const auto interval = CGAL::to_interval(cgal);
d = interval.first;
do {
const float next = nextafter(d, float(interval.second));
if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
d = next;
} while (d < float(interval.second));
}
#endif // WIN32
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign_scalar<float, double>(float const&, bool const&, double&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::assign_scalar<float, CGAL::Epeck::FT >(float const&, bool const&, CGAL::Epeck::FT&);
template void igl::copyleft::cgal::assign_scalar<double, double>(double const&, bool const&, double&);
template void igl::copyleft::cgal::assign_scalar<double, CGAL::Epeck::FT >(double const&, bool const&, CGAL::Epeck::FT&);
template void igl::copyleft::cgal::assign_scalar<CGAL::Epeck::FT, CGAL::Epeck::FT >(CGAL::Epeck::FT const&, bool const&, CGAL::Epeck::FT&);
#endif

View File

@ -1,6 +1,7 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
// Copyright (C) 2021 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
@ -10,9 +11,6 @@
#include "../../igl_inline.h"
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h>
#ifndef WIN32
#include <CGAL/gmpxx.h>
#endif
namespace igl
{
@ -20,54 +18,74 @@ namespace igl
{
namespace cgal
{
// Inputs:
// cgal cgal scalar
// Outputs:
// d output scalar
/// Conduct the casting copy:
/// lhs = rhs
/// using `slow_and_more_precise` rounding if more desired.
///
/// @tparam RHS right-hand side scalar type
/// @tparam LHS left-hand side scalar type
/// @param[in] rhs right-hand side scalar
/// @param[in] slow_and_more_precise when appropriate use more elaborate rounding
/// guaranteed to find a closest lhs value in an absolute value sense.
/// Think of `slow_and_more_precise=true` as "round to closest number"
/// and `slow_and_more_precise=false` as "round down/up". CGAL's number
/// types are bit mysterious about how exactly rounding is conducted.
/// For example, the rationals created during remesh_intersections on
/// floating point input appear to be tightly rounded up or down so the
/// difference with the `slow_and_more_precise=true` will be exactly
/// zero 50% of the time and "one floating point unit" (at whatever
/// scale) the other 50% of the time.
/// @param[out] lhs left-hand side scalar
template <typename RHS, typename LHS>
IGL_INLINE void assign_scalar(
const RHS & rhs,
const bool & slow_and_more_precise,
LHS & lhs);
/// \overload
/// \brief For legacy reasons, all of these overload uses
/// `slow_and_more_precise=true`. This is subject to change if we determine
/// it is sufficiently overkill. In that case, we'd create a new
/// non-overloaded function.
IGL_INLINE void assign_scalar(
const CGAL::Epeck::FT & cgal,
CGAL::Epeck::FT & d);
/// \overload
IGL_INLINE void assign_scalar(
const CGAL::Epeck::FT & cgal,
double & d);
/// \overload
IGL_INLINE void assign_scalar(
/// \overload
const CGAL::Epeck::FT & cgal,
float& d);
IGL_INLINE void assign_scalar(
/// \overload
const double & c,
double & d);
/// \overload
IGL_INLINE void assign_scalar(
const float& c,
float & d);
/// \overload
IGL_INLINE void assign_scalar(
const float& c,
double& d);
/// \overload
IGL_INLINE void assign_scalar(
const CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & cgal,
CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & d);
/// \overload
IGL_INLINE void assign_scalar(
const CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & cgal,
double & d);
/// \overload
IGL_INLINE void assign_scalar(
const CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt::FT & cgal,
float& d);
#ifndef WIN32
IGL_INLINE void assign_scalar(
const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
CGAL::Simple_cartesian<mpq_class>::FT & d);
IGL_INLINE void assign_scalar(
const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
double & d);
IGL_INLINE void assign_scalar(
const CGAL::Simple_cartesian<mpq_class>::FT & cgal,
float& d);
#endif // WIN32
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "assign_scalar.cpp"
#endif

View File

@ -11,5 +11,7 @@
#ifdef IGL_STATIC_LIBRARY
#undef IGL_STATIC_LIBRARY
#include "../../barycenter.cpp"
template void igl::barycenter<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&);
// Explicit template instantiation
template void igl::barycenter<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> >&);
template void igl::barycenter<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
#endif

View File

@ -11,7 +11,7 @@
template <typename DerivedC>
IGL_INLINE void igl::copyleft::cgal::cell_adjacency(
const Eigen::PlainObjectBase<DerivedC>& per_patch_cells,
const Eigen::MatrixBase<DerivedC>& per_patch_cells,
const size_t num_cells,
std::vector<std::set<std::tuple<typename DerivedC::Scalar, bool, size_t> > >&
adjacency_list) {
@ -27,8 +27,6 @@ IGL_INLINE void igl::copyleft::cgal::cell_adjacency(
}
#ifdef IGL_STATIC_LIBRARY
template void igl::copyleft::cgal::cell_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, unsigned long, std::vector<std::set<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long>, std::less<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long> >, std::allocator<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long> > >, std::allocator<std::set<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long>, std::less<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long> >, std::allocator<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, unsigned long> > > > >&);
#ifdef WIN32
template void igl::copyleft::cgal::cell_adjacency<class Eigen::Matrix<int, -1, -1, 0, -1, -1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, unsigned __int64, class std::vector<class std::set<class std::tuple<int, bool, unsigned __int64>, struct std::less<class std::tuple<int, bool, unsigned __int64>>, class std::allocator<class std::tuple<int, bool, unsigned __int64>>>, class std::allocator<class std::set<class std::tuple<int, bool, unsigned __int64>, struct std::less<class std::tuple<int, bool, unsigned __int64>>, class std::allocator<class std::tuple<int, bool, unsigned __int64>>>>> &);
#endif
// Explicit template instantiation
template void igl::copyleft::cgal::cell_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, size_t, std::vector<std::set<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, size_t>, std::less<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, size_t> >, std::allocator<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, size_t> > >, std::allocator<std::set<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, size_t>, std::less<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, size_t> >, std::allocator<std::tuple<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, bool, size_t> > > > >&);
#endif

View File

@ -20,23 +20,19 @@ namespace igl
{
namespace cgal
{
// Inputs:
// per_patch_cells #P by 2 list of cell labels on each side of each
// patch. Cell labels are assumed to be continuous
// from 0 to #C.
// num_cells number of cells.
//
// Outputs:
// adjacency_list #C array of list of adjcent cell information. If
// cell i and cell j are adjacent via patch x, where i
// is on the positive side of x, and j is on the
// negative side. Then,
// adjacency_list[i] will contain the entry {j, false, x}
// and
// adjacency_list[j] will contain the entry {i, true, x}
/// Determine adjacency of cells
///
/// @param[in] per_patch_cells #P by 2 list of cell labels on each side
/// of each patch. Cell labels are assumed to be continuous from 0 to #C.
/// @param[in] num_cells number of cells.
/// @param[out] adjacency_list #C array of list of adjcent cell
/// information. If cell i and cell j are adjacent via patch x, where i
/// is on the positive side of x, and j is on the negative side. Then,
/// adjacency_list[i] will contain the entry {j, false, x} and
/// adjacency_list[j] will contain the entry {i, true, x}
template < typename DerivedC >
IGL_INLINE void cell_adjacency(
const Eigen::PlainObjectBase<DerivedC>& per_patch_cells,
const Eigen::MatrixBase<DerivedC>& per_patch_cells,
const size_t num_cells,
std::vector<std::set<std::tuple<typename DerivedC::Scalar, bool, size_t> > >&
adjacency_list);

View File

@ -15,6 +15,7 @@
#include "order_facets_around_edge.h"
#include "submesh_aabb_tree.h"
#include "../../vertex_triangle_adjacency.h"
#include "../../PlainMatrix.h"
#include "../../LinSpaced.h"
//#include "../../writePLY.h"
@ -23,64 +24,20 @@ template<
typename DerivedF,
typename DerivedI,
typename DerivedP,
typename uE2EType,
typename DerivedEMAP,
typename DerivedR,
typename DerivedS >
IGL_INLINE void igl::copyleft::cgal::closest_facet(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedI>& I,
const Eigen::PlainObjectBase<DerivedP>& P,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedS>& S)
{
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Plane_3 Plane_3;
typedef Kernel::Segment_3 Segment_3;
typedef Kernel::Triangle_3 Triangle;
typedef std::vector<Triangle>::iterator Iterator;
typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
if (F.rows() <= 0 || I.rows() <= 0) {
throw std::runtime_error(
"Closest facet cannot be computed on empty mesh.");
}
std::vector<std::vector<size_t> > VF, VFi;
igl::vertex_triangle_adjacency(V.rows(), F, VF, VFi);
std::vector<bool> in_I;
std::vector<Triangle> triangles;
Tree tree;
submesh_aabb_tree(V,F,I,tree,triangles,in_I);
return closest_facet(
V,F,I,P,uE2E,EMAP,VF,VFi,tree,triangles,in_I,R,S);
}
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename DerivedP,
typename uE2EType,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename Kernel,
typename DerivedR,
typename DerivedS >
IGL_INLINE void igl::copyleft::cgal::closest_facet(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedI>& I,
const Eigen::PlainObjectBase<DerivedP>& P,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
const std::vector<std::vector<size_t> > & VF,
const std::vector<std::vector<size_t> > & VFi,
const CGAL::AABB_tree<
@ -103,7 +60,6 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
typedef typename CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
typedef typename CGAL::AABB_tree<AABB_triangle_traits> Tree;
const size_t num_faces = I.rows();
if (F.rows() <= 0 || I.rows() <= 0) {
throw std::runtime_error(
"Closest facet cannot be computed on empty mesh.");
@ -199,17 +155,20 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
corner_idx = 0;
} else
{
std::cerr << "s: " << s << "\t d:" << d << std::endl;
std::cerr << F.row(preferred_facet) << std::endl;
// Should never happen.
//std::cerr << "s: " << s << "\t d:" << d << std::endl;
//std::cerr << F.row(preferred_facet) << std::endl;
throw std::runtime_error(
"Invalid connectivity, edge does not belong to facet");
}
auto ueid = EMAP(preferred_facet + corner_idx * F.rows());
auto eids = uE2E[ueid];
std::vector<size_t> intersected_face_indices;
for (auto eid : eids)
//auto eids = uE2E[ueid];
//for (auto eid : eids)
for(size_t j = uEC(ueid);j<uEC(ueid+1);j++)
{
const size_t eid = uEE(j);
const size_t fid = eid % F.rows();
if (in_I[fid])
{
@ -240,7 +199,7 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
}
Eigen::VectorXi order;
DerivedP pivot = P.row(query_idx).eval();
PlainMatrix<DerivedP,1> pivot = P.row(query_idx).eval();
igl::copyleft::cgal::order_facets_around_edge(V, F, s, d,
intersected_face_signed_indices,
pivot, order);
@ -261,9 +220,11 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
}
};
auto process_face_case = [&](
const size_t query_idx, const Point_3& closest_point,
const size_t fid, bool& orientation) -> size_t {
auto process_face_case = [&F,&I,&process_edge_case](
const size_t query_idx,
const size_t fid,
bool& orientation) -> size_t
{
const auto& f = F.row(I(fid, 0));
return process_edge_case(query_idx, f[0], f[1], I(fid, 0), orientation);
};
@ -285,7 +246,6 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
auto process_vertex_case = [&](
const size_t query_idx,
size_t s,
size_t preferred_facet,
bool& orientation) -> size_t
{
const Point_3 query_point(
@ -341,7 +301,6 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
auto is_on_exterior = [&](const Plane_3& separator) -> bool{
size_t positive=0;
size_t negative=0;
size_t coplanar=0;
for (const auto& point : adj_points) {
switch(separator.oriented_side(point)) {
case CGAL::ON_POSITIVE_SIDE:
@ -351,7 +310,6 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
negative++;
break;
case CGAL::ON_ORIENTED_BOUNDARY:
coplanar++;
break;
default:
throw "Unknown plane-point orientation";
@ -393,16 +351,16 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
}
}
if (d == std::numeric_limits<size_t>::max()) {
Eigen::MatrixXd tmp_vertices(V.rows(), V.cols());
for (size_t i=0; i<V.rows(); i++) {
for (size_t j=0; j<V.cols(); j++) {
tmp_vertices(i,j) = CGAL::to_double(V(i,j));
}
}
Eigen::MatrixXi tmp_faces(adj_faces.size(), 3);
for (size_t i=0; i<adj_faces.size(); i++) {
tmp_faces.row(i) = F.row(adj_faces[i]);
}
//PlainMatrix<DerivedV,Eigen::Dynamic> tmp_vertices(V.rows(), V.cols());
//for (size_t i=0; i<V.rows(); i++) {
// for (size_t j=0; j<V.cols(); j++) {
// tmp_vertices(i,j) = CGAL::to_double(V(i,j));
// }
//}
//PlainMatrix<DerivedF,Eigen::Dynamic,3> tmp_faces(adj_faces.size(), 3);
//for (size_t i=0; i<adj_faces.size(); i++) {
// tmp_faces.row(i) = F.row(adj_faces[i]);
//}
//igl::writePLY("debug.ply", tmp_vertices, tmp_faces, false);
throw std::runtime_error("Invalid vertex neighborhood");
}
@ -442,7 +400,7 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
{
const auto& f = F.row(I(fid, 0));
const size_t s = f[element_index];
fid = process_vertex_case(i, s, I(fid, 0), fid_ori);
fid = process_vertex_case(i, s, fid_ori);
}
break;
case EDGE:
@ -455,7 +413,7 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
break;
case FACE:
{
fid = process_face_case(i, closest_point, fid, fid_ori);
fid = process_face_case(i, fid, fid_ori);
}
break;
default:
@ -471,34 +429,97 @@ IGL_INLINE void igl::copyleft::cgal::closest_facet(
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename DerivedP,
typename uE2EType,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedR,
typename DerivedS >
IGL_INLINE void igl::copyleft::cgal::closest_facet(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedP>& P,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedS>& S)
{
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Triangle_3 Triangle;
typedef std::vector<Triangle>::iterator Iterator;
typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
if (F.rows() <= 0 || I.rows() <= 0) {
throw std::runtime_error(
"Closest facet cannot be computed on empty mesh.");
}
std::vector<std::vector<size_t> > VF, VFi;
igl::vertex_triangle_adjacency(V.rows(), F, VF, VFi);
std::vector<bool> in_I;
std::vector<Triangle> triangles;
Tree tree;
submesh_aabb_tree(V,F,I,tree,triangles,in_I);
return closest_facet(
V,F,I,P,EMAP,uEC,uEE,VF,VFi,tree,triangles,in_I,R,S);
}
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedR,
typename DerivedS >
IGL_INLINE void igl::copyleft::cgal::closest_facet(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedS>& S) {
const size_t num_faces = F.rows();
Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi>(num_faces, 0, num_faces-1);
igl::copyleft::cgal::closest_facet(V, F, I, P, uE2E, EMAP, R, S);
igl::copyleft::cgal::closest_facet(V, F, I, P, EMAP, uEC, uEE, R, S);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> > > > const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> > const&, std::vector<bool, std::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 1, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, std::vector<std::vector<size_t, std::allocator<size_t>>, std::allocator<std::vector<size_t, std::allocator<size_t>>>> const&, std::vector<std::vector<size_t, std::allocator<size_t>>, std::allocator<std::vector<size_t, std::allocator<size_t>>>> const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3>>::iterator, CGAL::Boolean_tag<false>>, CGAL::Default>> const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3>> const&, std::vector<bool, std::allocator<bool>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -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&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> > > > const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> > const&, std::vector<bool, std::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#ifdef WIN32
template void igl::copyleft::cgal::closest_facet<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, unsigned __int64, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class CGAL::Epeck, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class CGAL::AABB_tree<class CGAL::AABB_traits<class CGAL::Epeck, class CGAL::AABB_triangle_primitive<class CGAL::Epeck, class std::_Vector_iterator<class std::_Vector_val<struct std::_Simple_types<class CGAL::Triangle_3<class CGAL::Epeck>>>>, struct CGAL::Boolean_tag<0>>>> const &, class std::vector<class CGAL::Triangle_3<class CGAL::Epeck>, class std::allocator<class CGAL::Triangle_3<class CGAL::Epeck>>> const &, class std::vector<bool, class std::allocator<bool>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::closest_facet<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, unsigned __int64, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class CGAL::Epeck, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class CGAL::AABB_tree<class CGAL::AABB_traits<class CGAL::Epeck, class CGAL::AABB_triangle_primitive<class CGAL::Epeck, class std::_Vector_iterator<class std::_Vector_val<struct std::_Simple_types<class CGAL::Triangle_3<class CGAL::Epeck>>>>, struct CGAL::Boolean_tag<0>>>> const &, class std::vector<class CGAL::Triangle_3<class CGAL::Epeck>, class std::allocator<class CGAL::Triangle_3<class CGAL::Epeck>>> const &, class std::vector<bool, class std::allocator<bool>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::closest_facet<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, 3, 1, -1, 3>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, unsigned __int64, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class CGAL::Epeck, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 1, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class CGAL::AABB_tree<class CGAL::AABB_traits<class CGAL::Epeck, class CGAL::AABB_triangle_primitive<class CGAL::Epeck, class std::_Vector_iterator<class std::_Vector_val<struct std::_Simple_types<class CGAL::Triangle_3<class CGAL::Epeck>>>>, struct CGAL::Boolean_tag<0>>>> const &, class std::vector<class CGAL::Triangle_3<class CGAL::Epeck>, class std::allocator<class CGAL::Triangle_3<class CGAL::Epeck>>> const &, class std::vector<bool, class std::allocator<bool>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
#endif
template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>> const&, std::vector<std::vector<size_t, std::allocator<size_t>>, std::allocator<std::vector<size_t, std::allocator<size_t>>>> const&, std::vector<std::vector<size_t, std::allocator<size_t>>, std::allocator<std::vector<size_t, std::allocator<size_t>>>> const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3>>::iterator, CGAL::Boolean_tag<false>>, CGAL::Default>> const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3>> const&, std::vector<bool, std::allocator<bool>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(
Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&,
Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<size_t, std::allocator<size_t> >, std::allocator<std::vector<size_t, std::allocator<size_t> > > > const&, std::vector<std::vector<size_t, std::allocator<size_t> >, std::allocator<std::vector<size_t, std::allocator<size_t> > > > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> > const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> > const&, std::vector<bool, std::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#include <cstdint>
template void igl::copyleft::cgal::closest_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, CGAL::Epeck, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(
Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&,
Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<size_t, std::allocator<size_t> >, std::allocator<std::vector<size_t, std::allocator<size_t> > > > const&, std::vector<std::vector<size_t, std::allocator<size_t> >, std::allocator<std::vector<size_t, std::allocator<size_t> > > > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epeck, CGAL::AABB_triangle_primitive<CGAL::Epeck, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> > const&, std::vector<CGAL::Epeck::Triangle_3, std::allocator<CGAL::Epeck::Triangle_3> > const&, std::vector<bool, std::allocator<bool> > const&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#endif

View File

@ -25,69 +25,117 @@ namespace igl
{
namespace cgal
{
// Determine the closest facet for each of the input points.
//
// Inputs:
// V #V by 3 array of vertices.
// F #F by 3 array of faces.
// I #I list of triangle indices to consider.
// P #P by 3 array of query points.
//
// Outputs:
// R #P list of closest facet indices.
// S #P list of bools indicating on which side of the closest facet
// each query point lies.
/// Determine the closest facet for each of the input points.
///
/// @param[in] V #V by 3 array of vertices.
/// @param[in] F #F by 3 array of faces.
/// @param[in] I #I list of triangle indices to consider.
/// @param[in] P #P by 3 array of query points.
/// @param[in] EMAP #F*3 list of indices into uE.
/// @param[in] uEC #uE+1 list of cumsums of directed edges sharing each unique edge
/// @param[in] uEE #E list of indices into E (see `igl::unique_edge_map`)
/// @param[in] VF #V list of lists of incident faces (adjacency list)
/// @param[in] VFi #V list of lists of index of incidence within incident faces listed in VF
/// @param[in] tree AABB containing triangles of (V,F(I,:))
/// @param[in] triangles #I list of cgal triangles
/// @param[in] in_I #F list of whether in submesh
/// @param[out] R #P list of closest facet indices.
/// @param[out] S #P list of bools indicating on which side of the closest facet
/// each query point lies.
///
/// \note The use of `size_t` here is a bad idea. These should just be int
/// to avoid nonsense with windows.
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename DerivedP,
typename uE2EType,
typename DerivedEMAP,
typename DerivedR,
typename DerivedS >
IGL_INLINE void closest_facet(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedI>& I,
const Eigen::PlainObjectBase<DerivedP>& P,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedS>& S);
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename uE2EType,
typename DerivedEMAP,
typename DerivedR,
typename DerivedS >
IGL_INLINE void closest_facet(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedP>& P,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedS>& S);
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename DerivedP,
typename uE2EType,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename Kernel,
typename DerivedR,
typename DerivedS >
IGL_INLINE void closest_facet(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedI>& I,
const Eigen::PlainObjectBase<DerivedP>& P,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
const std::vector<std::vector<size_t> > & VF,
const std::vector<std::vector<size_t> > & VFi,
const CGAL::AABB_tree<
CGAL::AABB_traits<
Kernel,
CGAL::AABB_triangle_primitive<
Kernel, typename std::vector<
typename Kernel::Triangle_3 >::iterator > > > & tree,
const std::vector<typename Kernel::Triangle_3 > & triangles,
const std::vector<bool> & in_I,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedS>& S);
/// \overload
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename DerivedP,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedR,
typename DerivedS >
IGL_INLINE void closest_facet(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedS>& S);
/// \overload
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedR,
typename DerivedS >
IGL_INLINE void closest_facet(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedS>& S);
/// \overload
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename DerivedP,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename Kernel,
typename DerivedR,
typename DerivedS >
IGL_INLINE void closest_facet(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
const std::vector<std::vector<size_t> > & VF,
const std::vector<std::vector<size_t> > & VFi,
const CGAL::AABB_tree<

View File

@ -148,5 +148,6 @@ IGL_INLINE bool igl::copyleft::cgal::complex_to_mesh(
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template bool igl::copyleft::cgal::complex_to_mesh<CGAL::Delaunay_triangulation_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_data_structure_3<CGAL::Surface_mesh_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_vertex_base_3<void> > >, CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Surface_mesh_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_cell_base_3<void> > > >, CGAL::Sequential_tag>, CGAL::Default, CGAL::Default>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Complex_2_in_triangulation_3<CGAL::Delaunay_triangulation_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_data_structure_3<CGAL::Surface_mesh_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_vertex_base_3<void> > >, CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Surface_mesh_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_cell_base_3<void> > > >, CGAL::Sequential_tag>, CGAL::Default, CGAL::Default>, void> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#endif

View File

@ -18,18 +18,16 @@ namespace igl
{
namespace cgal
{
// Templates:
// Tr CGAL triangulation type, e.g.
// CGAL::Surface_mesh_default_triangulation_3
// Inputs
// c2t3 2-complex (surface) living in a 3d triangulation (e.g. result of
// CGAL::make_surface_mesh)
// Outputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices
// Returns true iff conversion was successful, failure can ok if CGAL code
// can't figure out ordering.
//
/// Convert a CGAL::Complex_2_in_triangulation_3 to a mesh (V,F)
///
/// @tparam Tr CGAL triangulation type, e.g. CGAL::Surface_mesh_default_triangulation_3
/// @param[in] c2t3 2-complex (surface) living in a 3d triangulation
/// (e.g. result of CGAL::make_surface_mesh)
/// @param[out] V #V by 3 list of vertex positions
/// @param[out] F #F by 3 list of triangle indices
/// @return true iff conversion was successful, failure can ok if CGAL code
/// can't figure out ordering.
///
template <typename Tr, typename DerivedV, typename DerivedF>
IGL_INLINE bool complex_to_mesh(
const CGAL::Complex_2_in_triangulation_3<Tr> & c2t3,

View File

@ -23,12 +23,12 @@
template <typename DerivedV, typename DerivedF, typename DerivedI>
IGL_INLINE bool igl::copyleft::cgal::component_inside_component(
const Eigen::PlainObjectBase<DerivedV>& V1,
const Eigen::PlainObjectBase<DerivedF>& F1,
const Eigen::PlainObjectBase<DerivedI>& I1,
const Eigen::PlainObjectBase<DerivedV>& V2,
const Eigen::PlainObjectBase<DerivedF>& F2,
const Eigen::PlainObjectBase<DerivedI>& I2) {
const Eigen::MatrixBase<DerivedV>& V1,
const Eigen::MatrixBase<DerivedF>& F1,
const Eigen::MatrixBase<DerivedI>& I1,
const Eigen::MatrixBase<DerivedV>& V2,
const Eigen::MatrixBase<DerivedF>& F2,
const Eigen::MatrixBase<DerivedI>& I2) {
if (F1.rows() <= 0 || I1.rows() <= 0 || F2.rows() <= 0 || I2.rows() <= 0) {
throw "Component inside test cannot be done on empty component!";
}
@ -46,10 +46,10 @@ IGL_INLINE bool igl::copyleft::cgal::component_inside_component(
template<typename DerivedV, typename DerivedF>
IGL_INLINE bool igl::copyleft::cgal::component_inside_component(
const Eigen::PlainObjectBase<DerivedV>& V1,
const Eigen::PlainObjectBase<DerivedF>& F1,
const Eigen::PlainObjectBase<DerivedV>& V2,
const Eigen::PlainObjectBase<DerivedF>& F2) {
const Eigen::MatrixBase<DerivedV>& V1,
const Eigen::MatrixBase<DerivedF>& F1,
const Eigen::MatrixBase<DerivedV>& V2,
const Eigen::MatrixBase<DerivedF>& F2) {
if (F1.rows() <= 0 || F2.rows() <= 0) {
throw "Component inside test cannot be done on empty component!";
}
@ -62,22 +62,6 @@ IGL_INLINE bool igl::copyleft::cgal::component_inside_component(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template bool igl::copyleft::cgal::component_inside_component<
Eigen::Matrix<double, -1, -1, 0, -1, -1>,
Eigen::Matrix< int, -1, -1, 0, -1, -1>,
Eigen::Matrix< int, -1, -1, 0, -1, -1> > (
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&,
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&);
template bool igl::copyleft::cgal::component_inside_component<
Eigen::Matrix<double, -1, -1, 0, -1, -1>,
Eigen::Matrix< int, -1, -1, 0, -1, -1> > (
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&);
template bool igl::copyleft::cgal::component_inside_component<Eigen::Matrix<double, -1, -1, 0, -1, -1>,Eigen::Matrix< int, -1, -1, 0, -1, -1>,Eigen::Matrix< int, -1, -1, 0, -1, -1> > (Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&,Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&,Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&,Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&);
template bool igl::copyleft::cgal::component_inside_component<Eigen::Matrix<double, -1, -1, 0, -1, -1>,Eigen::Matrix< int, -1, -1, 0, -1, -1> > (Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&,Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&);
#endif

View File

@ -15,56 +15,37 @@
namespace igl {
namespace copyleft
{
namespace cgal {
// Determine if connected facet component (V1, F1, I1) is inside of
// connected facet component (V2, F2, I2).
//
// Precondition:
// Both components must represent closed, self-intersection free,
// non-degenerated surfaces that are the boundary of 3D volumes. In
// addition, (V1, F1, I1) must not intersect with (V2, F2, I2).
//
// Inputs:
// V1 #V1 by 3 list of vertex position of mesh 1
// F1 #F1 by 3 list of triangles indices into V1
// I1 #I1 list of indices into F1, indicate the facets of component
// V2 #V2 by 3 list of vertex position of mesh 2
// F2 #F2 by 3 list of triangles indices into V2
// I2 #I2 list of indices into F2, indicate the facets of component
//
// Outputs:
// return true iff (V1, F1, I1) is entirely inside of (V2, F2, I2).
template<typename DerivedV, typename DerivedF, typename DerivedI>
IGL_INLINE bool component_inside_component(
const Eigen::PlainObjectBase<DerivedV>& V1,
const Eigen::PlainObjectBase<DerivedF>& F1,
const Eigen::PlainObjectBase<DerivedI>& I1,
const Eigen::PlainObjectBase<DerivedV>& V2,
const Eigen::PlainObjectBase<DerivedF>& F2,
const Eigen::PlainObjectBase<DerivedI>& I2);
// Determine if mesh (V1, F1) is inside of mesh (V2, F2).
//
// Precondition:
// Both meshes must be closed, self-intersection free, non-degenerated
// surfaces that are the boundary of 3D volumes. They should not
// intersect each other.
//
// Inputs:
// V1 #V1 by 3 list of vertex position of mesh 1
// F1 #F1 by 3 list of triangles indices into V1
// V2 #V2 by 3 list of vertex position of mesh 2
// F2 #F2 by 3 list of triangles indices into V2
//
// Outputs:
// return true iff (V1, F1) is entirely inside of (V2, F2).
template<typename DerivedV, typename DerivedF>
IGL_INLINE bool component_inside_component(
const Eigen::PlainObjectBase<DerivedV>& V1,
const Eigen::PlainObjectBase<DerivedF>& F1,
const Eigen::PlainObjectBase<DerivedV>& V2,
const Eigen::PlainObjectBase<DerivedF>& F2);
namespace cgal
{
/// Determine if connected facet component (V1, F1, I1) is inside of
/// connected facet component (V2, F2, I2).
///
/// \pre Both components must represent closed, self-intersection free,
/// non-degenerated surfaces that are the boundary of 3D volumes. In
/// addition, (V1, F1, I1) must not intersect with (V2, F2, I2).
///
/// @param[in] V1 #V1 by 3 list of vertex position of mesh 1
/// @param[in] F1 #F1 by 3 list of triangles indices into V1
/// @param[in] I1 #I1 list of indices into F1, indicate the facets of component
/// @param[in] V2 #V2 by 3 list of vertex position of mesh 2
/// @param[in] F2 #F2 by 3 list of triangles indices into V2
/// @param[in] I2 #I2 list of indices into F2, indicate the facets of component
/// @return true iff (V1, F1, I1) is entirely inside of (V2, F2, I2).
template<typename DerivedV, typename DerivedF, typename DerivedI>
IGL_INLINE bool component_inside_component(
const Eigen::MatrixBase<DerivedV>& V1,
const Eigen::MatrixBase<DerivedF>& F1,
const Eigen::MatrixBase<DerivedI>& I1,
const Eigen::MatrixBase<DerivedV>& V2,
const Eigen::MatrixBase<DerivedF>& F2,
const Eigen::MatrixBase<DerivedI>& I2);
/// \overload
template<typename DerivedV, typename DerivedF>
IGL_INLINE bool component_inside_component(
const Eigen::MatrixBase<DerivedV>& V1,
const Eigen::MatrixBase<DerivedF>& F1,
const Eigen::MatrixBase<DerivedV>& V2,
const Eigen::MatrixBase<DerivedF>& F2);
}
}
}

View File

@ -6,7 +6,7 @@
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "convex_hull.h"
#include "../../ismember.h"
#include "../../ismember_rows.h"
#include "polyhedron_to_mesh.h"
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
@ -24,20 +24,48 @@ IGL_INLINE void igl::copyleft::cgal::convex_hull(
Eigen::PlainObjectBase<DerivedG> & G)
{
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point_3;
//typedef CGAL::Delaunay_triangulation_3<K> Delaunay;
//typedef Delaunay::Vertex_handle Vertex_handle;
//typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
typedef CGAL::Polyhedron_3<K> Polyhedron_3;
std::vector<Point_3> points(V.rows());
for(int i = 0;i<V.rows();i++)
switch(V.cols())
{
points[i] = Point_3(V(i,0),V(i,1),V(i,2));
case 3:
{
typedef K::Point_3 Point_3;
//typedef CGAL::Delaunay_triangulation_3<K> Delaunay;
//typedef Delaunay::Vertex_handle Vertex_handle;
//typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
typedef CGAL::Polyhedron_3<K> Polyhedron_3;
std::vector<Point_3> points(V.rows());
for(int i = 0;i<V.rows();i++)
{
points[i] = Point_3(V(i,0),V(i,1),V(i,2));
}
Polyhedron_3 poly;
CGAL::convex_hull_3(points.begin(),points.end(),poly);
assert(poly.is_pure_triangle() && "Assuming CGAL outputs a triangle mesh");
polyhedron_to_mesh(poly,W,G);
break;
}
case 2:
{
typedef K::Point_2 Point_2;
std::vector<Point_2> points(V.rows());
std::vector<Point_2> result;
for(int i = 0;i<V.rows();i++)
{
points[i] = Point_2(V(i,0),V(i,1));
}
CGAL::convex_hull_2(points.begin(),points.end(),std::back_inserter(result));
W.resize(result.size(),2);
G.resize(result.size(),2);
for(int i = 0;i<result.size();i++)
{
W(i,0) = result[i].x();
W(i,1) = result[i].y();
G(i,0) = i;
G(i,1) = (i+1)%result.size();
}
break;
}
}
Polyhedron_3 poly;
CGAL::convex_hull_3(points.begin(),points.end(),poly);
assert(poly.is_pure_triangle() && "Assuming CGAL outputs a triangle mesh");
polyhedron_to_mesh(poly,W,G);
}
template <
@ -67,6 +95,9 @@ IGL_INLINE void igl::copyleft::cgal::convex_hull(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#endif

View File

@ -16,13 +16,11 @@ namespace igl
{
namespace cgal
{
// Given a set of points (V), compute the convex hull as a triangle mesh (W,G)
//
// Inputs:
// V #V by 3 list of input points
// Outputs:
// W #W by 3 list of convex hull points
// G #G by 3 list of triangle indices into W
/// Given a set of points (V), compute the convex hull as a triangle mesh (W,G)
///
/// @param[in] V #V by 3 list of input points
/// @param[out] W #W by 3 list of convex hull points
/// @param[out] G #G by 3 list of triangle indices into W
template <
typename DerivedV,
typename DerivedW,
@ -31,14 +29,7 @@ namespace igl
const Eigen::MatrixBase<DerivedV> & V,
Eigen::PlainObjectBase<DerivedW> & W,
Eigen::PlainObjectBase<DerivedG> & G);
// Given a set of points (V), compute the convex hull as a triangle mesh (F)
// over input vertex set (V)
//
// Inputs:
// V #V by 3 list of input points
// Outputs:
// F #F by 3 list of triangle indices into V
//
/// \overload
template <
typename DerivedV,
typename DerivedF>

View File

@ -0,0 +1,48 @@
#include "coplanar.h"
#include "row_to_point.h"
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_3.h>
template <typename DerivedV>
IGL_INLINE bool igl::copyleft::cgal::coplanar(
const Eigen::MatrixBase<DerivedV> & V)
{
// 3 points in 3D are always coplanar
if(V.rows() < 4){ return true; }
// spanning points found so far
std::vector<CGAL::Point_3<CGAL::Epick> > p;
for(int i = 0;i<V.rows();i++)
{
const CGAL::Point_3<CGAL::Epick> pi(V(i,0), V(i,1), V(i,2));
switch(p.size())
{
case 0:
p.push_back(pi);
break;
case 1:
if(p[0] != pi)
{
p.push_back(pi);
}
break;
case 2:
if(!CGAL::collinear(p[0],p[1],pi))
{
p.push_back(pi);
}
break;
case 3:
if(!CGAL::coplanar(p[0],p[1],p[2],pi))
{
return false;
}
break;
}
}
return true;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template bool igl::copyleft::cgal::coplanar<Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&);
#endif

View File

@ -0,0 +1,25 @@
#ifndef IGL_COPYLEFT_CGAL_COPLANAR_H
#define IGL_COPYLEFT_CGAL_COPLANAR_H
#include "../../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace copyleft
{
namespace cgal
{
/// Test whether all points are on same plane.
///
/// @param[in] V #V by 3 list of 3D vertex positions
/// @return true if all points lie on the same plane
template <typename DerivedV>
IGL_INLINE bool coplanar(
const Eigen::MatrixBase<DerivedV> & V);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "coplanar.cpp"
#endif
#endif

View File

@ -16,7 +16,7 @@ template<
typename DerivedV,
typename DerivedF>
IGL_INLINE void igl::copyleft::cgal::delaunay_triangulation(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedF>& F)
{
typedef typename DerivedV::Scalar Scalar;
@ -60,3 +60,8 @@ IGL_INLINE void igl::copyleft::cgal::delaunay_triangulation(
// };
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::delaunay_triangulation<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#endif

View File

@ -18,21 +18,17 @@ namespace igl
{
namespace cgal
{
// Given a set of points in 2D, return a Delaunay triangulation of these
// points.
//
// Inputs:
// V #V by 2 list of vertex positions
//
// Outputs:
// F #F by 3 of faces in Delaunay triangulation.
/// Given a set of points in 2D, return a Delaunay triangulation of these
/// points.
///
/// @param[in] V #V by 2 list of vertex positions
/// @param[out] F #F by 3 of faces in Delaunay triangulation.
template<
typename DerivedV,
typename DerivedF
>
IGL_INLINE void delaunay_triangulation(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedF>& F);
}
}

View File

@ -1,21 +1,25 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
//
#include "extract_cells.h"
#include "extract_cells_single_component.h"
#include "closest_facet.h"
#include "order_facets_around_edge.h"
#include "outer_facet.h"
#include "submesh_aabb_tree.h"
#include "../../extract_manifold_patches.h"
#include "../../facet_components.h"
#include "../../IGL_ASSERT.h"
#include "../../parallel_for.h"
#include "../../get_seconds.h"
#include "../../PlainMatrix.h"
#include "../../triangle_triangle_adjacency.h"
#include "../../unique_edge_map.h"
#include "../../C_STR.h"
#include "../../vertex_triangle_adjacency.h"
#include <CGAL/AABB_tree.h>
@ -30,37 +34,42 @@
#include <map>
#include <set>
//#define EXTRACT_CELLS_DEBUG
//#define EXTRACT_CELLS_TIMING
template<
typename DerivedV,
typename DerivedF,
typename DerivedC >
IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
Eigen::PlainObjectBase<DerivedC>& cells)
{
using Index = typename DerivedF::Scalar;
static_assert(
std::is_same<Index, typename DerivedC::Scalar>::value,
"Index type mismatch");
using MatrixXI = Eigen::Matrix<Index, Eigen::Dynamic, Eigen::Dynamic>;
using VectorXI = Eigen::Matrix<Index, Eigen::Dynamic, 1>;
const size_t num_faces = F.rows();
// Construct edge adjacency
Eigen::MatrixXi E, uE;
Eigen::VectorXi EMAP;
std::vector<std::vector<size_t> > uE2E;
igl::unique_edge_map(F, E, uE, EMAP, uE2E);
MatrixXI E, uE;
VectorXI EMAP;
VectorXI uEC,uEE;
igl::unique_edge_map(F, E, uE, EMAP, uEC, uEE);
// Cluster into manifold patches
Eigen::VectorXi P;
igl::extract_manifold_patches(F, EMAP, uE2E, P);
VectorXI P;
igl::extract_manifold_patches(F, EMAP, uEC, uEE, P);
// Extract cells
DerivedC per_patch_cells;
const size_t num_cells =
igl::copyleft::cgal::extract_cells(V,F,P,E,uE,uE2E,EMAP,per_patch_cells);
const size_t ncells = extract_cells(V,F,P,uE,EMAP,uEC,uEE,per_patch_cells);
// Distribute per-patch cell information to each face
cells.resize(num_faces, 2);
for (size_t i=0; i<num_faces; i++)
for (size_t i=0; i<num_faces; i++)
{
cells.row(i) = per_patch_cells.row(P[i]);
}
return num_cells;
return ncells;
}
@ -68,20 +77,20 @@ template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DerivedE,
typename DeriveduE,
typename uE2EType,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedC >
IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::PlainObjectBase<DerivedE>& E,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
Eigen::PlainObjectBase<DerivedC>& cells)
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DeriveduE>& uE,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
Eigen::PlainObjectBase<DerivedC>& cells)
{
// Trivial base case
if(P.size() == 0)
@ -92,16 +101,8 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
}
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Plane_3 Plane_3;
typedef Kernel::Segment_3 Segment_3;
typedef Kernel::Triangle_3 Triangle;
typedef std::vector<Triangle>::iterator Iterator;
typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
#ifdef EXTRACT_CELLS_DEBUG
#ifdef EXTRACT_CELLS_TIMING
const auto & tictoc = []() -> double
{
static double t_start = igl::get_seconds();
@ -110,8 +111,8 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
return diff;
};
const auto log_time = [&](const std::string& label) -> void {
std::cout << "extract_cells." << label << ": "
<< tictoc() << std::endl;
printf("%50s: %0.5lf\n",
C_STR("extract_cells." << label),tictoc());
};
tictoc();
#else
@ -120,18 +121,19 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
#endif
const size_t num_faces = F.rows();
typedef typename DerivedF::Scalar Index;
using VectorXI = Eigen::Matrix<Index, Eigen::Dynamic, 1>;
assert(P.size() > 0);
const size_t num_patches = P.maxCoeff()+1;
// Extract all cells...
DerivedC raw_cells;
const size_t num_raw_cells =
extract_cells_single_component(V,F,P,uE,uE2E,EMAP,raw_cells);
log_time("extract_single_component_cells");
const int num_raw_cells =
extract_cells_single_component(V,F,P,uE,uEC,uEE,raw_cells);
log_time("extract_cells_single_component");
// Compute triangle-triangle adjacency data-structure
std::vector<std::vector<std::vector<Index > > > TT,_1;
igl::triangle_triangle_adjacency(E, EMAP, uE2E, false, TT, _1);
igl::triangle_triangle_adjacency(EMAP, uEC, uEE, false, TT, _1);
log_time("compute_face_adjacency");
// Compute connected components of the mesh
@ -143,7 +145,7 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
// components[c] --> list of face indices into F of faces in component c
std::vector<std::vector<size_t> > components(num_components);
// Loop over all faces
for (size_t i=0; i<num_faces; i++)
for (size_t i=0; i<num_faces; i++)
{
components[C[i]].push_back(i);
}
@ -151,23 +153,27 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
// and precompute data-structures for each component
std::vector<std::vector<size_t> > VF,VFi;
igl::vertex_triangle_adjacency(V.rows(), F, VF, VFi);
std::vector<Eigen::VectorXi> Is(num_components);
std::vector<VectorXI> Is(num_components);
std::vector<
CGAL::AABB_tree<
CGAL::AABB_traits<
Kernel,
Kernel,
CGAL::AABB_triangle_primitive<
Kernel, std::vector<
Kernel::Triangle_3 >::iterator > > > > trees(num_components);
std::vector< std::vector<Kernel::Triangle_3 > >
std::vector< std::vector<Kernel::Triangle_3 > >
triangle_lists(num_components);
// O(num_components * num_faces)
// In general, extract_cells appears to have O(num_components * num_faces)
// performance. This could be painfully tested by a processing a cloud of
// tetrahedra.
std::vector<std::vector<bool> > in_Is(num_components);
// Find outer facets, their orientations and cells for each component
Eigen::VectorXi outer_facets(num_components);
Eigen::VectorXi outer_facet_orientation(num_components);
Eigen::VectorXi outer_cells(num_components);
for (size_t i=0; i<num_components; i++)
VectorXI outer_facets(num_components);
VectorXI outer_facet_orientation(num_components);
VectorXI outer_cells(num_components);
igl::parallel_for(num_components,[&](size_t i)
{
Is[i].resize(components[i].size());
std::copy(components[i].begin(), components[i].end(),Is[i].data());
@ -175,8 +181,8 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
igl::copyleft::cgal::outer_facet(V, F, Is[i], outer_facets[i], flipped);
outer_facet_orientation[i] = flipped?1:0;
outer_cells[i] = raw_cells(P[outer_facets[i]], outer_facet_orientation[i]);
}
#ifdef EXTRACT_CELLS_DEBUG
},1000);
#ifdef EXTRACT_CELLS_TIMING
log_time("outer_facet_per_component");
#endif
@ -185,7 +191,7 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
// Inputs:
// fid index into F
// Returns row-vector of barycenter coordinates
const auto get_triangle_center = [&V,&F](const size_t fid)
const auto get_triangle_center = [&V,&F](const size_t fid)
{
return ((V.row(F(fid,0))+V.row(F(fid,1))+V.row(F(fid,2)))/3.0).eval();
};
@ -193,21 +199,21 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
std::vector<std::vector<size_t> > ambient_cells(num_raw_cells);
std::vector<std::vector<size_t> > ambient_comps(num_components);
// Only bother if there's more than one component
if(num_components > 1)
if(num_components > 1)
{
// construct bounding boxes for each component
DerivedV bbox_min(num_components, 3);
DerivedV bbox_max(num_components, 3);
PlainMatrix<DerivedV,Eigen::Dynamic,3> bbox_min(num_components, 3);
PlainMatrix<DerivedV,Eigen::Dynamic,3> bbox_max(num_components, 3);
// Assuming our mesh (in exact numbers) fits in the range of double.
bbox_min.setConstant(std::numeric_limits<double>::max());
bbox_max.setConstant(std::numeric_limits<double>::min());
bbox_max.setConstant(std::numeric_limits<double>::lowest());
// Loop over faces
for (size_t i=0; i<num_faces; i++)
{
// component of this face
const auto comp_id = C[i];
const auto& f = F.row(i);
for (size_t j=0; j<3; j++)
for (size_t j=0; j<3; j++)
{
for(size_t d=0;d<3;d++)
{
@ -227,7 +233,7 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
bbox_max(cj,1) < bbox_min(ci,1) ||
bbox_max(cj,2) < bbox_min(ci,2));
};
// Loop over components. This section is O(m²)
for (size_t i=0; i<num_components; i++)
{
@ -235,7 +241,7 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
std::vector<size_t> candidate_comps;
candidate_comps.reserve(num_components);
// Loop over components
for (size_t j=0; j<num_components; j++)
for (size_t j=0; j<num_components; j++)
{
if (i == j) continue;
if (bbox_intersects(i,j)) candidate_comps.push_back(j);
@ -248,8 +254,8 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
submesh_aabb_tree(V,F,Is[i],trees[i],triangle_lists[i],in_Is[i]);
// Get query points on each candidate component: barycenter of
// outer-facet
DerivedV queries(num_candidate_comps, 3);
// outer-facet
PlainMatrix<DerivedV,Eigen::Dynamic,3> queries(num_candidate_comps, 3);
for (size_t j=0; j<num_candidate_comps; j++)
{
const size_t index = candidate_comps[j];
@ -263,20 +269,21 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
const auto& in_I = in_Is[i];
const auto& triangles = triangle_lists[i];
Eigen::VectorXi closest_facets, closest_facet_orientations;
VectorXI closest_facets, closest_facet_orientations;
closest_facet(
V,
F,
I,
F,
I,
queries,
uE2E,
EMAP,
EMAP,
uEC,
uEE,
VF,
VFi,
tree,
triangles,
in_I,
closest_facets,
closest_facets,
closest_facet_orientations);
// Loop over all candidates
for (size_t j=0; j<num_candidate_comps; j++)
@ -301,7 +308,7 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
}
}
#ifdef EXTRACT_CELLS_DEBUG
#ifdef EXTRACT_CELLS_TIMING
log_time("nested_relationship");
#endif
@ -325,8 +332,8 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
break;
}
}
assert(embedded_comp != INVALID);
assert(embedded_cell != INVALID);
IGL_ASSERT(embedded_comp != INVALID);
IGL_ASSERT(embedded_cell != INVALID);
embedded_cells[outer_cell] = embedded_cell;
} else {
embedded_cells[outer_cell] = INFINITE_CELL;
@ -369,179 +376,19 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
raw_cells(i, 1) = negative_cell_id;
}
cells = raw_cells;
#ifdef EXTRACT_CELLS_DEBUG
#ifdef EXTRACT_CELLS_TIMING
log_time("finalize");
#endif
return count;
}
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DeriveduE,
typename uE2EType,
typename DerivedEMAP,
typename DerivedC>
IGL_INLINE size_t igl::copyleft::cgal::extract_cells_single_component(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
Eigen::PlainObjectBase<DerivedC>& cells)
{
const size_t num_faces = F.rows();
// Input:
// index index into #F*3 list of undirect edges
// Returns index into face
const auto edge_index_to_face_index = [&num_faces](size_t index)
{
return index % num_faces;
};
// Determine if a face (containing undirected edge {s,d} is consistently
// oriented with directed edge {s,d} (or otherwise it is with {d,s})
//
// Inputs:
// fid face index into F
// s source index of edge
// d destination index of edge
// Returns true if face F(fid,:) is consistent with {s,d}
const auto is_consistent =
[&F](const size_t fid, const size_t s, const size_t d) -> bool
{
if ((size_t)F(fid, 0) == s && (size_t)F(fid, 1) == d) return false;
if ((size_t)F(fid, 1) == s && (size_t)F(fid, 2) == d) return false;
if ((size_t)F(fid, 2) == s && (size_t)F(fid, 0) == d) return false;
if ((size_t)F(fid, 0) == d && (size_t)F(fid, 1) == s) return true;
if ((size_t)F(fid, 1) == d && (size_t)F(fid, 2) == s) return true;
if ((size_t)F(fid, 2) == d && (size_t)F(fid, 0) == s) return true;
throw "Invalid face!";
return false;
};
const size_t num_unique_edges = uE.rows();
const size_t num_patches = P.maxCoeff() + 1;
// Build patch-patch adjacency list.
std::vector<std::map<size_t, size_t> > patch_adj(num_patches);
for (size_t i=0; i<num_unique_edges; i++) {
const size_t s = uE(i,0);
const size_t d = uE(i,1);
const auto adj_faces = uE2E[i];
const size_t num_adj_faces = adj_faces.size();
if (num_adj_faces > 2) {
for (size_t j=0; j<num_adj_faces; j++) {
const size_t patch_j = P[edge_index_to_face_index(adj_faces[j])];
for (size_t k=j+1; k<num_adj_faces; k++) {
const size_t patch_k = P[edge_index_to_face_index(adj_faces[k])];
if (patch_adj[patch_j].find(patch_k) == patch_adj[patch_j].end()) {
patch_adj[patch_j].insert({patch_k, i});
}
if (patch_adj[patch_k].find(patch_j) == patch_adj[patch_k].end()) {
patch_adj[patch_k].insert({patch_j, i});
}
}
}
}
}
const int INVALID = std::numeric_limits<int>::max();
std::vector<size_t> cell_labels(num_patches * 2);
for (size_t i=0; i<num_patches; i++) cell_labels[i] = i;
std::vector<std::set<size_t> > equivalent_cells(num_patches*2);
std::vector<bool> processed(num_unique_edges, false);
size_t label_count=0;
for (size_t i=0; i<num_patches; i++) {
for (const auto& entry : patch_adj[i]) {
const size_t neighbor_patch = entry.first;
const size_t uei = entry.second;
if (processed[uei]) continue;
processed[uei] = true;
const auto& adj_faces = uE2E[uei];
const size_t num_adj_faces = adj_faces.size();
assert(num_adj_faces > 2);
const size_t s = uE(uei,0);
const size_t d = uE(uei,1);
std::vector<int> signed_adj_faces;
for (auto ej : adj_faces)
{
const size_t fid = edge_index_to_face_index(ej);
bool cons = is_consistent(fid, s, d);
signed_adj_faces.push_back((fid+1)*(cons ? 1:-1));
}
{
// Sort adjacent faces cyclically around {s,d}
Eigen::VectorXi order;
// order[f] will reveal the order of face f in signed_adj_faces
order_facets_around_edge(V, F, s, d, signed_adj_faces, order);
for (size_t j=0; j<num_adj_faces; j++) {
const size_t curr_idx = j;
const size_t next_idx = (j+1)%num_adj_faces;
const size_t curr_patch_idx =
P[edge_index_to_face_index(adj_faces[order[curr_idx]])];
const size_t next_patch_idx =
P[edge_index_to_face_index(adj_faces[order[next_idx]])];
const bool curr_cons = signed_adj_faces[order[curr_idx]] > 0;
const bool next_cons = signed_adj_faces[order[next_idx]] > 0;
const size_t curr_cell_idx = curr_patch_idx*2 + (curr_cons?0:1);
const size_t next_cell_idx = next_patch_idx*2 + (next_cons?1:0);
equivalent_cells[curr_cell_idx].insert(next_cell_idx);
equivalent_cells[next_cell_idx].insert(curr_cell_idx);
}
}
}
}
size_t count=0;
cells.resize(num_patches, 2);
cells.setConstant(INVALID);
const auto extract_equivalent_cells = [&](size_t i) {
if (cells(i/2, i%2) != INVALID) return;
std::queue<size_t> Q;
Q.push(i);
cells(i/2, i%2) = count;
while (!Q.empty()) {
const size_t index = Q.front();
Q.pop();
for (const auto j : equivalent_cells[index]) {
if (cells(j/2, j%2) == INVALID) {
cells(j/2, j%2) = count;
Q.push(j);
}
}
}
count++;
};
for (size_t i=0; i<num_patches; i++) {
extract_equivalent_cells(i*2);
extract_equivalent_cells(i*2+1);
}
assert((cells.array() != INVALID).all());
return count;
}
#ifdef IGL_STATIC_LIBRARY
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
// Explicit template instantiation
// generated by autoexplicit.sh
template unsigned long igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -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&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template unsigned long igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -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&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
template unsigned long igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template unsigned long igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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> >&);
template size_t igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template size_t igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template size_t igl::copyleft::cgal::extract_cells<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#ifdef WIN32
template unsigned __int64 igl::copyleft::cgal::extract_cells<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned __int64, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &);
template unsigned __int64 igl::copyleft::cgal::extract_cells<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned __int64, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &);
template unsigned __int64 igl::copyleft::cgal::extract_cells<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, 3, 1, -1, 3>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned __int64, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 1, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &);
#endif
#endif

View File

@ -6,8 +6,8 @@
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
//
#ifndef IGL_COPYLEFT_CGAL_EXTRACT_CELLS
#define IGL_COPYLEFT_CGAL_EXTRACT_CELLS
#ifndef IGL_COPYLEFT_CGAL_EXTRACT_CELLS_H
#define IGL_COPYLEFT_CGAL_EXTRACT_CELLS_H
#include "../../igl_inline.h"
#include <Eigen/Core>
@ -18,93 +18,46 @@ namespace igl {
{
namespace cgal
{
// Extract connected 3D space partitioned by mesh (V, F).
//
// Inputs:
// V #V by 3 array of vertices.
// F #F by 3 array of faces.
//
// Output:
// cells #F by 2 array of cell indices. cells(i,0) represents the
// cell index on the positive side of face i, and cells(i,1)
// represents cell index of the negqtive side.
// By convension cell with index 0 is the infinite cell.
// Returns the number of cells
template<
typename DerivedV,
typename DerivedF,
typename DerivedC >
IGL_INLINE size_t extract_cells(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
Eigen::PlainObjectBase<DerivedC>& cells);
// Extract connected 3D space partitioned by mesh (V, F).
//
// Inputs:
// V #V by 3 array of vertices.
// F #F by 3 array of faces.
// P #F list of patch indices.
// E #E by 2 array of vertex indices, one edge per row.
// uE #uE by 2 list of vertex_indices, represents undirected edges.
// uE2E #uE list of lists that maps uE to E. (a one-to-many map)
// EMAP #F*3 list of indices into uE.
//
// Output:
// cells #P by 2 array of cell indices. cells(i,0) represents the
// cell index on the positive side of patch i, and cells(i,1)
// represents cell index of the negqtive side.
// By convension cell with index 0 is the infinite cell.
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DerivedE,
typename DeriveduE,
typename uE2EType,
typename DerivedEMAP,
typename DerivedC >
IGL_INLINE size_t extract_cells(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::PlainObjectBase<DerivedE>& E,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
Eigen::PlainObjectBase<DerivedC>& cells);
// Extract connected 3D space partitioned by mesh (V,F) composed of
// **possibly multiple components** (the name of this function is
// dubious).
//
// Inputs:
// V #V by 3 array of vertices.
// F #F by 3 array of faces.
// P #F list of patch indices.
// E #E by 2 array of vertex indices, one edge per row.
// uE #uE by 2 list of vertex_indices, represents undirected edges.
// uE2E #uE list of lists that maps uE to E. (a one-to-many map)
// EMAP #F*3 list of indices into uE.
// Output:
// cells #P by 2 array of cell indices. cells(i,0) represents the
// cell index on the positive side of patch i, and cells(i,1)
// represents cell index of the negative side.
/// Extract connected 3D space partitioned by mesh (V, F).
///
/// @param[in] V #V by 3 array of vertices.
/// @param[in] F #F by 3 array of faces.
/// @param[in] P #F list of patch indices.
/// @param[in] uE #uE by 2 list of vertex_indices, represents undirected edges.
/// @param[in] EMAP #F*3 list of indices into uE.
/// @param[in] uEC #uE+1 list of cumsums of directed edges sharing each unique edge
/// @param[in] uEE #E list of indices into E (see `igl::unique_edge_map`)
/// @param[out] cells #F by 2 array of cell indices. cells(i,0) represents the
/// cell index on the positive side of face i, and cells(i,1)
/// represents cell index of the negqtive side.
/// By convension cell with index 0 is the infinite cell.
/// @return the number of cells
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DeriveduE,
typename uE2EType,
typename DerivedEMAP,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedC >
IGL_INLINE size_t extract_cells_single_component(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
IGL_INLINE size_t extract_cells(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DeriveduE>& uE,
const Eigen::MatrixBase<DerivedEMAP>& EMAP,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
Eigen::PlainObjectBase<DerivedC>& cells);
/// \overload
template<
typename DerivedV,
typename DerivedF,
typename DerivedC >
IGL_INLINE size_t extract_cells(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
Eigen::PlainObjectBase<DerivedC>& cells);
}
}

View File

@ -0,0 +1,221 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
//
#include "extract_cells_single_component.h"
#include "order_facets_around_edge.h"
#include "../../C_STR.h"
#include "../../get_seconds.h"
#include <limits>
#include <vector>
#include <set>
#include <map>
#include <queue>
//#define EXTRACT_CELLS_SINGLE_COMPONENT_TIMING
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DeriveduE,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedC>
IGL_INLINE int igl::copyleft::cgal::extract_cells_single_component(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DeriveduE>& uE,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
Eigen::PlainObjectBase<DerivedC>& cells)
{
#ifdef EXTRACT_CELLS_SINGLE_COMPONENT_TIMING
const auto & tictoc = []() -> double
{
static double t_start = igl::get_seconds();
double diff = igl::get_seconds()-t_start;
t_start += diff;
return diff;
};
const auto log_time = [&](const std::string& label) -> void {
printf("%50s: %0.5lf\n",
C_STR("extrac*_single_component." << label),tictoc());
};
tictoc();
#else
// no-op
const auto log_time = [](const std::string){};
#endif
const size_t num_faces = F.rows();
// Input:
// index index into #F*3 list of undirect edges
// Returns index into face
const auto e2f = [&num_faces](size_t index) { return index % num_faces; };
// Determine if a face (containing undirected edge {s,d} is consistently
// oriented with directed edge {s,d} (or otherwise it is with {d,s})
//
// Inputs:
// fid face index into F
// s source index of edge
// d destination index of edge
// Returns true if face F(fid,:) is consistent with {s,d}
const auto is_consistent =
[&F](const size_t fid, const size_t s, const size_t d) -> bool
{
if ((size_t)F(fid, 0) == s && (size_t)F(fid, 1) == d) return false;
if ((size_t)F(fid, 1) == s && (size_t)F(fid, 2) == d) return false;
if ((size_t)F(fid, 2) == s && (size_t)F(fid, 0) == d) return false;
if ((size_t)F(fid, 0) == d && (size_t)F(fid, 1) == s) return true;
if ((size_t)F(fid, 1) == d && (size_t)F(fid, 2) == s) return true;
if ((size_t)F(fid, 2) == d && (size_t)F(fid, 0) == s) return true;
throw "Invalid face!";
return false;
};
const size_t num_unique_edges = uE.rows();
const size_t num_patches = P.maxCoeff() + 1;
// Build patch-patch adjacency list.
//
// Does this really need to be a map? Or do I just want a list of neighbors
// and for each neighbor an index to a unique edge? (i.e., a sparse matrix)
std::vector<std::map<size_t, size_t> > patch_adj(num_patches);
for (size_t i=0; i<num_unique_edges; i++)
{
//const auto adj_faces = uE2E[i];
//const size_t num_adj_faces = adj_faces.size();
const size_t num_adj_faces = uEC(i+1)-uEC(i);
if (num_adj_faces > 2)
{
//for (size_t j=0; j<num_adj_faces; j++) {
// const auto aj = adj_faces[j];
for (size_t ij=uEC(i); ij<uEC(i+1); ij++)
{
const auto aj = uEE(ij);
const size_t patch_j = P[e2f(aj)];
//for (size_t k=j+1; k<num_adj_faces; k++) {
// const auto ak = adj_faces[k];
for (size_t ik=ij+1; ik<uEC(i+1); ik++)
{
const auto ak = uEE(ik);
const size_t patch_k = P[e2f(ak)];
if (patch_adj[patch_j].find(patch_k) == patch_adj[patch_j].end())
{
patch_adj[patch_j].insert({patch_k, i});
}
if (patch_adj[patch_k].find(patch_j) == patch_adj[patch_k].end())
{
patch_adj[patch_k].insert({patch_j, i});
}
}
}
}
}
log_time("patch-adjacency");
const int INVALID = std::numeric_limits<int>::max();
//std::vector<size_t> cell_labels(num_patches * 2);
//for (size_t i=0; i<num_patches; i++) cell_labels[i] = i;
std::vector<std::set<size_t> > equivalent_cells(num_patches*2);
std::vector<bool> processed(num_unique_edges, false);
// bottleneck appears to be `order_facets_around_edge`
for (size_t i=0; i<num_patches; i++)
{
for (const auto& entry : patch_adj[i])
{
const size_t uei = entry.second;
if (processed[uei]) continue;
processed[uei] = true;
//const auto& adj_faces = uE2E[uei];
//const size_t num_adj_faces = adj_faces.size();
const size_t num_adj_faces = uEC(uei+1)-uEC(uei);
assert(num_adj_faces > 2);
const size_t s = uE(uei,0);
const size_t d = uE(uei,1);
std::vector<int> signed_adj_faces;
//for (auto ej : adj_faces)
for(size_t ij = uEC(uei);ij<uEC(uei+1);ij++)
{
const size_t ej = uEE(ij);
const size_t fid = e2f(ej);
bool cons = is_consistent(fid, s, d);
signed_adj_faces.push_back((fid+1)*(cons ? 1:-1));
}
{
// Sort adjacent faces cyclically around {s,d}
Eigen::VectorXi order;
// order[f] will reveal the order of face f in signed_adj_faces
order_facets_around_edge(V, F, s, d, signed_adj_faces, order);
for (size_t j=0; j<num_adj_faces; j++)
{
const size_t curr_idx = j;
const size_t next_idx = (j+1)%num_adj_faces;
//const size_t curr_patch_idx = P[e2f(adj_faces[order[curr_idx]])];
//const size_t next_patch_idx = P[e2f(adj_faces[order[next_idx]])];
const size_t curr_patch_idx = P[e2f( uEE(uEC(uei)+order[curr_idx]) )];
const size_t next_patch_idx = P[e2f( uEE(uEC(uei)+order[next_idx]) )];
const bool curr_cons = signed_adj_faces[order[curr_idx]] > 0;
const bool next_cons = signed_adj_faces[order[next_idx]] > 0;
const size_t curr_cell_idx = curr_patch_idx*2 + (curr_cons?0:1);
const size_t next_cell_idx = next_patch_idx*2 + (next_cons?1:0);
equivalent_cells[curr_cell_idx].insert(next_cell_idx);
equivalent_cells[next_cell_idx].insert(curr_cell_idx);
}
}
}
}
#ifdef EXTRACT_CELLS_SINGLE_COMPONENT_TIMING
log_time("equivalent_cells");
#endif
size_t count=0;
cells.resize(num_patches, 2);
cells.setConstant(INVALID);
const auto extract_equivalent_cells = [&](size_t i) {
if (cells(i/2, i%2) != INVALID) return;
std::queue<size_t> Q;
Q.push(i);
cells(i/2, i%2) = count;
while (!Q.empty()) {
const size_t index = Q.front();
Q.pop();
for (const auto j : equivalent_cells[index]) {
if (cells(j/2, j%2) == INVALID) {
cells(j/2, j%2) = count;
Q.push(j);
}
}
}
count++;
};
for (size_t i=0; i<num_patches; i++) {
extract_equivalent_cells(i*2);
extract_equivalent_cells(i*2+1);
}
log_time("extract-equivalent_cells");
assert((cells.array() != INVALID).all());
return count;
}
#ifdef IGL_STATIC_LIBRARY
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
// Explicit template instantiation
template int igl::copyleft::cgal::extract_cells_single_component<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template int igl::copyleft::cgal::extract_cells_single_component<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#endif

View File

@ -0,0 +1,59 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
//
#ifndef IGL_COPYLEFT_CGAL_EXTRACT_CELLS_SINGLE_COMPONENT_H
#define IGL_COPYLEFT_CGAL_EXTRACT_CELLS_SINGLE_COMPONENT_H
#include "../../igl_inline.h"
#include <Eigen/Core>
#include <vector>
namespace igl {
namespace copyleft
{
namespace cgal
{
/// Extract connected 3D space partitioned by mesh (V,F) composed of
/// **possibly multiple components** (the name of this function is
/// dubious).
///
/// @param[in] V #V by 3 array of vertices.
/// @param[in] F #F by 3 array of faces.
/// @param[in] P #F list of patch indices.
/// @param[in] uE #uE by 2 list of vertex_indices, represents undirected edges.
/// @param[in] uEC #uE+1 list of cumsums of directed edges sharing each unique edge
/// @param[in] uEE #E list of indices into E (see `igl::unique_edge_map`)
/// @param[out] cells #P by 2 array of cell indices. cells(i,0) represents the
/// cell index on the positive side of patch i, and cells(i,1)
/// represents cell index of the negative side.
/// @return number of components
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DeriveduE,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedC >
IGL_INLINE int extract_cells_single_component(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DeriveduE>& uE,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
Eigen::PlainObjectBase<DerivedC>& cells);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "extract_cells_single_component.cpp"
#endif
#endif

View File

@ -7,22 +7,23 @@
// obtain one at http://mozilla.org/MPL/2.0/.
#include "extract_feature.h"
#include <igl/unique_edge_map.h>
#include "../../unique_edge_map.h"
#include "../../PI.h"
#include <CGAL/Kernel/global_functions.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
template<
typename DerivedV,
typename DerivedF,
typename DerivedE >
typename Derivedfeature_edges >
IGL_INLINE void igl::copyleft::cgal::extract_feature(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const double tol,
Eigen::PlainObjectBase<DerivedE>& feature_edges) {
Eigen::PlainObjectBase<Derivedfeature_edges>& feature_edges) {
using IndexType = typename DerivedE::Scalar;
DerivedE E, uE;
using IndexType = typename Derivedfeature_edges::Scalar;
Derivedfeature_edges E, uE;
Eigen::VectorXi EMAP;
std::vector<std::vector<IndexType> > uE2E;
igl::unique_edge_map(F, E, uE, EMAP, uE2E);
@ -33,20 +34,22 @@ IGL_INLINE void igl::copyleft::cgal::extract_feature(
template<
typename DerivedV,
typename DerivedF,
typename DerivedE >
typename DeriveduE,
typename Derivedfeature_edges
>
IGL_INLINE void igl::copyleft::cgal::extract_feature(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const double tol,
const Eigen::PlainObjectBase<DerivedE>& E,
const Eigen::PlainObjectBase<DerivedE>& uE,
const std::vector<std::vector<typename DerivedE::Scalar> >& uE2E,
Eigen::PlainObjectBase<DerivedE>& feature_edges) {
const Eigen::MatrixBase<DeriveduE>& uE,
const std::vector<std::vector<typename DeriveduE::Scalar> >& uE2E,
Eigen::PlainObjectBase<Derivedfeature_edges>& feature_edges)
{
assert(V.cols() == 3);
assert(F.cols() == 3);
using Scalar = typename DerivedV::Scalar;
using IndexType = typename DerivedE::Scalar;
using IndexType = typename DeriveduE::Scalar;
using Vertex = Eigen::Matrix<Scalar, 3, 1>;
using Kernel = typename CGAL::Exact_predicates_exact_constructions_kernel;
using Point = typename Kernel::Point_3;
@ -121,3 +124,7 @@ IGL_INLINE void igl::copyleft::cgal::extract_feature(
feature_edges.row(i) = uE.row(result[i]);
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif

View File

@ -18,68 +18,50 @@ namespace igl
{
namespace cgal
{
// Extract feature edges based on dihedral angle.
// Here, dihedral angle is defined as the angle between surface
// __normals__ as described in
// http://mathworld.wolfram.com/DihedralAngle.html
//
// Non-manifold and boundary edges are automatically considered as
// features.
//
// Inputs:
// V #V by 3 array of vertices.
// F #F by 3 array of faces.
// tol Edges with dihedral angle larger than this are considered
// as features. Angle is measured in radian.
//
// Output:
// feature_edges: #E by 2 array of edges. Each edge satisfies at
// least one of the following criteria:
//
// * Edge has dihedral angle larger than tol.
// * Edge is boundary.
// * Edge is non-manifold (i.e. it has more than 2 adjacent
// faces).
/// Extract feature edges based on dihedral angle.
/// Here, dihedral angle is defined as the angle between surface
/// __normals__ as described in
/// http://mathworld.wolfram.com/DihedralAngle.html
///
/// Non-manifold and boundary edges are automatically considered as
/// features.
///
/// @param[in] V #V by 3 array of vertices.
/// @param[in] F #F by 3 array of faces.
/// @param[in] tol Edges with dihedral angle larger than this are considered
/// as features. Angle is measured in radian.
/// @param[out] feature_edges: #E by 2 array of edges. Each edge satisfies at
/// least one of the following criteria:
/// * Edge has dihedral angle larger than tol.
/// * Edge is boundary.
/// * Edge is non-manifold (i.e. it has more than 2 adjacent
/// faces).
template <
typename DerivedV,
typename DerivedF,
typename DerivedE>
typename Derivedfeature_edges>
IGL_INLINE void extract_feature(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const double tol,
Eigen::PlainObjectBase<DerivedE>& feature_edges);
// Inputs:
// V #V by 3 array of vertices.
// F #F by 3 array of faces.
// tol Edges with dihedral angle larger than this are considered
// as features. Angle is measured in radian.
// E #E by 2 array of directed edges.
// uE #uE by 2 array of undirected edges.
// uE2E #uE list of lists mapping undirected edges to all corresponding
// directed edges.
//
// Output:
// feature_edges: #E by 2 array of edges. Each edge satisfies at
// least one of the following criteria:
//
// * Edge has dihedral angle larger than tol.
// * Edge is boundary.
// * Edge is non-manifold (i.e. it has more than 2 adjacent
// faces).
Eigen::PlainObjectBase<Derivedfeature_edges>& feature_edges);
// \overload
// @param[in] uE #uE by 2 array of undirected edges.
// @param[in] uE2E #uE list of lists mapping undirected edges to all
// corresponding directed edges.
template <
typename DerivedV,
typename DerivedF,
typename DerivedE>
typename DeriveduE,
typename Derivedfeature_edges
>
IGL_INLINE void extract_feature(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const double tol,
const Eigen::PlainObjectBase<DerivedE>& E,
const Eigen::PlainObjectBase<DerivedE>& uE,
const std::vector<std::vector<typename DerivedE::Scalar> >& uE2E,
Eigen::PlainObjectBase<DerivedE>& feature_edges);
const Eigen::MatrixBase<DeriveduE>& uE,
const std::vector<std::vector<typename DeriveduE::Scalar> >& uE2E,
Eigen::PlainObjectBase<Derivedfeature_edges>& feature_edges);
}
}
}

View File

@ -1,3 +1,4 @@
#include "fast_winding_number.h"
#include "../../fast_winding_number.h"
#include "../../octree.h"
#include "../../knn.h"
@ -5,78 +6,58 @@
#include "point_areas.h"
#include <vector>
namespace igl {
namespace copyleft{
namespace cgal{
template <typename DerivedP, typename DerivedN, typename DerivedQ,
typename BetaType, typename DerivedWN>
IGL_INLINE void fast_winding_number(const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DerivedQ>& Q,
const int expansion_order,
const BetaType beta,
Eigen::PlainObjectBase<DerivedWN>& WN
){
typedef typename DerivedWN::Scalar real;
typedef typename Eigen::Matrix<real,Eigen::Dynamic,Eigen::Dynamic>
RealMatrix;
template <
typename DerivedP,
typename DerivedN,
typename DerivedQ,
typename BetaType,
typename DerivedWN>
IGL_INLINE void igl::copyleft::cgal::fast_winding_number(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DerivedQ>& Q,
const int expansion_order,
const BetaType beta,
Eigen::PlainObjectBase<DerivedWN>& WN)
{
typedef typename DerivedWN::Scalar real;
std::vector<std::vector<int> > point_indices;
Eigen::Matrix<int,Eigen::Dynamic,8> CH;
Eigen::Matrix<real,Eigen::Dynamic,3> CN;
Eigen::Matrix<real,Eigen::Dynamic,1> W;
Eigen::MatrixXi I;
Eigen::Matrix<real,Eigen::Dynamic,1> A;
octree(P,point_indices,CH,CN,W);
knn(P,21,point_indices,CH,CN,W,I);
point_areas(P,I,N,A);
Eigen::Matrix<real,Eigen::Dynamic,Eigen::Dynamic> EC;
Eigen::Matrix<real,Eigen::Dynamic,3> CM;
Eigen::Matrix<real,Eigen::Dynamic,1> R;
igl::fast_winding_number(P,N,A,point_indices,CH,
expansion_order,CM,R,EC);
igl::fast_winding_number(P,N,A,point_indices,CH,
CM,R,EC,Q,beta,WN);
}
std::vector<std::vector<int> > point_indices;
Eigen::Matrix<int,Eigen::Dynamic,8> CH;
Eigen::Matrix<real,Eigen::Dynamic,3> CN;
Eigen::Matrix<real,Eigen::Dynamic,1> W;
Eigen::MatrixXi I;
Eigen::Matrix<real,Eigen::Dynamic,1> A;
octree(P,point_indices,CH,CN,W);
knn(P,21,point_indices,CH,CN,W,I);
point_areas(P,I,N,A);
Eigen::Matrix<real,Eigen::Dynamic,Eigen::Dynamic> EC;
Eigen::Matrix<real,Eigen::Dynamic,3> CM;
Eigen::Matrix<real,Eigen::Dynamic,1> R;
igl::fast_winding_number(
P,N,A,point_indices,CH,expansion_order,CM,R,EC);
igl::fast_winding_number(
P,N,A,point_indices,CH,CM,R,EC,Q,beta,WN);
}
template <typename DerivedP, typename DerivedN,
typename DerivedQ, typename DerivedWN>
IGL_INLINE void fast_winding_number(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DerivedQ>& Q,
Eigen::PlainObjectBase<DerivedWN>& WN
){
fast_winding_number(P,N,Q,2,2.0,WN);
}
}
}
template <
typename DerivedP,
typename DerivedN,
typename DerivedQ,
typename DerivedWN>
IGL_INLINE void igl::copyleft::cgal::fast_winding_number(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DerivedQ>& Q,
Eigen::PlainObjectBase<DerivedWN>& WN)
{
fast_winding_number(P,N,Q,2,2.0,WN);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::copyleft::cgal::fast_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, double, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
#endif

View File

@ -5,58 +5,53 @@
#include <vector>
namespace igl
{
// Evaluate the fast winding number for point data, without known areas. The
// areas are calculated using igl::knn and igl::copyleft::cgal::point_areas.
//
// This function performes the precomputation and evaluation all in one.
// If you need to acess the precomuptation for repeated evaluations, use the
// two functions designed for exposed precomputation, which are the first two
// functions see in igl/fast_winding_number.h
//
// Inputs:
// P #P by 3 list of point locations
// N #P by 3 list of point normals
// Q #Q by 3 list of query points for the winding number
// beta This is a Barnes-Hut style accuracy term that separates near feild
// from far field. The higher the beta, the more accurate and slower
// the evaluation. We reccommend using a beta value of 2.
// expansion_order the order of the taylor expansion. We support 0,1,2.
// Outputs:
// WN #Q by 1 list of windinng number values at each query point
//
template <typename DerivedP, typename DerivedN, typename DerivedQ,
typename BetaType, typename DerivedWN>
IGL_INLINE void fast_winding_number(const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DerivedQ>& Q,
const int expansion_order,
const BetaType beta,
Eigen::PlainObjectBase<DerivedWN>& WN
);
// Evaluate the fast winding number for point data, without known areas. The
// areas are calculated using igl::knn and
// igl::point_areas. This function uses the default expansion
// order and beta (both are set to 2).
//
// This function performes the precomputation and evaluation all in one.
// If you need to acess the precomuptation for repeated evaluations, use the
// two functions designed for exposed precomputation (described above).
// Inputs:
// P #P by 3 list of point locations
// N #P by 3 list of point normals
// Q #Q by 3 list of query points for the winding number
// Outputs:
// WN #Q by 1 list of windinng number values at each query point
//
template <typename DerivedP, typename DerivedN, typename DerivedQ,
typename DerivedWN>
IGL_INLINE void fast_winding_number(const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DerivedQ>& Q,
Eigen::PlainObjectBase<DerivedWN>& WN
);
namespace copyleft
{
namespace cgal
{
/// Evaluate the fast winding number for point data, without known areas. The
/// areas are calculated using igl::knn and igl::copyleft::cgal::point_areas.
///
/// This function performes the precomputation and evaluation all in one.
/// If you need to acess the precomuptation for repeated evaluations, use the
/// two functions designed for exposed precomputation, which are the first two
/// functions see in igl/fast_winding_number.h
///
/// @param[in] P #P by 3 list of point locations
/// @param[in] N #P by 3 list of point normals
/// @param[in] Q #Q by 3 list of query points for the winding number
/// @param[in] expansion_order the order of the taylor expansion. We support 0,1,2.
/// @param[in] beta This is a Barnes-Hut style accuracy term that separates near feild
/// from far field. The higher the beta, the more accurate and slower
/// the evaluation. We reccommend using a beta value of 2.
/// @param[out] WN #Q by 1 list of windinng number values at each query point
///
template <
typename DerivedP,
typename DerivedN,
typename DerivedQ,
typename BetaType,
typename DerivedWN>
IGL_INLINE void fast_winding_number(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DerivedQ>& Q,
const int expansion_order,
const BetaType beta,
Eigen::PlainObjectBase<DerivedWN>& WN);
/// \overload
template <
typename DerivedP,
typename DerivedN,
typename DerivedQ,
typename DerivedWN>
IGL_INLINE void fast_winding_number(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DerivedQ>& Q,
Eigen::PlainObjectBase<DerivedWN>& WN);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "fast_winding_number.cpp"

View File

@ -3,41 +3,35 @@
#include <CGAL/Point_3.h>
#include <CGAL/Vector_3.h>
template <typename DerivedV>
template <typename DerivedV, typename Index>
IGL_INLINE void igl::copyleft::cgal::half_space_box(
const CGAL::Plane_3<CGAL::Epeck> & P,
const Eigen::MatrixBase<DerivedV> & V,
Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
Eigen::Matrix<int,12,3> & BF)
Eigen::Matrix<Index,12,3> & BF)
{
typedef CGAL::Plane_3<CGAL::Epeck> Plane;
typedef CGAL::Point_3<CGAL::Epeck> Point;
typedef CGAL::Vector_3<CGAL::Epeck> Vector;
typedef CGAL::Epeck::FT EScalar;
Eigen::Matrix<typename DerivedV::Scalar,1,3> avg(0,0,0);
for(int v = 0;v<V.rows();v++) for(int c = 0;c<V.cols();c++) avg(c) += V(v,c);
avg /= V.rows();
Point o3(avg(0),avg(1),avg(2));
Point o3(V(0,0),V(0,1),V(0,2));
Point o2 = P.projection(o3);
Vector u;
EScalar max_sqrd = -1;
for(int v = 0;v<V.rows();v++)
//https://math.stackexchange.com/a/4112622/35376
const auto copysign = [](const EScalar & a, const EScalar & b)->EScalar
{
Vector v2 = P.projection(Point(V(v,0),V(v,1),V(v,2))) - o2;
const EScalar sqrd = v2.squared_length();
if(max_sqrd<0 || sqrd < max_sqrd)
{
u = v2;
max_sqrd = sqrd;
}
}
// L1 bbd
return (b>=0 ? abs(a) : -abs(a));
};
Vector n = P.orthogonal_vector();
Vector u(
copysign(n.z(),n.x()),
copysign(n.z(),n.y()),
-copysign(n.x(),n.z()) - copysign(n.y(),n.z()));
// L1 of bounding box diagonal. ‖x‖₂ ≤ ‖x‖₁
const EScalar bbd =
(EScalar(V.col(0).maxCoeff())- EScalar(V.col(0).minCoeff())) +
(EScalar(V.col(1).maxCoeff())- EScalar(V.col(1).minCoeff())) +
(EScalar(V.col(2).maxCoeff())- EScalar(V.col(2).minCoeff()));
Vector n = P.orthogonal_vector();
const EScalar bbd_sqr = bbd*bbd;
// now we have a center o2 and a vector u to the farthest point on the plane
std::vector<Point> vBV;vBV.reserve(8);
Vector v = CGAL::cross_product(u,n);
@ -50,9 +44,9 @@ IGL_INLINE void igl::copyleft::cgal::half_space_box(
x = 2.*x;
}
};
longer_than(bbd*bbd,u);
longer_than(bbd*bbd,v);
longer_than(bbd*bbd,n);
longer_than(bbd_sqr,u);
longer_than(bbd_sqr,v);
longer_than(bbd_sqr,n);
vBV.emplace_back( o2 + u + v);
vBV.emplace_back( o2 - u + v);
vBV.emplace_back( o2 - u - v);
@ -84,13 +78,13 @@ IGL_INLINE void igl::copyleft::cgal::half_space_box(
7,0,4;
}
template <typename Derivedp, typename Derivedn, typename DerivedV>
template <typename Derivedp, typename Derivedn, typename DerivedV, typename Index>
IGL_INLINE void igl::copyleft::cgal::half_space_box(
const Eigen::MatrixBase<Derivedp> & p,
const Eigen::MatrixBase<Derivedn> & n,
const Eigen::MatrixBase<DerivedV> & V,
Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
Eigen::Matrix<int,12,3> & BF)
Eigen::Matrix<Index,12,3> & BF)
{
typedef CGAL::Plane_3<CGAL::Epeck> Plane;
typedef CGAL::Point_3<CGAL::Epeck> Point;
@ -99,25 +93,27 @@ IGL_INLINE void igl::copyleft::cgal::half_space_box(
return half_space_box(P,V,BV,BF);
}
template <typename Derivedequ, typename DerivedV>
template <typename Derivedequ, typename DerivedV, typename Index>
IGL_INLINE void igl::copyleft::cgal::half_space_box(
const Eigen::MatrixBase<Derivedequ> & equ,
const Eigen::MatrixBase<DerivedV> & V,
Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
Eigen::Matrix<int,12,3> & BF)
Eigen::Matrix<Index,12,3> & BF)
{
typedef CGAL::Plane_3<CGAL::Epeck> Plane;
Plane P(equ(0),equ(1),equ(2),equ(3));
return half_space_box(P,V,BV,BF);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, -1, 3, 1, -1, 3> >(CGAL::Plane_3<CGAL::Epeck> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, 1, 4, 1, 1, 4>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 4, 1, 1, 4>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, -1, 3, 1, -1, 3>, int>(CGAL::Plane_3<CGAL::Epeck> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<float, -1, 3, 1, -1, 3> >(CGAL::Plane_3<CGAL::Epeck> const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 4, 1, 1, 4>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 4, 1, 1, 4>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 4, 0, -1, 4> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 4, 0, -1, 4> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 4, 1, 1, 4>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<float, -1, 3, 1, -1, 3>, int>(CGAL::Plane_3<CGAL::Epeck> const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<CGAL::Epeck::FT, -1, 4, 0, -1, 4>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 4, 0, -1, 4> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
#endif

View File

@ -11,48 +11,38 @@ namespace igl
{
namespace cgal
{
// Construct a mesh of box (BV,BF) so that it contains the intersection of
// the half-space under the plane (P) and the bounding box of V, and does not
// contain any of the half-space above (P).
//
// Inputs:
// P plane so that normal points away from half-space
// V #V by 3 list of vertex positions
// Outputs:
// BV #BV by 3 list of box vertex positions
// BF #BF b3 list of box triangle indices into BV
template <typename DerivedV>
/// Construct a mesh of box (BV,BF) so that it contains the intersection of
/// the half-space under the plane (P) and the bounding box of V, and does not
/// contain any of the half-space above (P).
///
/// @param[in] P plane so that normal points away from half-space
/// @param[in] V #V by 3 list of vertex positions
/// @param[out] BV #BV by 3 list of box vertex positions
/// @param[out] BF #BF b3 list of box triangle indices into BV
template <typename DerivedV, typename Index>
IGL_INLINE void half_space_box(
const CGAL::Plane_3<CGAL::Epeck> & P,
const Eigen::MatrixBase<DerivedV> & V,
Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
Eigen::Matrix<int,12,3> & BF);
// Inputs:
// p 3d point on plane
// n 3d vector of normal of plane pointing away from inside
// V #V by 3 list of vertex positions
// Outputs:
// BV #BV by 3 list of box vertex positions
// BF #BF b3 list of box triangle indices into BV
template <typename Derivedp, typename Derivedn, typename DerivedV>
Eigen::Matrix<Index,12,3> & BF);
/// \overload
/// @param[in] p 3d point on plane
/// @param[in] n 3d vector of normal of plane pointing away from inside
template <typename Derivedp, typename Derivedn, typename DerivedV, typename Index>
IGL_INLINE void half_space_box(
const Eigen::MatrixBase<Derivedp> & p,
const Eigen::MatrixBase<Derivedn> & n,
const Eigen::MatrixBase<DerivedV> & V,
Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
Eigen::Matrix<int,12,3> & BF);
// Inputs:
// equ plane equation: a*x+b*y+c*z + d = 0
// V #V by 3 list of vertex positions
// Outputs:
// BV #BV by 3 list of box vertex positions
// BF #BF b3 list of box triangle indices into BV
template <typename Derivedequ, typename DerivedV>
Eigen::Matrix<Index,12,3> & BF);
/// \overload
/// @param[in] equ plane equation: a*x+b*y+c*z + d = 0
template <typename Derivedequ, typename DerivedV, typename Index>
IGL_INLINE void half_space_box(
const Eigen::MatrixBase<Derivedequ> & equ,
const Eigen::MatrixBase<DerivedV> & V,
Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
Eigen::Matrix<int,12,3> & BF);
Eigen::Matrix<Index,12,3> & BF);
}
}
}

View File

@ -37,3 +37,9 @@ IGL_INLINE void igl::copyleft::cgal::hausdorff(
};
return igl::hausdorff(V,dist_to_B,l,u);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::hausdorff<Eigen::Matrix<double, -1, -1, 0, -1, -1>, CGAL::Simple_cartesian<double>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > > const&, double&, double&);
#endif

View File

@ -19,20 +19,18 @@ namespace igl
{
namespace cgal
{
// Compute lower and upper bounds (l,u) on the Hausdorff distance between a triangle
// (V) and a pointset (e.g., mesh, triangle soup) given by a distance function
// handle (dist_to_B).
//
// Inputs:
// V 3 by 3 list of corner positions so that V.row(i) is the position of the
// ith corner
// treeB CGAL's AABB tree containing triangle soup (VB,FB)
// TB list of CGAL triangles in order of FB (for determining which was found
// in computation)
// Outputs:
// l lower bound on Hausdorff distance
// u upper bound on Hausdorff distance
//
/// Compute lower and upper bounds (l,u) on the Hausdorff distance between a triangle
/// (V) and a pointset (e.g., mesh, triangle soup) given by a distance function
/// handle (dist_to_B).
///
/// @param[in] V 3 by 3 list of corner positions so that V.row(i) is the position of the
/// ith corner
/// @param[in] treeB CGAL's AABB tree containing triangle soup (VB,FB)
/// @param[in] TB list of CGAL triangles in order of FB (for determining which was found
/// in computation)
/// @param[out] l lower bound on Hausdorff distance
/// @param[out] u upper bound on Hausdorff distance
///
template <
typename DerivedV,
typename Kernel,

View File

@ -1,9 +1,9 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2016 Qingan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "incircle.h"
@ -12,10 +12,10 @@
template<typename Scalar>
IGL_INLINE short igl::copyleft::cgal::incircle(
const Scalar pa[2],
const Scalar pb[2],
const Scalar pc[2],
const Scalar pd[2])
const Scalar *pa,
const Scalar *pb,
const Scalar *pc,
const Scalar *pd)
{
typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick;
@ -37,3 +37,12 @@ IGL_INLINE short igl::copyleft::cgal::incircle(
throw "Invalid incircle result";
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template short igl::copyleft::cgal::incircle<double>(double const*, double const*, double const*, double const*);
#ifdef WIN32
template short igl::copyleft::cgal::incircle<double>(double const * const,double const * const,double const * const,double const * const);
#endif
#endif

View File

@ -1,9 +1,9 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2016 Qingan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_COPYLEFT_CGAL_INCIRCLE_H
@ -17,18 +17,21 @@ namespace igl
{
namespace cgal
{
// Inputs:
// pa,pb,pc,pd 2D points.
// Output:
// 1 if pd is inside of the oriented circle formed by pa,pb,pc.
// 0 if pd is co-circular with pa,pb,pc.
// -1 if pd is outside of the oriented circle formed by pa,pb,pc.
/// Test whether point is in a given circle
///
/// @param[in] pa 2D point on sphere
/// @param[in] pb 2D point on sphere
/// @param[in] pc 2D point on sphere
/// @param[in] pd 2D point to test
/// @return 1 if pd is inside of the oriented circle formed by pa,pb,pc.
/// 0 if pd is co-circular with pa,pb,pc.
/// -1 if pd is outside of the oriented circle formed by pa,pb,pc.
template <typename Scalar>
IGL_INLINE short incircle(
const Scalar pa[2],
const Scalar pb[2],
const Scalar pc[2],
const Scalar pd[2]);
const Scalar *pa,
const Scalar *pb,
const Scalar *pc,
const Scalar *pd);
}
}
}

View File

@ -61,8 +61,8 @@ IGL_INLINE void igl::copyleft::cgal::insert_into_cdt(
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
// Explicit template instantiation
template void igl::copyleft::cgal::insert_into_cdt<CGAL::Epick>(CGAL::Object const&, CGAL::Plane_3<CGAL::Epick> const&, CGAL::Constrained_triangulation_plus_2<CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epick, CGAL::Triangulation_data_structure_2<CGAL::Triangulation_vertex_base_2<CGAL::Epick, CGAL::Triangulation_ds_vertex_base_2<void> >, CGAL::Constrained_triangulation_face_base_2<CGAL::Epick, CGAL::Triangulation_face_base_2<CGAL::Epick, CGAL::Triangulation_ds_face_base_2<void> > > >, CGAL::Exact_intersections_tag> >&);
template void igl::copyleft::cgal::insert_into_cdt<CGAL::Epeck>(CGAL::Object const&, CGAL::Plane_3<CGAL::Epeck> const&, CGAL::Constrained_triangulation_plus_2<CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epeck, CGAL::Triangulation_data_structure_2<CGAL::Triangulation_vertex_base_2<CGAL::Epeck, CGAL::Triangulation_ds_vertex_base_2<void> >, CGAL::Constrained_triangulation_face_base_2<CGAL::Epeck, CGAL::Triangulation_face_base_2<CGAL::Epeck, CGAL::Triangulation_ds_face_base_2<void> > > >, CGAL::Exact_intersections_tag> >&);
#endif

View File

@ -20,21 +20,19 @@ namespace igl
{
namespace cgal
{
// Given a current 2D constrained Delaunay triangulation (cdt), insert a
// 3D "object" (e.g., resulting from intersecting two triangles) into the
// cdt, by projecting it via the given plane (P) and adding appropriate
// constraints.
//
// Inputs:
// obj CGAL::Object representing a vertex, segment, or (convex)
// polygon. All vertices should lie on the plane P. If not, then this
// adds the _projection_ of this object to the cdt and that might not
// be what you wanted to do.
// P plane obj lies on and upon which the cdt is being performed
// cdt current CDT, see output
// Outputs:
// cdt CDT updated to contain constraints for the given object
//
/// Given a current 2D constrained Delaunay triangulation (cdt), insert a
/// 3D "object" (e.g., resulting from intersecting two triangles) into the
/// cdt, by projecting it via the given plane (P) and adding appropriate
/// constraints.
///
/// @param[in] obj CGAL::Object representing a vertex, segment, or (convex)
/// polygon. All vertices should lie on the plane P. If not, then this
/// adds the _projection_ of this object to the cdt and that might not
/// be what you wanted to do.
/// @param[in] P plane obj lies on and upon which the cdt is being performed
/// @param[in] cdt current CDT, see output
/// @param[out] cdt CDT updated to contain constraints for the given object
///
template <typename Kernel>
IGL_INLINE void insert_into_cdt(
const CGAL::Object & obj,

View File

@ -17,12 +17,17 @@ namespace igl
{
namespace cgal
{
// Inputs:
// pa,pb,pc,pd,pe 3D points.
// Output:
// 1 if pe is inside of the oriented sphere formed by pa,pb,pc,pd.
// 0 if pe is co-spherical with pa,pb,pc,pd.
// -1 if pe is outside of the oriented sphere formed by pa,pb,pc,pd.
/// Test whether point is in a given sphere.
///
/// @param[in] pa 3D point on sphere
/// @param[in] pb 3D point on sphere
/// @param[in] pc 3D point on sphere
/// @param[in] pd 3D point on sphere
/// @param[in] pe 3D point to test
/// @return 1 if pe is inside of the oriented sphere formed by pa,pb,pc,pd,
/// 0 if pe is co-spherical with pa,pb,pc,pd,
/// -1 if pe is outside of the oriented sphere formed by pa,pb,pc,pd.
///
template <typename Scalar>
IGL_INLINE short insphere(
const Scalar pa[3],

View File

@ -9,8 +9,8 @@
#include "CGAL_includes.hpp"
#include "mesh_to_cgal_triangle_list.h"
#include "remesh_intersections.h"
#include "../../slice_mask.h"
#include "../../remove_unreferenced.h"
#include "../../PlainMatrix.h"
#ifndef IGL_FIRST_HIT_EXCEPTION
#define IGL_FIRST_HIT_EXCEPTION 10
@ -23,33 +23,23 @@ namespace igl
{
namespace cgal
{
template <typename DerivedF>
template <typename Index>
static IGL_INLINE void push_result(
const Eigen::PlainObjectBase<DerivedF> & F,
const int f,
const int f_other,
const CGAL::Object & result,
std::map<
typename DerivedF::Index,
std::vector<std::pair<typename DerivedF::Index, CGAL::Object> > > &
Index,
std::vector<std::pair<Index, CGAL::Object> > > &
offending)
//std::map<
// std::pair<typename DerivedF::Index,typename DerivedF::Index>,
// std::vector<typename DerivedF::Index> > & edge2faces)
{
typedef typename DerivedF::Index Index;
typedef std::pair<Index,Index> EMK;
if(offending.count(f) == 0)
{
// first time marking, initialize with new id and empty list
offending[f] = {};
for(Index e = 0; e<3;e++)
{
// append face to edge's list
Index i = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+1)%3) : F(f,(e+2)%3);
Index j = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+2)%3) : F(f,(e+1)%3);
//edge2faces[EMK(i,j)].push_back(f);
}
}
offending[f].push_back({f_other,result});
}
@ -65,10 +55,10 @@ namespace igl
typename DerivedJAB,
typename DerivedIMAB>
static IGL_INLINE bool intersect_other_helper(
const Eigen::PlainObjectBase<DerivedVA> & VA,
const Eigen::PlainObjectBase<DerivedFA> & FA,
const Eigen::PlainObjectBase<DerivedVB> & VB,
const Eigen::PlainObjectBase<DerivedFB> & FB,
const Eigen::MatrixBase<DerivedVA> & VA,
const Eigen::MatrixBase<DerivedFA> & FA,
const Eigen::MatrixBase<DerivedVB> & VB,
const Eigen::MatrixBase<DerivedFB> & FB,
const RemeshSelfIntersectionsParam & params,
Eigen::PlainObjectBase<DerivedIF> & IF,
Eigen::PlainObjectBase<DerivedVVAB> & VVAB,
@ -81,33 +71,16 @@ namespace igl
using namespace Eigen;
typedef typename DerivedFA::Index Index;
// 3D Primitives
typedef CGAL::Point_3<Kernel> Point_3;
typedef CGAL::Segment_3<Kernel> Segment_3;
typedef CGAL::Triangle_3<Kernel> Triangle_3;
typedef CGAL::Plane_3<Kernel> Plane_3;
typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3;
// 2D Primitives
typedef CGAL::Point_2<Kernel> Point_2;
typedef CGAL::Segment_2<Kernel> Segment_2;
typedef CGAL::Triangle_2<Kernel> Triangle_2;
// 2D Constrained Delaunay Triangulation types
typedef CGAL::Triangulation_vertex_base_2<Kernel> TVB_2;
typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTAB_2;
typedef CGAL::Triangulation_data_structure_2<TVB_2,CTAB_2> TDS_2;
typedef CGAL::Exact_intersections_tag Itag;
// Axis-align boxes for all-pairs self-intersection detection
//// Axis-align boxes for all-pairs self-intersection detection
typedef std::vector<Triangle_3> Triangles;
typedef typename Triangles::iterator TrianglesIterator;
typedef typename Triangles::const_iterator TrianglesConstIterator;
typedef
CGAL::Box_intersection_d::Box_with_handle_d<double,3,TrianglesIterator>
Box;
typedef
std::map<Index,std::vector<std::pair<Index,CGAL::Object> > >
OffendingMap;
typedef std::map<std::pair<Index,Index>,std::vector<Index> > EdgeMap;
typedef std::pair<Index,Index> EMK;
Triangles TA,TB;
// Compute and process self intersections
@ -154,8 +127,8 @@ namespace igl
{
CGAL::Object result = CGAL::intersection(A,B);
push_result(FA,fa,fb,result,offendingA);
push_result(FB,fb,fa,result,offendingB);
push_result(fa,fb,result,offendingA);
push_result(fb,fa,result,offendingB);
}
}
};
@ -163,7 +136,8 @@ namespace igl
CGAL::box_intersection_d(
A_boxes.begin(), A_boxes.end(),
B_boxes.begin(), B_boxes.end(),
cb);
cb,
std::ptrdiff_t(params.cutoff));
}catch(int e)
{
// Rethrow if not FIRST_HIT_EXCEPTION
@ -197,9 +171,9 @@ namespace igl
// remesh_intersections(VA,FA,TA,offendingA,VVA,FFA,JA,IMA);
// remesh_intersections(VB,FB,TB,offendingB,VVB,FFB,JB,IMB);
// Combine mesh and offending maps
DerivedVA VAB(VA.rows()+VB.rows(),3);
PlainMatrix<DerivedVA,Eigen::Dynamic> VAB(VA.rows()+VB.rows(),3);
VAB<<VA,VB;
DerivedFA FAB(FA.rows()+FB.rows(),3);
PlainMatrix<DerivedFA,Eigen::Dynamic> FAB(FA.rows()+FB.rows(),3);
FAB<<FA,(FB.array()+VA.rows());
Triangles TAB;
TAB.reserve(TA.size()+TB.size());
@ -224,7 +198,9 @@ namespace igl
}
remesh_intersections(
VAB,FAB,TAB,offending,params.stitch_all,VVAB,FFAB,JAB,IMAB);
VAB,FAB,TAB,offending,
params.stitch_all,params.slow_and_more_precise_rounding,
VVAB,FFAB,JAB,IMAB);
}
return IF.rows() > 0;
@ -244,10 +220,10 @@ template <
typename DerivedJAB,
typename DerivedIMAB>
IGL_INLINE bool igl::copyleft::cgal::intersect_other(
const Eigen::PlainObjectBase<DerivedVA> & VA,
const Eigen::PlainObjectBase<DerivedFA> & FA,
const Eigen::PlainObjectBase<DerivedVB> & VB,
const Eigen::PlainObjectBase<DerivedFB> & FB,
const Eigen::MatrixBase<DerivedVA> & VA,
const Eigen::MatrixBase<DerivedFA> & FA,
const Eigen::MatrixBase<DerivedVB> & VB,
const Eigen::MatrixBase<DerivedFB> & FB,
const RemeshSelfIntersectionsParam & params,
Eigen::PlainObjectBase<DerivedIF> & IF,
Eigen::PlainObjectBase<DerivedVVAB> & VVAB,
@ -255,7 +231,12 @@ IGL_INLINE bool igl::copyleft::cgal::intersect_other(
Eigen::PlainObjectBase<DerivedJAB> & JAB,
Eigen::PlainObjectBase<DerivedIMAB> & IMAB)
{
if(params.detect_only)
typedef typename DerivedVA::Scalar VAScalar;
typedef typename DerivedVB::Scalar VBScalar;
if(params.detect_only && ! (
std::is_same<VAScalar,CGAL::Epeck::FT>::value ||
std::is_same<VBScalar,CGAL::Epeck::FT>::value
))
{
return intersect_other_helper<CGAL::Epick>
(VA,FA,VB,FB,params,IF,VVAB,FFAB,JAB,IMAB);
@ -266,24 +247,47 @@ IGL_INLINE bool igl::copyleft::cgal::intersect_other(
}
}
template <
typename DerivedVA,
typename DerivedFA,
typename DerivedVB,
typename DerivedFB,
typename DerivedIF>
IGL_INLINE bool igl::copyleft::cgal::intersect_other(
const Eigen::MatrixXd & VA,
const Eigen::MatrixXi & FA,
const Eigen::MatrixXd & VB,
const Eigen::MatrixXi & FB,
const Eigen::MatrixBase<DerivedVA> & VA,
const Eigen::MatrixBase<DerivedFA> & FA,
const Eigen::MatrixBase<DerivedVB> & VB,
const Eigen::MatrixBase<DerivedFB> & FB,
const bool first_only,
Eigen::MatrixXi & IF)
Eigen::PlainObjectBase<DerivedIF> & IF)
{
Eigen::MatrixXd VVAB;
Eigen::MatrixXi FFAB;
Eigen::VectorXi JAB,IMAB;
PlainMatrix<DerivedVA,Eigen::Dynamic> VVAB;
PlainMatrix<DerivedFA,Eigen::Dynamic> FFAB;
Eigen::VectorXi JAB, IMAB;
return intersect_other(
VA,FA,VB,FB,{true,first_only},IF,VVAB,FFAB,JAB,IMAB);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::intersect_other<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>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::intersect_other<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::intersect_other<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>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(
Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,
Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::intersect_other<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(
Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&,
Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,
Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&,
Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#endif

View File

@ -18,25 +18,23 @@ namespace igl
{
namespace cgal
{
// INTERSECT_OTHER Given a triangle mesh (VA,FA) and another mesh (VB,FB)
// find all pairs of intersecting faces. Note that self-intersections are
// ignored.
//
// Inputs:
// VA #V by 3 list of vertex positions
// FA #F by 3 list of triangle indices into VA
// VB #V by 3 list of vertex positions
// FB #F by 3 list of triangle indices into VB
// params whether to detect only and then whether to only find first
// intersection
// Outputs:
// IF #intersecting face pairs by 2 list of intersecting face pairs,
// indexing FA and FB
// VVAB #VVAB by 3 list of vertex positions
// FFAB #FFAB by 3 list of triangle indices into VVA
// JAB #FFAB list of indices into [FA;FB] denoting birth triangle
// IMAB #VVAB list of indices stitching duplicates (resulting from
// mesh intersections) together
/// Given a triangle mesh (VA,FA) and another mesh (VB,FB) find all pairs
/// of intersecting faces. Note that self-intersections are ignored.
///
/// @param[in] VA #V by 3 list of vertex positions
/// @param[in] FA #F by 3 list of triangle indices into VA
/// @param[in] VB #V by 3 list of vertex positions
/// @param[in] FB #F by 3 list of triangle indices into VB
/// @param[in] params whether to detect only and then whether to only
/// find first intersection
/// @param[out] IF #intersecting face pairs by 2 list of intersecting
/// face pairs, indexing FA and FB
/// @param[out] VVAB #VVAB by 3 list of vertex positions
/// @param[out] FFAB #FFAB by 3 list of triangle indices into VVA
/// @param[out] JAB #FFAB list of indices into [FA;FB] denoting birth triangle
/// @param[out] IMAB #VVAB list of indices stitching duplicates
/// (resulting from mesh intersections) together
/// @return true on success
template <
typename DerivedVA,
typename DerivedFA,
@ -48,37 +46,31 @@ namespace igl
typename DerivedJAB,
typename DerivedIMAB>
IGL_INLINE bool intersect_other(
const Eigen::PlainObjectBase<DerivedVA> & VA,
const Eigen::PlainObjectBase<DerivedFA> & FA,
const Eigen::PlainObjectBase<DerivedVB> & VB,
const Eigen::PlainObjectBase<DerivedFB> & FB,
const Eigen::MatrixBase<DerivedVA> & VA,
const Eigen::MatrixBase<DerivedFA> & FA,
const Eigen::MatrixBase<DerivedVB> & VB,
const Eigen::MatrixBase<DerivedFB> & FB,
const RemeshSelfIntersectionsParam & params,
Eigen::PlainObjectBase<DerivedIF> & IF,
Eigen::PlainObjectBase<DerivedVVAB> & VVAB,
Eigen::PlainObjectBase<DerivedFFAB> & FFAB,
Eigen::PlainObjectBase<DerivedJAB> & JAB,
Eigen::PlainObjectBase<DerivedIMAB> & IMAB);
// Legacy wrapper for detect only using common types.
//
// Inputs:
// VA #V by 3 list of vertex positions
// FA #F by 3 list of triangle indices into VA
// VB #V by 3 list of vertex positions
// FB #F by 3 list of triangle indices into VB
// first_only whether to only detect the first intersection.
// Outputs:
// IF #intersecting face pairs by 2 list of intersecting face pairs,
// indexing FA and FB
// Returns true if any intersections were found
//
// See also: remesh_self_intersections
/// \overload
/// @param[in] first_only whether to only find first intersection
template <
typename DerivedVA,
typename DerivedFA,
typename DerivedVB,
typename DerivedFB,
typename DerivedIF>
IGL_INLINE bool intersect_other(
const Eigen::MatrixXd & VA,
const Eigen::MatrixXi & FA,
const Eigen::MatrixXd & VB,
const Eigen::MatrixXi & FB,
const Eigen::MatrixBase<DerivedVA> & VA,
const Eigen::MatrixBase<DerivedFA> & FA,
const Eigen::MatrixBase<DerivedVB> & VB,
const Eigen::MatrixBase<DerivedFB> & FB,
const bool first_only,
Eigen::MatrixXi & IF);
Eigen::PlainObjectBase<DerivedIF> & IF);
}
}
}

View File

@ -61,7 +61,7 @@ IGL_INLINE bool igl::copyleft::cgal::intersect_with_half_space(
Eigen::PlainObjectBase<DerivedJ > & J)
{
Eigen::Matrix<CGAL::Epeck::FT,8,3> BV;
Eigen::Matrix<int,12,3> BF;
Eigen::Matrix<typename DerivedF::Scalar,12,3> BF;
half_space_box(P,V,BV,BF);
// Disturbingly, (BV,BF) must be first argument
const bool ret = mesh_boolean(BV,BF,V,F,MESH_BOOLEAN_TYPE_INTERSECT,VC,FC,J);
@ -77,12 +77,8 @@ IGL_INLINE bool igl::copyleft::cgal::intersect_with_half_space(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<double>, Eigen::Matrix<double, 1, 3, 1, 1, 3> const>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<double>, Eigen::Matrix<double, 1, 3, 1, 1, 3> const> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<float>, Eigen::Matrix<float, 1, 3, 1, 1, 3> const>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<float>, Eigen::Matrix<float, 1, 3, 1, 1, 3> const> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<double>, Eigen::Matrix<double, 1, 3, 1, 1, 3> const>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<double>, Eigen::Matrix<double, 1, 3, 1, 1, 3> const> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::intersect_with_half_space<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<float>, Eigen::Matrix<float, 1, 3, 1, 1, 3> const>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<float>, Eigen::Matrix<float, 1, 3, 1, 1, 3> const> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#endif

View File

@ -11,18 +11,17 @@ namespace igl
{
namespace cgal
{
// Intersect a PWN mesh with a half-space. Point on plane, normal pointing
// outward.
//
// Inputs:
// V #V by 3 list of mesh vertex positions
// p 3d point on plane
// n 3d vector of normal of plane pointing away from inside
// Outputs:
// VC #VC by 3 list of vertex positions of boolean result mesh
// FC #FC by 3 list of triangle indices into VC
// J #FC list of indices into [F;F.rows()+[1;2]] revealing "birth"
// facet
/// Intersect a PWN mesh with a half-space. Point on plane, normal pointing
/// outward.
///
/// @param[in] V #V by 3 list of mesh vertex positions
/// @param[in] p 3d point on plane
/// @param[in] n 3d vector of normal of plane pointing away from inside
/// @param[out] VC #VC by 3 list of vertex positions of boolean result mesh
/// @param[out] FC #FC by 3 list of triangle indices into VC
/// @param[out] J #FC list of indices into [F;F.rows()+[1;2]] revealing
/// "birth" facet
/// @return true if mesh_boolean was succsesful
template <
typename DerivedV,
typename DerivedF,
@ -39,16 +38,9 @@ namespace igl
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J);
// Intersect a PWN mesh with a half-space. Plane equation.
//
// Inputs:
// V #V by 3 list of mesh vertex positions
// equ plane equation: P(x,y,z) = a*x+b*y+c*z + d = 0, P(x,y,z) < 0 is
// _inside_.
// Outputs:
// VC #VC by 3 list of vertex positions of boolean result mesh
// FC #FC by 3 list of triangle indices into VC
// J #FC list of indices into [F;F.rows()+[1;2]] revealing "birth" facet
/// \overload
/// @param[in] equ plane equation: P(x,y,z) = a*x+b*y+c*z + d = 0,
/// P(x,y,z) < 0 is _inside_.
template <
typename DerivedV,
typename DerivedF,
@ -63,15 +55,8 @@ namespace igl
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J);
// Intersect a PWN mesh with a half-space. CGAL Plane.
//
// Inputs:
// V #V by 3 list of mesh vertex positions
// P plane
// Outputs:
// VC #VC by 3 list of vertex positions of boolean result mesh
// FC #FC by 3 list of triangle indices into VC
// J #FC list of indices into [F;F.rows()+[1;2]] revealing "birth" facet
/// \overload
/// @param[in] P plane
template <
typename DerivedV,
typename DerivedF,

View File

@ -0,0 +1,64 @@
#include "is_self_intersecting.h"
#include "../../placeholders.h"
#include "../../find.h"
#include "../../doublearea.h"
#include "../../remove_unreferenced.h"
#include "RemeshSelfIntersectionsParam.h"
#include "remesh_self_intersections.h"
#include "../../collapse_edge.h"
template <
typename DerivedV,
typename DerivedF>
bool igl::copyleft::cgal::is_self_intersecting(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F)
{
assert(V.cols() == 3);
assert(F.cols() == 3);
using MatrixV = Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 3>;
using MatrixF = Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, 3>;
const auto valid =
igl::find((F.array() != IGL_COLLAPSE_EDGE_NULL).rowwise().any().eval());
// Extract only the valid faces
MatrixF FF = F(valid, igl::placeholders::all);
// Remove unreferneced vertices
MatrixV VV;
{
Eigen::VectorXi I;
igl::remove_unreferenced(V,MatrixF(FF),VV,FF,I);
}
Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,1> A;
igl::doublearea(VV,FF,A);
if(A.minCoeff() <= 0)
{
return true;
}
if(
(FF.array().col(0) == FF.array().col(1)).any() ||
(FF.array().col(1) == FF.array().col(2)).any() ||
(FF.array().col(2) == FF.array().col(0)).any())
{
return true;
}
// check for self-intersections VV,FF
igl::copyleft::cgal::RemeshSelfIntersectionsParam params;
params.detect_only = true;
params.first_only = true;
Eigen::MatrixXi IF;
Eigen::VectorXi J,IM;
{
MatrixV tempV;
MatrixF tempF;
igl::copyleft::cgal::remesh_self_intersections(
V,F,params,tempV,tempF,IF,J,IM);
}
return IF.rows() > 0;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template specialization
template bool igl::copyleft::cgal::is_self_intersecting<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
#endif

View File

@ -0,0 +1,36 @@
#ifndef IGL_COPYLEFT_CGAL_IS_SELF_INTERSECTING_H
#define IGL_COPYLEFT_CGAL_IS_SELF_INTERSECTING_H
#include "../../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace copyleft
{
namespace cgal
{
/// Determine if a mesh has _any_ self-intersections. Skips any
/// `(IGL_COLLAPSE_EDGE_NULL,IGL_COLLAPSE_EDGE_NULL,IGL_COLLAPSE_EDGE_NULL)`
/// faces and returns true if any faces have zero area.
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @return true if any faces intersect
///
/// \see remesh_self_intersections, SelfIntersectMesh
template <
typename DerivedV,
typename DerivedF>
bool is_self_intersecting(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "is_self_intersecting.cpp"
#endif
#endif

View File

@ -16,7 +16,7 @@ template<
typename DerivedF
>
IGL_INLINE void igl::copyleft::cgal::lexicographic_triangulation(
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedP>& P,
Eigen::PlainObjectBase<DerivedF>& F)
{
typedef typename DerivedP::Scalar Scalar;

View File

@ -18,21 +18,17 @@ namespace igl
{
namespace cgal
{
// Given a set of points in 2D, return a lexicographic triangulation of these
// points.
//
// Inputs:
// P #P by 2 list of vertex positions
//
// Outputs:
// F #F by 3 of faces in lexicographic triangulation.
/// Given a set of points in 2D, return a lexicographic triangulation of these
/// points.
///
/// @param[in] P #P by 2 list of vertex positions
/// @param[out] F #F by 3 of faces in lexicographic triangulation.
template<
typename DerivedP,
typename DerivedF
>
IGL_INLINE void lexicographic_triangulation(
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedP>& P,
Eigen::PlainObjectBase<DerivedF>& F);
}
}

View File

@ -11,5 +11,5 @@
#ifdef IGL_STATIC_LIBRARY
#undef IGL_STATIC_LIBRARY
#include "../../list_to_matrix.cpp"
template bool igl::list_to_matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >(std::vector<std::vector<CGAL::Lazy_exact_nt<CGAL::Gmpq>, std::allocator<CGAL::Lazy_exact_nt<CGAL::Gmpq> > >, std::allocator<std::vector<CGAL::Lazy_exact_nt<CGAL::Gmpq>, std::allocator<CGAL::Lazy_exact_nt<CGAL::Gmpq> > > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&);
template bool igl::list_to_matrix<CGAL::Epeck::FT, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >(std::vector<std::vector<CGAL::Epeck::FT, std::allocator<CGAL::Epeck::FT > >, std::allocator<std::vector<CGAL::Epeck::FT, std::allocator<CGAL::Epeck::FT > > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&);
#endif

View File

@ -8,7 +8,7 @@
// obtain one at http://mozilla.org/MPL/2.0/.
//
#include "mesh_boolean.h"
#include "assign.h"
#include "assign_scalar.h"
#include "extract_cells.h"
#include "mesh_boolean_type_to_funcs.h"
#include "propagate_winding_numbers.h"
@ -16,14 +16,17 @@
#include "remesh_self_intersections.h"
#include "string_to_mesh_boolean_type.h"
#include "../../combine.h"
#include "../../PlainVector.h"
#include "../../PlainMatrix.h"
#include "../../cumsum.h"
#include "../../extract_manifold_patches.h"
#include "../../get_seconds.h"
#include "../../parallel_for.h"
#include "../../remove_unreferenced.h"
#include "../../resolve_duplicated_faces.h"
#include "../../slice.h"
#include "../../unique_edge_map.h"
#include "../../unique_simplices.h"
#include "../../C_STR.h"
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <algorithm>
@ -104,7 +107,7 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
// implies that VA must have the trumping precision (and a valid assignment
// operator from VB's type).
Eigen::Matrix<typename DerivedVA::Scalar,Eigen::Dynamic,3> VV(VA.rows() + VB.rows(), 3);
DerivedFC FF(FA.rows() + FB.rows(), 3);
Eigen::Matrix<typename DerivedFA::Scalar,Eigen::Dynamic,3> FF(FA.rows() + FB.rows(), 3);
// Can't use comma initializer
for(int a = 0;a<VA.rows();a++)
{
@ -138,8 +141,8 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J)
{
DerivedV VV;
DerivedF FF;
PlainMatrix<DerivedV,Eigen::Dynamic> VV;
PlainMatrix<DerivedF,Eigen::Dynamic> FF;
Eigen::Matrix<size_t,Eigen::Dynamic,1> Vsizes,Fsizes;
igl::combine(Vlist,Flist,VV,FF,Vsizes,Fsizes);
return mesh_boolean(VV,FF,Fsizes,wind_num_op,keep,VC,FC,J);
@ -159,8 +162,8 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J)
{
DerivedV VV;
DerivedF FF;
PlainMatrix<DerivedV,Eigen::Dynamic> VV;
PlainMatrix<DerivedF,Eigen::Dynamic> FF;
Eigen::Matrix<size_t,Eigen::Dynamic,1> Vsizes,Fsizes;
igl::combine(Vlist,Flist,VV,FF,Vsizes,Fsizes);
std::function<int(const int, const int)> keep;
@ -195,15 +198,13 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
return diff;
};
const auto log_time = [&](const std::string& label) -> void {
std::cout << "mesh_boolean." << label << ": "
<< tictoc() << std::endl;
printf("%50s: %0.5lf\n",
C_STR("mesh_boolean." << label),tictoc());
};
tictoc();
#endif
typedef typename DerivedVC::Scalar Scalar;
typedef CGAL::Epeck Kernel;
typedef Kernel::FT ExactScalar;
typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3> MatrixX3S;
typedef Eigen::Matrix<typename DerivedJ::Scalar,Eigen::Dynamic,1> VectorXJ;
typedef Eigen::Matrix<
ExactScalar,
@ -214,35 +215,23 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
DerivedFC F;
VectorXJ CJ;
{
Eigen::VectorXi I;
igl::copyleft::cgal::RemeshSelfIntersectionsParam params;
params.stitch_all = true;
MatrixXES Vr;
DerivedFC Fr;
Eigen::MatrixXi IF;
igl::copyleft::cgal::remesh_self_intersections(
VV, FF, params, Vr, Fr, IF, CJ, I);
assert(I.size() == Vr.rows());
// Merge coinciding vertices into non-manifold vertices.
std::for_each(Fr.data(), Fr.data()+Fr.size(),
[&I](typename DerivedFC::Scalar& a) { a=I[a]; });
// Remove unreferenced vertices.
Eigen::VectorXi UIM;
igl::remove_unreferenced(Vr, Fr, V, F, UIM);
}
remesh_self_intersections(VV,FF,params,V,F,IF,CJ);
}
#ifdef MESH_BOOLEAN_TIMING
log_time("resolve_self_intersection");
#endif
// Compute edges of (F) --> (E,uE,EMAP,uE2E)
Eigen::MatrixXi E, uE;
Eigen::VectorXi EMAP;
std::vector<std::vector<size_t> > uE2E;
igl::unique_edge_map(F, E, uE, EMAP, uE2E);
Eigen::VectorXi EMAP, uEC, uEE;
igl::unique_edge_map(F, E, uE, EMAP, uEC, uEE);
// Compute patches (F,EMAP,uE2E) --> (P)
// Compute patches (F,EMAP,uEC,uEE) --> (P)
Eigen::VectorXi P;
const size_t num_patches = igl::extract_manifold_patches(F, EMAP, uE2E, P);
const size_t num_patches = igl::extract_manifold_patches(F,EMAP,uEC,uEE,P);
#ifdef MESH_BOOLEAN_TIMING
log_time("patch_extraction");
#endif
@ -250,8 +239,7 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
// Compute cells (V,F,P,E,uE,EMAP) -> (per_patch_cells)
Eigen::MatrixXi per_patch_cells;
const size_t num_cells =
igl::copyleft::cgal::extract_cells(
V, F, P, E, uE, uE2E, EMAP, per_patch_cells);
extract_cells( V, F, P, uE, EMAP, uEC, uEE, per_patch_cells);
#ifdef MESH_BOOLEAN_TIMING
log_time("cell_extraction");
#endif
@ -266,7 +254,7 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
// labels(f) = i means that face f comes from mesh i
Eigen::VectorXi labels(num_faces);
// cumulative sizes
Derivedsizes cumsizes;
PlainVector<Derivedsizes,Eigen::Dynamic> cumsizes;
igl::cumsum(sizes,1,cumsizes);
const size_t num_inputs = sizes.size();
std::transform(
@ -286,9 +274,8 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
bool valid = true;
if (num_faces > 0)
{
valid = valid &
igl::copyleft::cgal::propagate_winding_numbers(
V, F, uE, uE2E, num_patches, P, num_cells, per_patch_cells, labels, W);
valid = valid && propagate_winding_numbers(
V,F,uE,uEC,uEE,num_patches,P,num_cells,per_patch_cells,labels,W);
} else
{
W.resize(0, 2*num_inputs);
@ -374,7 +361,7 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
DerivedFC G;
DerivedJ JJ;
igl::resolve_duplicated_faces(kept_faces, G, JJ);
igl::slice(kept_face_indices, JJ, 1, J);
J = kept_face_indices(JJ);
#ifdef DOUBLE_CHECK_EXACT_OUTPUT
{
@ -401,10 +388,25 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
}
#endif
MatrixX3S Vs;
assign(V,Vs);
Eigen::VectorXi newIM;
igl::remove_unreferenced(Vs,G,VC,FC,newIM);
// `assign` _after_ removing unreferenced vertices
{
Eigen::VectorXi I,J;
igl::remove_unreferenced(V.rows(),G,I,J);
FC = G;
std::for_each(FC.data(),FC.data()+FC.size(),
[&I](typename DerivedFC::Scalar & a){a=I(a);});
const bool slow_and_more_precise = false;
VC.resize(J.size(),3);
igl::parallel_for(J.size(),[&](Eigen::Index i)
{
for(Eigen::Index c = 0;c<3;c++)
{
assign_scalar(V(J(i),c),slow_and_more_precise,VC(i,c));
}
},1000);
}
}
#ifdef MESH_BOOLEAN_TIMING
log_time("clean_up");
@ -428,39 +430,19 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC)
{
Eigen::Matrix<typename DerivedFC::Index, Eigen::Dynamic,1> J;
Eigen::Matrix<typename DerivedFC::Scalar, Eigen::Dynamic,1> J;
return igl::copyleft::cgal::mesh_boolean(VA,FA,VB,FB,type,VC,FC,J);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 4, 0, -1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 4, 0, -1, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<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>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<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>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<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>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template bool igl::copyleft::cgal::mesh_boolean<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>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3>, 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>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<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>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template bool igl::copyleft::cgal::mesh_boolean<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>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, std::function<int (Eigen::Matrix<int, 1, -1, 1, 1, -1>)> const&, std::function<int (int, int)> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<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>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template bool igl::copyleft::cgal::mesh_boolean<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>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#ifdef WIN32
template bool igl::copyleft::cgal::mesh_boolean<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::MatrixBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::MatrixBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, enum igl::MeshBooleanType const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
#endif
#endif

View File

@ -22,24 +22,21 @@ namespace igl
{
namespace cgal
{
// MESH_BOOLEAN Compute boolean csg operations on "solid", consistently
// oriented meshes.
//
// Inputs:
// VA #VA by 3 list of vertex positions of first mesh
// FA #FA by 3 list of triangle indices into VA
// VB #VB by 3 list of vertex positions of second mesh
// FB #FB by 3 list of triangle indices into VB
// type type of boolean operation
// Outputs:
// VC #VC by 3 list of vertex positions of boolean result mesh
// FC #FC by 3 list of triangle indices into VC
// J #FC list of indices into [FA;FA.rows()+FB] revealing "birth" facet
// Returns true if inputs induce a piecewise constant winding number
// field and type is valid
//
// See also: mesh_boolean_cork, intersect_other,
// remesh_self_intersections
/// Compute Boolean csg operations on "solid", consistently oriented
/// meshes.
///
/// @param[in] VA #VA by 3 list of vertex positions of first mesh
/// @param[in] FA #FA by 3 list of triangle indices into VA
/// @param[in] VB #VB by 3 list of vertex positions of second mesh
/// @param[in] FB #FB by 3 list of triangle indices into VB
/// @param[in] type type of boolean operation
/// @param[out] VC #VC by 3 list of vertex positions of boolean result mesh
/// @param[out] FC #FC by 3 list of triangle indices into VC
/// @param[out] J #FC list of indices into [FA;FA.rows()+FB] revealing "birth" facet
/// @return true if inputs induce a piecewise constant winding number
/// field and type is valid
///
/// \see mesh_boolean_cork, intersect_other, remesh_self_intersections
template <
typename DerivedVA,
typename DerivedFA,
@ -57,6 +54,8 @@ namespace igl
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J);
/// \overload
/// @param[in] type_str string describing type of boolean operation see mesh_boolean_type_to_funcs
template <
typename DerivedVA,
typename DerivedFA,
@ -74,25 +73,12 @@ namespace igl
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J);
//
// Inputs:
// VA #VA by 3 list of vertex positions of first mesh
// FA #FA by 3 list of triangle indices into VA
// VB #VB by 3 list of vertex positions of second mesh
// FB #FB by 3 list of triangle indices into VB
// wind_num_op function handle for filtering winding numbers from
// tuples of integer values to [0,1] outside/inside values
// keep function handle for determining if a patch should be "kept"
// in the output based on the winding number on either side
// Outputs:
// VC #VC by 3 list of vertex positions of boolean result mesh
// FC #FC by 3 list of triangle indices into VC
// J #FC list of indices into [FA;FB] revealing "birth" facet
// Returns true iff inputs induce a piecewise constant winding number
// field
//
// See also: mesh_boolean_cork, intersect_other,
// remesh_self_intersections
/// \overload
///
/// @param[in] wind_num_op function handle for filtering winding numbers from
/// tuples of integer values to [0,1] outside/inside values
/// @param[in] keep function handle for determining if a patch should be "kept"
/// in the output based on the winding number on either side
template <
typename DerivedVA,
typename DerivedFA,
@ -111,26 +97,21 @@ namespace igl
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J);
// MESH_BOOLEAN Variadic boolean operations
//
// Inputs:
// Vlist k-long list of lists of mesh vertex positions
// Flist k-long list of lists of mesh face indices, so that Flist[i] indexes
// vertices in Vlist[i]
// wind_num_op function handle for filtering winding numbers from
// n-tuples of integer values to [0,1] outside/inside values
// keep function handle for determining if a patch should be "kept"
// in the output based on the winding number on either side
// Outputs:
// VC #VC by 3 list of vertex positions of boolean result mesh
// FC #FC by 3 list of triangle indices into VC
// J #FC list of indices into [Flist[0];Flist[1];...;Flist[k]]
// revealing "birth" facet
// Returns true iff inputs induce a piecewise constant winding number
// field
//
// See also: mesh_boolean_cork, intersect_other,
// remesh_self_intersections
/// Variadic mesh Boolean operations
///
/// @param[in] Vlist k-long list of lists of mesh vertex positions
/// @param[in] Flist k-long list of lists of mesh face indices, so that Flist[i] indexes
/// vertices in Vlist[i]
/// @param[in] wind_num_op function handle for filtering winding numbers from
/// n-tuples of integer values to [0,1] outside/inside values
/// @param[in] keep function handle for determining if a patch should be "kept"
/// in the output based on the winding number on either side
/// @param[out] VC #VC by 3 list of vertex positions of boolean result mesh
/// @param[out] FC #FC by 3 list of triangle indices into VC
/// @param[out] J #FC list of indices into [Flist[0];Flist[1];...;Flist[k]]
/// revealing "birth" facet
/// @return true iff inputs induce a piecewise constant winding number
/// field
template <
typename DerivedV,
typename DerivedF,
@ -145,6 +126,7 @@ namespace igl
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J);
/// \overload
template <
typename DerivedV,
typename DerivedF,
@ -158,24 +140,15 @@ namespace igl
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J);
// Given a merged mesh (V,F) and list of sizes of inputs
//
// Inputs:
// V #V by 3 list of merged mesh vertex positions
// F #F by 3 list of merged mesh face indices so that first sizes(0)
// faces come from the first input, and the next sizes(1) faces come
// from the second input, and so on.
// sizes #inputs list of sizes so that sizes(i) is the #faces in the
// ith input
// wind_num_op function handle for filtering winding numbers from
// tuples of integer values to [0,1] outside/inside values
// keep function handle for determining if a patch should be "kept"
// in the output based on the winding number on either side
// Outputs:
// VC #VC by 3 list of vertex positions of boolean result mesh
// FC #FC by 3 list of triangle indices into VC
// J #FC list of birth parent indices
//
/// \overload
/// \brief Given a merged mesh (V,F) and list of sizes of inputs
///
/// @param[in] V #V by 3 list of merged mesh vertex positions
/// @param[in] F #F by 3 list of merged mesh face indices so that first sizes(0)
/// faces come from the first input, and the next sizes(1) faces come
/// from the second input, and so on.
/// @param[in] sizes #inputs list of sizes so that sizes(i) is the #faces in the
/// ith input
template <
typename DerivedVV,
typename DerivedFF,
@ -192,17 +165,7 @@ namespace igl
Eigen::PlainObjectBase<DerivedVC > & VC,
Eigen::PlainObjectBase<DerivedFC > & FC,
Eigen::PlainObjectBase<DerivedJ > & J);
// Inputs:
// VA #VA by 3 list of vertex positions of first mesh
// FA #FA by 3 list of triangle indices into VA
// VB #VB by 3 list of vertex positions of second mesh
// FB #FB by 3 list of triangle indices into VB
// type type of boolean operation
// Outputs:
// VC #VC by 3 list of vertex positions of boolean result mesh
// FC #FC by 3 list of triangle indices into VC
// Returns true ff inputs induce a piecewise constant winding number
// field and type is valid
/// \overload
template <
typename DerivedVA,
typename DerivedFA,

View File

@ -11,18 +11,16 @@ namespace igl
{
namespace cgal
{
// Convert a MeshBooleanType enum to a pair of winding number conversion
// function and "keep" function used by mesh_boolean
//
// Inputs:
// type MeshBooleanType enum value
// Outputs:
// wind_num_op function handle for filtering winding numbers from
// tuples of integer values to [0,1] outside/inside values
// keep function handle for determining if a patch should be "kept"
// in the output based on the winding number on either side
//
// See also: string_to_mesh_boolean_type
/// Convert a MeshBooleanType enum to a pair of winding number conversion
/// function and "keep" function used by mesh_boolean
///
/// @param[in] type MeshBooleanType enum value
/// @param[out] wind_num_op function handle for filtering winding numbers from
/// tuples of integer values to [0,1] outside/inside values
/// @param[out] keep function handle for determining if a patch should be "kept"
/// in the output based on the winding number on either side
///
/// \see string_to_mesh_boolean_type
IGL_INLINE void mesh_boolean_type_to_funcs(
const MeshBooleanType & type,
std::function<int(const Eigen::Matrix<int,1,Eigen::Dynamic>) >&

View File

@ -7,6 +7,8 @@
// obtain one at http://mozilla.org/MPL/2.0/.
#include "mesh_to_cgal_triangle_list.h"
#include "assign.h"
#include "../../parallel_for.h"
#include "../../get_seconds.h"
#include <cassert>
@ -19,6 +21,14 @@ IGL_INLINE void igl::copyleft::cgal::mesh_to_cgal_triangle_list(
const Eigen::MatrixBase<DerivedF> & F,
std::vector<CGAL::Triangle_3<Kernel> > & T)
{
const auto & tictoc = []()
{
static double t_start = igl::get_seconds();
double diff = igl::get_seconds()-t_start;
t_start += diff;
return diff;
};
tictoc();
typedef CGAL::Point_3<Kernel> Point_3;
typedef CGAL::Triangle_3<Kernel> Triangle_3;
// Must be 3D
@ -33,44 +43,39 @@ IGL_INLINE void igl::copyleft::cgal::mesh_to_cgal_triangle_list(
assign(V,KV);
// Must be triangles
assert(F.cols() == 3);
T.reserve(F.rows());
// Loop over faces
for(int f = 0;f<(int)F.rows();f++)
T.resize(F.rows());
igl::parallel_for(F.rows(),[&](const Eigen::Index f)
{
T.push_back(
T[f] =
Triangle_3(
Point_3( KV(F(f,0),0), KV(F(f,0),1), KV(F(f,0),2)),
Point_3( KV(F(f,1),0), KV(F(f,1),1), KV(F(f,1),2)),
Point_3( KV(F(f,2),0), KV(F(f,2),1), KV(F(f,2),2))));
}
Point_3( KV(F(f,2),0), KV(F(f,2),1), KV(F(f,2),2)));
},1000);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Simple_cartesian<double> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Simple_cartesian<double> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
#endif

View File

@ -16,16 +16,13 @@ namespace igl
{
namespace cgal
{
// Convert a mesh (V,F) to a list of CGAL triangles
//
// Templates:
// Kernal CGAL computation and construction kernel (e.g.
// CGAL::Exact_predicates_exact_constructions_kernel)
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices
// Outputs:
// T #F list of CGAL triangles
/// Convert a mesh (V,F) to a list of CGAL triangles
///
/// @2tparam Kernal CGAL computation and construction kernel (e.g.
/// CGAL::Exact_predicates_exact_constructions_kernel)
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices
/// @param[out] T #F list of CGAL triangles
template <
typename DerivedV,
typename DerivedF,

View File

@ -9,12 +9,14 @@
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>
template <typename Polyhedron>
template <
typename DerivedV,
typename DerivedF,
typename Polyhedron>
IGL_INLINE bool igl::copyleft::cgal::mesh_to_polyhedron(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
Polyhedron & poly)
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
Polyhedron& poly)
{
typedef typename Polyhedron::HalfedgeDS HalfedgeDS;
// Postcondition: hds is a valid polyhedral surface.
@ -50,5 +52,7 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_to_polyhedron(
// Explicit template instantiation
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
template bool igl::copyleft::cgal::mesh_to_polyhedron<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >&);
#include <CGAL/Polyhedron_3.h>
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::mesh_to_polyhedron<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >&);
#endif

View File

@ -16,21 +16,21 @@ namespace igl
{
namespace cgal
{
// Convert a mesh (V,F) to a CGAL Polyhedron
//
// Templates:
// Polyhedron CGAL Polyhedron type (e.g. Polyhedron_3)
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices
// Outputs:
// poly cgal polyhedron
// Returns true only if (V,F) can be converted to a valid polyhedron (i.e. if
// (V,F) is vertex and edge manifold).
template <typename Polyhedron>
/// Convert a mesh (V,F) to a CGAL Polyhedron
///
/// @tparam Polyhedron CGAL Polyhedron type (e.g. Polyhedron_3)
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices
/// @param[out] poly cgal polyhedron
/// @return true only if (V,F) can be converted to a valid polyhedron
/// (i.e. if (V,F) is vertex and edge manifold).
template <
typename DerivedV,
typename DerivedF,
typename Polyhedron>
IGL_INLINE bool mesh_to_polyhedron(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
Polyhedron & poly);
}
}

View File

@ -8,10 +8,10 @@
#include "minkowski_sum.h"
#include "mesh_boolean.h"
#include "../../slice.h"
#include "../../slice_mask.h"
#include "../../LinSpaced.h"
#include "../../unique_rows.h"
#include "../../placeholders.h"
#include "../../find.h"
#include "../../get_seconds.h"
#include "../../edges.h"
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
@ -142,7 +142,7 @@ IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
W,
G,
SJ);
slice(DerivedJ(J),SJ,1,J);
J = J(SJ).eval();
}
}
@ -198,7 +198,7 @@ IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
//// Mask whether positive dot product, or negative: because of exactly zero,
//// these are not necessarily complementary
// Nevermind, actually P = !N
Matrix<bool,Dynamic,1> P(m,1),N(m,1);
Array<bool,Dynamic,1> P(m,1),N(m,1);
// loop over faces
int mp = 0,mn = 0;
for(int f = 0;f<m;f++)
@ -230,16 +230,23 @@ IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
typedef Matrix<typename DerivedG::Scalar,Dynamic,Dynamic> MatrixXI;
typedef Matrix<typename DerivedG::Scalar,Dynamic,1> VectorXI;
MatrixXI GT(mp+mn,3);
GT<< slice_mask(FA,N,1), slice_mask((FA.array()+n).eval(),P,1);
GT<<
FA(igl::find(N),igl::placeholders::all),
(FA.array()+n).eval()(igl::find(P),igl::placeholders::all);
// J indexes FA for parts at s and m+FA for parts at d
J.derived() = igl::LinSpaced<DerivedJ >(m,0,m-1);
DerivedJ JT(mp+mn);
JT << slice_mask(J,P,1), slice_mask(J,N,1);
JT <<
J(igl::find(P),igl::placeholders::all),
J(igl::find(N),igl::placeholders::all);
JT.block(mp,0,mn,1).array()+=m;
// Original non-co-planar faces with positively oriented reversed
MatrixXI BA(mp+mn,3);
BA << slice_mask(FA,P,1).rowwise().reverse(), slice_mask(FA,N,1);
BA <<
FA(igl::find(P),igl::placeholders::all).rowwise().reverse(),
FA(igl::find(N),igl::placeholders::all);
// Quads along **all** sides
MatrixXI GQ((mp+mn)*3,4);
GQ<<
@ -289,7 +296,7 @@ IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
sF.block(f,1,1,d-1) = sF.block(f,1,1,d-1).reverse().eval();
}
}
Matrix<bool,Dynamic,1> M = Matrix<bool,Dynamic,1>::Zero(m,1);
Array<bool,Dynamic,1> M = Array<bool,Dynamic,1>::Zero(m,1);
{
VectorXI P = igl::LinSpaced<VectorXI >(d,0,d-1);
for(int p = 0;p<d;p++)
@ -355,7 +362,7 @@ IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
Matrix<typename DerivedVA::Scalar,Dynamic,Dynamic>(),MatrixXI(),
MESH_BOOLEAN_TYPE_UNION,
W,G,SJ);
J.derived() = slice(DerivedJ(J),SJ,1);
J = J(SJ).eval();
}
}
@ -381,15 +388,7 @@ IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::minkowski_sum<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Lazy_exact_nt<CGAL::Gmpq>, 3, 1, CGAL::Lazy_exact_nt<CGAL::Gmpq>, 3, 1, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 3, 1, 1, 3> const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 3, 1, 1, 3> const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::minkowski_sum<
Eigen::Matrix<float, -1, 3, 1, -1, 3>,
Eigen::Matrix<int, -1, 3, 1, -1, 3>,
double, 3, 1,
float, 3, 1,
Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>,
Eigen::Matrix<int, -1, -1, 0, -1, -1>,
Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::minkowski_sum<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck::FT, 3, 1, CGAL::Epeck::FT, 3, 1, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3> const&, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3> const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::minkowski_sum<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>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::minkowski_sum<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, 3, 1, double, 3, 1, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#endif

View File

@ -17,22 +17,20 @@ namespace igl
{
namespace cgal
{
// Compute the Minkowski sum of a closed triangle mesh (V,F) and a
// set of simplices in 3D.
//
// Inputs:
// VA #VA by 3 list of mesh vertices in 3D
// FA #FA by 3 list of triangle indices into VA
// VB #VB by 3 list of mesh vertices in 3D
// FB #FB by ss list of simplex indices into VB, ss<=3
// resolve_overlaps whether or not to resolve self-union. If false
// then result may contain self-intersections if input mesh is
// non-convex.
// Outputs:
// W #W by 3 list of mesh vertices in 3D
// G #G by 3 list of triangle indices into W
// J #G by 2 list of indices into
//
/// Compute the Minkowski sum of a closed triangle mesh (V,F) and a
/// set of simplices in 3D.
///
/// @param[in] VA #VA by 3 list of mesh vertices in 3D
/// @param[in] FA #FA by 3 list of triangle indices into VA
/// @param[in] VB #VB by 3 list of mesh vertices in 3D
/// @param[in] FB #FB by ss list of simplex indices into VB, ss<=3
/// @param[in] resolve_overlaps whether or not to resolve self-union. If false
/// then result may contain self-intersections if input mesh is
/// non-convex.
/// @param[out] W #W by 3 list of mesh vertices in 3D
/// @param[out] G #G by 3 list of triangle indices into W
/// @param[out] J #G by 2 list of indices into
///
template <
typename DerivedVA,
typename DerivedFA,
@ -50,22 +48,12 @@ namespace igl
Eigen::PlainObjectBase<DerivedW> & W,
Eigen::PlainObjectBase<DerivedG> & G,
Eigen::PlainObjectBase<DerivedJ> & J);
// Compute the Minkowski sum of a closed triangle mesh (V,F) and a
// segment [s,d] in 3D.
//
// Inputs:
// VA #VA by 3 list of mesh vertices in 3D
// FA #FA by 3 list of triangle indices into VA
// s segment source endpoint in 3D
// d segment source endpoint in 3D
// resolve_overlaps whether or not to resolve self-union. If false
// then result may contain self-intersections if input mesh is
// non-convex.
// Outputs:
// W #W by 3 list of mesh vertices in 3D
// G #G by 3 list of triangle indices into W
// J #G list of indices into [F;#V+F;[s d]] of birth parents
//
/// \overload
/// \brief Compute the Minkowski sum of a closed triangle mesh (V,F) and a
/// segment [s,d] in 3D.
///
/// @param[in] s segment source endpoint in 3D
/// @param[in] d segment source endpoint in 3D
template <
typename DerivedVA,
typename DerivedFA,
@ -83,6 +71,7 @@ namespace igl
Eigen::PlainObjectBase<DerivedW> & W,
Eigen::PlainObjectBase<DerivedG> & G,
Eigen::PlainObjectBase<DerivedJ> & J);
/// \overload
template <
typename DerivedVA,
typename DerivedFA,

View File

@ -1,4 +1,5 @@
#include "order_facets_around_edge.h"
#include "../../PlainMatrix.h"
#include <Eigen/Geometry>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
@ -10,8 +11,8 @@ template<
typename DerivedF,
typename DerivedI >
void igl::copyleft::cgal::order_facets_around_edge(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
size_t s,
size_t d,
const std::vector<int>& adj_faces,
@ -85,9 +86,8 @@ void igl::copyleft::cgal::order_facets_around_edge(
order(1, 0) = 1;
break;
case CGAL::COLLINEAR:
std::cerr << "Degenerated triangle detected." <<
std::endl;
assert(false);
// Should never happen (assumes input is non-degenerate).
assert(false && "Degenerated triangle detected.");
break;
default:
assert(false);
@ -277,15 +277,16 @@ void igl::copyleft::cgal::order_facets_around_edge(
template<
typename DerivedV,
typename DerivedF,
typename Derivedpivot_point,
typename DerivedI>
IGL_INLINE
void igl::copyleft::cgal::order_facets_around_edge(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
size_t s,
size_t d,
const std::vector<int>& adj_faces,
const Eigen::PlainObjectBase<DerivedV>& pivot_point,
const Eigen::MatrixBase<Derivedpivot_point>& pivot_point,
Eigen::PlainObjectBase<DerivedI>& order)
{
assert(V.cols() == 3);
@ -332,7 +333,7 @@ void igl::copyleft::cgal::order_facets_around_edge(
for (size_t i=0; i<N; i++) adj_order[i] = i;
std::sort(adj_order.begin(), adj_order.end(), comp);
DerivedV vertices(num_faces + 2, 3);
PlainMatrix<DerivedV,Eigen::Dynamic> vertices(num_faces + 2, 3);
for (size_t i=0; i<N; i++)
{
const size_t fid = signed_index_to_index(adj_faces[adj_order[i]]);
@ -342,7 +343,7 @@ void igl::copyleft::cgal::order_facets_around_edge(
vertices.row(N+1) = V.row(s);
vertices.row(N+2) = V.row(d);
DerivedF faces(num_faces, 3);
PlainMatrix<DerivedF,Eigen::Dynamic> faces(num_faces, 3);
for (size_t i=0; i<N; i++)
{
if (adj_faces[adj_order[i]] < 0)
@ -399,30 +400,23 @@ void igl::copyleft::cgal::order_facets_around_edge(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, bool);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, unsigned long, unsigned long, std::vector<int, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, 1, -1, 1, 1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, -1, 1, 1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, bool);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, 1, -1, 1, 1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, -1, 1, 1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, bool);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 3, 1, 1, 3>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, bool);
template void igl::copyleft::cgal::order_facets_around_edge<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>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, bool);
template void igl::copyleft::cgal::order_facets_around_edge<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<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3>> const&, size_t, size_t, std::vector<int, std::allocator<int>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, bool);
#ifdef WIN32
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &, bool);
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &, bool);
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, 3, 1, -1, 3>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 1, -1, 3>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, 3, 1, -1, 3>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 1, -1, 3>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &, bool);
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 0, -1, 3>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<double, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::order_facets_around_edge<class Eigen::Matrix<double, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 0, -1, 3>> const &, unsigned __int64, unsigned __int64, class std::vector<int, class std::allocator<int>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
#endif
#endif

View File

@ -18,54 +18,55 @@ namespace igl
{
namespace cgal
{
// Given a directed edge, sort its adjacent faces. Assuming the
// directed edge is (s, d). Sort the adjacent faces clockwise around the
// axis (d - s), i.e. left-hand rule. An adjacent face is consistently
// oriented if it contains (d, s) as a directed edge.
//
// For overlapping faces, break the tie using signed face index, smaller
// signed index comes before the larger signed index. Signed index is
// computed as (consistent? 1:-1) * (face_index + 1).
//
// Inputs:
// V #V by 3 list of vertices.
// F #F by 3 list of faces
// s Index of source vertex.
// d Index of destination vertex.
// adj_faces List of adjacent face signed indices.
// Output:
// order List of face indices that orders adjacent faces around edge
// (s, d) clockwise.
/// Given a directed edge, sort its adjacent faces. Assuming the
/// directed edge is (s, d). Sort the adjacent faces clockwise around the
/// axis (d - s), i.e. left-hand rule. An adjacent face is consistently
/// oriented if it contains (d, s) as a directed edge.
///
/// For overlapping faces, break the tie using signed face index, smaller
/// signed index comes before the larger signed index. Signed index is
/// computed as (consistent? 1:-1) * (face_index + 1).
///
/// @param[in] V #V by 3 list of vertices.
/// @param[in] F #F by 3 list of faces
/// @param[in] s Index of source vertex.
/// @param[in] d Index of destination vertex.
/// @param[in] adj_faces List of adjacent face signed indices.
/// @param[out] order List of face indices that orders adjacent faces around edge
/// (s, d) clockwise.
template<
typename DerivedV,
typename DerivedF,
typename DerivedI >
IGL_INLINE
void order_facets_around_edge(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
size_t s,
size_t d,
const std::vector<int>& adj_faces,
Eigen::PlainObjectBase<DerivedI>& order,
bool debug=false);
// This function is a wrapper around the one above. Since the ordering
// is circular, the pivot point is used to define a starting point. So
// order[0] is the index into adj_face that is immediately after the
// pivot face (s, d, pivot point) in clockwise order.
/// \overload
/// \brief This function is a wrapper around the one above. Since the ordering
/// is circular, the pivot point is used to define a starting point. So
/// order[0] is the index into adj_face that is immediately after the
/// pivot face (s, d, pivot point) in clockwise order.
///
/// @param[in] pivot_point A point that forms pivot with edge (s,d)
template<
typename DerivedV,
typename DerivedF,
typename Derivedpivot_point,
typename DerivedI>
IGL_INLINE
void order_facets_around_edge(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
size_t s,
size_t d,
const std::vector<int>& adj_faces,
const Eigen::PlainObjectBase<DerivedV>& pivot_point,
const Eigen::MatrixBase<Derivedpivot_point>& pivot_point,
Eigen::PlainObjectBase<DerivedI>& order);
}
}

View File

@ -1,9 +1,9 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "order_facets_around_edges.h"
#include "order_facets_around_edge.h"
@ -24,10 +24,10 @@ IGL_INLINE
typename std::enable_if<!std::is_same<typename DerivedV::Scalar,
typename CGAL::Exact_predicates_exact_constructions_kernel::FT>::value, void>::type
igl::copyleft::cgal::order_facets_around_edges(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedN>& N,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
std::vector<std::vector<uE2oEType> >& uE2oE,
std::vector<std::vector<uE2CType > >& uE2C ) {
@ -95,21 +95,21 @@ igl::copyleft::cgal::order_facets_around_edges(
edge *= -1;
}
if (edge.norm() < EPS) {
std::cerr << "=====================================" << std::endl;
std::cerr << " ui: " << ui << std::endl;
std::cerr << "edge: " << ref_edge << std::endl;
std::cerr << "face: " << ref_face << std::endl;
std::cerr << " vs: " << V.row(s) << std::endl;
std::cerr << " vd: " << V.row(d) << std::endl;
std::cerr << "adj face normals: " << std::endl;
std::cerr << normals << std::endl;
std::cerr << "Very degenerated case detected:" << std::endl;
std::cerr << "Near zero edge surrounded by "
<< edge_valance << " neearly colinear faces" <<
std::endl;
std::cerr << "=====================================" << std::endl;
}
//if (edge.norm() < EPS) {
// std::cerr << "=====================================" << std::endl;
// std::cerr << " ui: " << ui << std::endl;
// std::cerr << "edge: " << ref_edge << std::endl;
// std::cerr << "face: " << ref_face << std::endl;
// std::cerr << " vs: " << V.row(s) << std::endl;
// std::cerr << " vd: " << V.row(d) << std::endl;
// std::cerr << "adj face normals: " << std::endl;
// std::cerr << normals << std::endl;
// std::cerr << "Very degenerated case detected:" << std::endl;
// std::cerr << "Near zero edge surrounded by "
// << edge_valance << " neearly colinear faces" <<
// std::endl;
// std::cerr << "=====================================" << std::endl;
//}
}
} else {
edge.normalize();
@ -160,14 +160,14 @@ template<
typename uE2EType,
typename uE2oEType,
typename uE2CType >
IGL_INLINE
IGL_INLINE
typename std::enable_if<std::is_same<typename DerivedV::Scalar,
typename CGAL::Exact_predicates_exact_constructions_kernel::FT>::value, void>::type
igl::copyleft::cgal::order_facets_around_edges(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedN>& N,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
std::vector<std::vector<uE2oEType> >& uE2oE,
std::vector<std::vector<uE2CType > >& uE2C ) {
@ -255,9 +255,9 @@ template<
typename uE2oEType,
typename uE2CType >
IGL_INLINE void igl::copyleft::cgal::order_facets_around_edges(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
std::vector<std::vector<uE2oEType> >& uE2oE,
std::vector<std::vector<uE2CType > >& uE2C ) {
@ -321,12 +321,13 @@ IGL_INLINE void igl::copyleft::cgal::order_facets_around_edges(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::order_facets_around_edges<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, int, bool>(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&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
// generated by autoexplicit.sh
template std::enable_if<!(std::is_same<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, CGAL::Lazy_exact_nt<CGAL::Gmpq> >::value), void>::type igl::copyleft::cgal::order_facets_around_edges<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, int, bool>(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&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, long, long, bool>(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<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, long, long, bool>(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<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, long, long, bool>(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, 2, 0, -1, 2> > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, long, long, bool>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
#include <cstdint>
template std::enable_if<!(std::is_same<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, CGAL::Epeck::FT >::value), void>::type igl::copyleft::cgal::order_facets_around_edges<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, int, bool>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, std::ptrdiff_t, std::ptrdiff_t, bool>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, std::ptrdiff_t, std::ptrdiff_t, bool>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<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, int, bool>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, std::ptrdiff_t, std::ptrdiff_t, bool>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
template void igl::copyleft::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, std::ptrdiff_t, std::ptrdiff_t, bool>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > > const&, std::vector<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> >, std::allocator<std::vector<std::ptrdiff_t, std::allocator<std::ptrdiff_t> > > >&, std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > >&);
#ifdef WIN32
#endif
#endif

View File

@ -18,28 +18,25 @@ namespace igl
{
namespace cgal
{
// For each undirected edge, sort its adjacent faces. Assuming the
// undirected edge is (s, d). Sort the adjacent faces clockwise around the
// axis (d - s), i.e. left-hand rule. An adjacent face is consistently
// oriented if it contains (d, s) as a directed edge.
//
// For overlapping faces, break the tie using signed face index, smaller
// signed index comes before the larger signed index. Signed index is
// computed as (consistent? 1:-1) * index.
//
// Inputs:
// V #V by 3 list of vertices.
// F #F by 3 list of faces
// N #F by 3 list of face normals.
// uE #uE by 2 list of vertex_indices, represents undirected edges.
// uE2E #uE list of lists that maps uE to E. (a one-to-many map)
//
// Outputs:
// uE2oE #uE list of lists that maps uE to an ordered list of E. (a
// one-to-many map)
// uE2C #uE list of lists of bools indicates whether each face in
// uE2oE[i] is consistently orientated as the ordering.
//
/// For each undirected edge, sort its adjacent faces. Assuming the
/// undirected edge is (s, d). Sort the adjacent faces clockwise around the
/// axis (d - s), i.e. left-hand rule. An adjacent face is consistently
/// oriented if it contains (d, s) as a directed edge.
///
/// For overlapping faces, break the tie using signed face index, smaller
/// signed index comes before the larger signed index. Signed index is
/// computed as (consistent? 1:-1) * index.
///
/// @param[in] V #V by 3 list of vertices.
/// @param[in] F #F by 3 list of faces
/// @param[in] N #F by 3 list of face normals.
/// @param[in] uE #uE by 2 list of vertex_indices, represents undirected edges.
/// @param[in] uE2E #uE list of lists that maps uE to E. (a one-to-many map)
/// @param[out] uE2oE #uE list of lists that maps uE to an ordered list of E. (a
/// one-to-many map)
/// @param[out] uE2C #uE list of lists of bools indicates whether each face in
/// uE2oE[i] is consistently orientated as the ordering.
///
template<
typename DerivedV,
typename DerivedF,
@ -52,14 +49,14 @@ namespace igl
typename std::enable_if<!std::is_same<typename DerivedV::Scalar,
typename CGAL::Exact_predicates_exact_constructions_kernel::FT>::value, void>::type
order_facets_around_edges(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedN>& N,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
std::vector<std::vector<uE2oEType> >& uE2oE,
std::vector<std::vector<uE2CType > >& uE2C );
/// \overload
template<
typename DerivedV,
typename DerivedF,
@ -72,16 +69,16 @@ namespace igl
typename std::enable_if<std::is_same<typename DerivedV::Scalar,
typename CGAL::Exact_predicates_exact_constructions_kernel::FT>::value, void>::type
order_facets_around_edges(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedN>& N,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedN>& N,
const Eigen::MatrixBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
std::vector<std::vector<uE2oEType> >& uE2oE,
std::vector<std::vector<uE2CType > >& uE2C );
// Order faces around each edge. Only exact predicate is used in the algorithm.
// Normal is not needed.
/// \overload
/// \brief Order faces around each edge. Only exact predicate is used in
/// the algorithm. Normal is not needed.
template<
typename DerivedV,
typename DerivedF,
@ -90,9 +87,9 @@ namespace igl
typename uE2oEType,
typename uE2CType >
IGL_INLINE void order_facets_around_edges(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
std::vector<std::vector<uE2oEType> >& uE2oE,
std::vector<std::vector<uE2CType > >& uE2C );

View File

@ -1,9 +1,9 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2016 Qingan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "orient2D.h"
@ -12,9 +12,9 @@
template<typename Scalar>
IGL_INLINE short igl::copyleft::cgal::orient2D(
const Scalar pa[2],
const Scalar pb[2],
const Scalar pc[2])
const Scalar *pa,
const Scalar *pb,
const Scalar *pc)
{
typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick;
@ -24,7 +24,8 @@ IGL_INLINE short igl::copyleft::cgal::orient2D(
switch(CGAL::orientation(
typename Kernel::Point_2(pa[0], pa[1]),
typename Kernel::Point_2(pb[0], pb[1]),
typename Kernel::Point_2(pc[0], pc[1]))) {
typename Kernel::Point_2(pc[0], pc[1])))
{
case CGAL::LEFT_TURN:
return 1;
case CGAL::RIGHT_TURN:
@ -35,3 +36,11 @@ IGL_INLINE short igl::copyleft::cgal::orient2D(
throw "Invalid orientation";
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template short igl::copyleft::cgal::orient2D<double>(double const*, double const*, double const*);
#ifdef WIN32
#endif
#endif

View File

@ -1,9 +1,9 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2016 Qingan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_COPYLEFT_CGAL_ORIENT_2D_H
@ -17,17 +17,19 @@ namespace igl
{
namespace cgal
{
// Inputs:
// pa,pb,pc 2D points.
// Output:
// 1 if pa,pb,pc are counterclockwise oriented.
// 0 if pa,pb,pc are counterclockwise oriented.
// -1 if pa,pb,pc are clockwise oriented.
/// Tests whether a point is above, on, or below a line.
///
/// @param[in] pa 2D point on plane
/// @param[in] pb 2D point on plane
/// @param[in] pc 2D point to test
/// @return 1 if pa,pb,pc,pd forms a triangle of positive area.
/// 0 if pa,pb,pc,pd are coplanar.
/// -1 if pa,pb,pc,pd forms a tet of negative area.
template <typename Scalar>
IGL_INLINE short orient2D(
const Scalar pa[2],
const Scalar pb[2],
const Scalar pc[2]);
const Scalar *pa,
const Scalar *pb,
const Scalar *pc);
}
}
}

View File

@ -17,12 +17,15 @@ namespace igl
{
namespace cgal
{
// Inputs:
// pa,pb,pc,pd 3D points.
// Output:
// 1 if pa,pb,pc,pd forms a tet of positive volume.
// 0 if pa,pb,pc,pd are coplanar.
// -1 if pa,pb,pc,pd forms a tet of negative volume.
/// Tests whether a point is above, on, or below a plane.
///
/// @param[in] pa 3D point on plane
/// @param[in] pb 3D point on plane
/// @param[in] pc 3D point on plane
/// @param[in] pd 3D point to test
/// @return 1 if pa,pb,pc,pd forms a tet of positive volume.
/// 0 if pa,pb,pc,pd are coplanar.
/// -1 if pa,pb,pc,pd forms a tet of negative volume.
template <typename Scalar>
IGL_INLINE short orient3D(
const Scalar pa[3],

View File

@ -0,0 +1,160 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
// Copyright (C) 2021 Alec Jacobson <jacobson@cs.toronto.edu>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "outer_edge.h"
#include "outer_vertex.h"
#include <iostream>
#include <vector>
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType,
typename DerivedA
>
IGL_INLINE void igl::copyleft::cgal::outer_edge(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedI> & I,
IndexType & v1,
IndexType & v2,
Eigen::PlainObjectBase<DerivedA> & A)
{
// Algorithm:
// Find an outer vertex first.
// Find the incident edge with largest abs slope when projected onto XY plane.
// If there is a tie, check the signed slope and use the positive one.
// If there is still a tie, break it using the projected slope onto ZX plane.
// If there is still a tie, again check the signed slope and use the positive one.
// If there is still a tie, then there are multiple overlapping edges,
// which violates the precondition.
typedef typename DerivedV::Scalar Scalar;
typedef typename DerivedV::Index Index;
typedef typename Eigen::Matrix<Scalar, 3, 1> ScalarArray3;
typedef typename Eigen::Matrix<typename DerivedF::Scalar, 3, 1> IndexArray3;
const Index INVALID = std::numeric_limits<Index>::max();
Index outer_vid;
Eigen::Matrix<Index,Eigen::Dynamic,1> candidate_faces;
outer_vertex(V, F, I, outer_vid, candidate_faces);
const ScalarArray3& outer_v = V.row(outer_vid);
assert(candidate_faces.size() > 0);
auto get_vertex_index = [&](const IndexArray3& f, Index vid) -> Index
{
if (f[0] == vid) return 0;
if (f[1] == vid) return 1;
if (f[2] == vid) return 2;
assert(false);
return -1;
};
auto unsigned_value = [](Scalar v) -> Scalar {
if (v < 0) return v * -1;
else return v;
};
Scalar outer_slope_YX = 0;
Scalar outer_slope_ZX = 0;
Index outer_opp_vid = INVALID;
bool infinite_slope_detected = false;
std::vector<Index> incident_faces;
auto check_and_update_outer_edge = [&](Index opp_vid, Index fid) -> void {
if (opp_vid == outer_opp_vid)
{
incident_faces.push_back(fid);
return;
}
const ScalarArray3 opp_v = V.row(opp_vid);
if (!infinite_slope_detected && outer_v[0] != opp_v[0])
{
// Finite slope
const ScalarArray3 diff = opp_v - outer_v;
const Scalar slope_YX = diff[1] / diff[0];
const Scalar slope_ZX = diff[2] / diff[0];
const Scalar u_slope_YX = unsigned_value(slope_YX);
const Scalar u_slope_ZX = unsigned_value(slope_ZX);
bool update = false;
if (outer_opp_vid == INVALID) {
update = true;
} else {
const Scalar u_outer_slope_YX = unsigned_value(outer_slope_YX);
if (u_slope_YX > u_outer_slope_YX) {
update = true;
} else if (u_slope_YX == u_outer_slope_YX &&
slope_YX > outer_slope_YX) {
update = true;
} else if (slope_YX == outer_slope_YX) {
const Scalar u_outer_slope_ZX =
unsigned_value(outer_slope_ZX);
if (u_slope_ZX > u_outer_slope_ZX) {
update = true;
} else if (u_slope_ZX == u_outer_slope_ZX &&
slope_ZX > outer_slope_ZX) {
update = true;
} else if (slope_ZX == u_outer_slope_ZX) {
assert(false);
}
}
}
if (update) {
outer_opp_vid = opp_vid;
outer_slope_YX = slope_YX;
outer_slope_ZX = slope_ZX;
incident_faces = {fid};
}
} else if (!infinite_slope_detected)
{
// Infinite slope
outer_opp_vid = opp_vid;
infinite_slope_detected = true;
incident_faces = {fid};
}
};
const size_t num_candidate_faces = candidate_faces.size();
for (size_t i=0; i<num_candidate_faces; i++)
{
const Index fid = candidate_faces(i);
const IndexArray3& f = F.row(fid);
size_t id = get_vertex_index(f, outer_vid);
Index next_vid = f((id+1)%3);
Index prev_vid = f((id+2)%3);
check_and_update_outer_edge(next_vid, fid);
check_and_update_outer_edge(prev_vid, fid);
}
v1 = outer_vid;
v2 = outer_opp_vid;
A.resize(incident_faces.size());
std::copy(incident_faces.begin(), incident_faces.end(), A.data());
}
#ifdef IGL_STATIC_LIBRARY
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
// Explicit template instantiation
// generated by autoexplicit.sh
#include <cstdint>
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,1,0,-1,1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,-1,0,-1,-1>,Eigen::Matrix<int,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,1,0,-1,1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<int,-1,3,0,-1,3>,Eigen::Matrix<int,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,3,0,-1,3> > const &,Eigen::MatrixBase<Eigen::Matrix<int,-1,3,0,-1,3> > const &,Eigen::MatrixBase<Eigen::Matrix<int,-1,1,0,-1,1> > const &,std::ptrdiff_t &,std::ptrdiff_t &,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > &);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<int,-1,3,0,-1,3>,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1>,std::ptrdiff_t,Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,3,0,-1,3> > const&,Eigen::MatrixBase<Eigen::Matrix<int,-1,3,0,-1,3> > const&,Eigen::MatrixBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > const&,std::ptrdiff_t&,std::ptrdiff_t&,Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >&);
#ifdef WIN32
template void __cdecl igl::copyleft::cgal::outer_edge<class Eigen::Matrix<class CGAL::Epeck::FT,-1,-1,0,-1,-1>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<long,-1,1,0,-1,1>,std::ptrdiff_t,class Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(class Eigen::MatrixBase<class Eigen::Matrix<class CGAL::Epeck::FT,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<long,-1,1,0,-1,1> > const &,std::ptrdiff_t &,std::ptrdiff_t &,class Eigen::PlainObjectBase<class Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > &);
template void __cdecl igl::copyleft::cgal::outer_edge<class Eigen::Matrix<double,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,3,0,-1,3>,class Eigen::Matrix<long,-1,1,0,-1,1>,std::ptrdiff_t,class Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> >(class Eigen::MatrixBase<class Eigen::Matrix<double,-1,3,0,-1,3> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,3,0,-1,3> > const &,class Eigen::MatrixBase<class Eigen::Matrix<long,-1,1,0,-1,1> > const &,std::ptrdiff_t &,std::ptrdiff_t &,class Eigen::PlainObjectBase<class Eigen::Matrix<std::ptrdiff_t,-1,1,0,-1,1> > &);
#endif
#endif

View File

@ -0,0 +1,56 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Qingan Zhou <qnzhou@gmail.com>
// Copyright (C) 2021 Alec Jacobson <jacobson@cs.toronto.edu>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_COPYLEFT_CGAL_OUTER_EDGE_H
#define IGL_COPYLEFT_CGAL_OUTER_EDGE_H
#include "../../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace copyleft
{
namespace cgal
{
/// Find an edge that is reachable from infinity without crossing any faces.
/// Such edge is called "outer edge."
///
/// \pre The input mesh must have all self-intersection resolved
/// and no duplicated vertices. The correctness of the output depends on
/// the fact that there is no edge overlap. See
/// cgal::remesh_self_intersections.h for how to obtain such input.
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @param[in] I #I list of facets to consider
/// @param[out] v1 index of the first end point of outer edge
/// @param[out] v2 index of the second end point of outer edge
/// @param[out] A #A list of facets incident to the outer edge
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType,
typename DerivedA
>
IGL_INLINE void outer_edge(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedI> & I,
IndexType & v1,
IndexType & v2,
Eigen::PlainObjectBase<DerivedA> & A);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "outer_edge.cpp"
#endif
#endif

View File

@ -1,232 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "outer_element.h"
#include <iostream>
#include <vector>
template <
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType,
typename DerivedA
>
IGL_INLINE void igl::copyleft::cgal::outer_vertex(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::PlainObjectBase<DerivedI> & I,
IndexType & v_index,
Eigen::PlainObjectBase<DerivedA> & A)
{
// Algorithm:
// Find an outer vertex (i.e. vertex reachable from infinity)
// Return the vertex with the largest X value.
// If there is a tie, pick the one with largest Y value.
// If there is still a tie, pick the one with the largest Z value.
// If there is still a tie, then there are duplicated vertices within the
// mesh, which violates the precondition.
typedef typename DerivedF::Scalar Index;
const Index INVALID = std::numeric_limits<Index>::max();
const size_t num_selected_faces = I.rows();
std::vector<size_t> candidate_faces;
Index outer_vid = INVALID;
typename DerivedV::Scalar outer_val = 0;
for (size_t i=0; i<num_selected_faces; i++)
{
size_t f = I(i);
for (size_t j=0; j<3; j++)
{
Index v = F(f, j);
auto vx = V(v, 0);
if (outer_vid == INVALID || vx > outer_val)
{
outer_val = vx;
outer_vid = v;
candidate_faces = {f};
} else if (v == outer_vid)
{
candidate_faces.push_back(f);
} else if (vx == outer_val)
{
// Break tie.
auto vy = V(v,1);
auto vz = V(v, 2);
auto outer_y = V(outer_vid, 1);
auto outer_z = V(outer_vid, 2);
assert(!(vy == outer_y && vz == outer_z));
bool replace = (vy > outer_y) ||
((vy == outer_y) && (vz > outer_z));
if (replace)
{
outer_val = vx;
outer_vid = v;
candidate_faces = {f};
}
}
}
}
assert(outer_vid != INVALID);
assert(candidate_faces.size() > 0);
v_index = outer_vid;
A.resize(candidate_faces.size());
std::copy(candidate_faces.begin(), candidate_faces.end(), A.data());
}
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType,
typename DerivedA
>
IGL_INLINE void igl::copyleft::cgal::outer_edge(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::PlainObjectBase<DerivedI> & I,
IndexType & v1,
IndexType & v2,
Eigen::PlainObjectBase<DerivedA> & A) {
// Algorithm:
// Find an outer vertex first.
// Find the incident edge with largest abs slope when projected onto XY plane.
// If there is a tie, check the signed slope and use the positive one.
// If there is still a tie, break it using the projected slope onto ZX plane.
// If there is still a tie, again check the signed slope and use the positive one.
// If there is still a tie, then there are multiple overlapping edges,
// which violates the precondition.
typedef typename DerivedV::Scalar Scalar;
typedef typename DerivedV::Index Index;
typedef typename Eigen::Matrix<Scalar, 3, 1> ScalarArray3;
typedef typename Eigen::Matrix<typename DerivedF::Scalar, 3, 1> IndexArray3;
const Index INVALID = std::numeric_limits<Index>::max();
Index outer_vid;
Eigen::Matrix<Index,Eigen::Dynamic,1> candidate_faces;
outer_vertex(V, F, I, outer_vid, candidate_faces);
const ScalarArray3& outer_v = V.row(outer_vid);
assert(candidate_faces.size() > 0);
auto get_vertex_index = [&](const IndexArray3& f, Index vid) -> Index
{
if (f[0] == vid) return 0;
if (f[1] == vid) return 1;
if (f[2] == vid) return 2;
assert(false);
return -1;
};
auto unsigned_value = [](Scalar v) -> Scalar {
if (v < 0) return v * -1;
else return v;
};
Scalar outer_slope_YX = 0;
Scalar outer_slope_ZX = 0;
Index outer_opp_vid = INVALID;
bool infinite_slope_detected = false;
std::vector<Index> incident_faces;
auto check_and_update_outer_edge = [&](Index opp_vid, Index fid) -> void {
if (opp_vid == outer_opp_vid)
{
incident_faces.push_back(fid);
return;
}
const ScalarArray3 opp_v = V.row(opp_vid);
if (!infinite_slope_detected && outer_v[0] != opp_v[0])
{
// Finite slope
const ScalarArray3 diff = opp_v - outer_v;
const Scalar slope_YX = diff[1] / diff[0];
const Scalar slope_ZX = diff[2] / diff[0];
const Scalar u_slope_YX = unsigned_value(slope_YX);
const Scalar u_slope_ZX = unsigned_value(slope_ZX);
bool update = false;
if (outer_opp_vid == INVALID) {
update = true;
} else {
const Scalar u_outer_slope_YX = unsigned_value(outer_slope_YX);
if (u_slope_YX > u_outer_slope_YX) {
update = true;
} else if (u_slope_YX == u_outer_slope_YX &&
slope_YX > outer_slope_YX) {
update = true;
} else if (slope_YX == outer_slope_YX) {
const Scalar u_outer_slope_ZX =
unsigned_value(outer_slope_ZX);
if (u_slope_ZX > u_outer_slope_ZX) {
update = true;
} else if (u_slope_ZX == u_outer_slope_ZX &&
slope_ZX > outer_slope_ZX) {
update = true;
} else if (slope_ZX == u_outer_slope_ZX) {
assert(false);
}
}
}
if (update) {
outer_opp_vid = opp_vid;
outer_slope_YX = slope_YX;
outer_slope_ZX = slope_ZX;
incident_faces = {fid};
}
} else if (!infinite_slope_detected)
{
// Infinite slope
outer_opp_vid = opp_vid;
infinite_slope_detected = true;
incident_faces = {fid};
}
};
const size_t num_candidate_faces = candidate_faces.size();
for (size_t i=0; i<num_candidate_faces; i++)
{
const Index fid = candidate_faces(i);
const IndexArray3& f = F.row(fid);
size_t id = get_vertex_index(f, outer_vid);
Index next_vid = f((id+1)%3);
Index prev_vid = f((id+2)%3);
check_and_update_outer_edge(next_vid, fid);
check_and_update_outer_edge(prev_vid, fid);
}
v1 = outer_vid;
v2 = outer_opp_vid;
A.resize(incident_faces.size());
std::copy(incident_faces.begin(), incident_faces.end(), A.data());
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
template void igl::copyleft::cgal::outer_edge<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>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(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&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(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&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(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&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(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<int, -1, -1, 1, -1, -1> > const&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(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&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -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&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
#ifdef WIN32
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<long, -1, 1, 0, -1, 1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<long, -1, 1, 0, -1, 1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, 3, 1, -1, 3>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 1, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, 3, 0, -1, 3>, class Eigen::Matrix<long, -1, 1, 0, -1, 1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 0, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<long, -1, 1, 0, -1, 1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<double, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<double, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<double, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 1, -1, -1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 1, -1, -1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
template void igl::copyleft::cgal::outer_edge<class Eigen::Matrix<double, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, 3, 0, -1, 3>, class Eigen::Matrix<long, -1, 1, 0, -1, 1>, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 0, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<long, -1, 1, 0, -1, 1>> const &, __int64 &, __int64 &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &);
#endif
#endif

View File

@ -1,83 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Qingan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_COPYLEFT_CGAL_OUTER_ELEMENT_H
#define IGL_COPYLEFT_CGAL_OUTER_ELEMENT_H
#include "../../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace copyleft
{
namespace cgal
{
// Find a vertex that is reachable from infinite without crossing any faces.
// Such vertex is called "outer vertex."
//
// Precondition: The input mesh must have all self-intersection resolved and
// no duplicated vertices. See cgal::remesh_self_intersections.h for how to
// obtain such input.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices into V
// I #I list of facets to consider
// Outputs:
// v_index index of outer vertex
// A #A list of facets incident to the outer vertex
template <
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType,
typename DerivedA
>
IGL_INLINE void outer_vertex(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::PlainObjectBase<DerivedI> & I,
IndexType & v_index,
Eigen::PlainObjectBase<DerivedA> & A);
// Find an edge that is reachable from infinity without crossing any faces.
// Such edge is called "outer edge."
//
// Precondition: The input mesh must have all self-intersection resolved
// and no duplicated vertices. The correctness of the output depends on
// the fact that there is no edge overlap. See
// cgal::remesh_self_intersections.h for how to obtain such input.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices into V
// I #I list of facets to consider
// Outputs:
// v1 index of the first end point of outer edge
// v2 index of the second end point of outer edge
// A #A list of facets incident to the outer edge
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType,
typename DerivedA
>
IGL_INLINE void outer_edge(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::PlainObjectBase<DerivedI> & I,
IndexType & v1,
IndexType & v2,
Eigen::PlainObjectBase<DerivedA> & A);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "outer_element.cpp"
#endif
#endif

View File

@ -1,14 +1,15 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "outer_facet.h"
#include "outer_element.h"
#include "outer_edge.h"
#include "order_facets_around_edge.h"
#include "../../PlainMatrix.h"
#include <algorithm>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
@ -19,9 +20,9 @@ template<
typename IndexType
>
IGL_INLINE void igl::copyleft::cgal::outer_facet(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::PlainObjectBase<DerivedI> & I,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedI> & I,
IndexType & f,
bool & flipped) {
@ -39,7 +40,7 @@ IGL_INLINE void igl::copyleft::cgal::outer_facet(
// implemnetation of outer_edge()). The first adjacent facet is facing
// outside (i.e. flipped=false) if it has positive X normal component.
// If it has zero normal component, it is facing outside if it contains
// directed edge (s, d).
// directed edge (s, d).
//typedef typename DerivedV::Scalar Scalar;
typedef typename DerivedV::Index Index;
@ -69,7 +70,7 @@ IGL_INLINE void igl::copyleft::cgal::outer_facet(
adj_faces.begin(),
convert_to_signed_index);
DerivedV pivot_point = V.row(s);
PlainMatrix<DerivedV,1> pivot_point = V.row(s);
pivot_point(0, 0) += 1.0;
Eigen::VectorXi order;
@ -89,10 +90,10 @@ template<
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,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedN> & N,
const Eigen::MatrixBase<DerivedI> & I,
IndexType & f,
bool & flipped) {
// Algorithm:
@ -118,7 +119,7 @@ IGL_INLINE void igl::copyleft::cgal::outer_facet(
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++)
for (size_t i=0; i<num_incident_faces; i++)
{
const auto& fid = incident_faces(i);
const Scalar nx = N(fid, 0);
@ -148,33 +149,21 @@ IGL_INLINE void igl::copyleft::cgal::outer_facet(
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, unsigned long&, bool&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -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&, unsigned long&, bool&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -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&);
// generated by autoexplicit.sh
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>, unsigned long>(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&, unsigned long&, bool&);
#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&);
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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&, unsigned long&, bool&);
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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&);
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > 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&);
// Explicit template instantiation
// generated by autoexplicit.sh
#include <cstdint>
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, bool&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Index>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Index &, bool&);
template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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<int, -1, 1, 0, -1, 1>, Eigen::Index>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Index&, 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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<int, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
//template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
#ifdef WIN32
template void igl::copyleft::cgal::outer_facet<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned __int64>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, unsigned __int64 &, bool &);
template void igl::copyleft::cgal::outer_facet<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned __int64>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, unsigned __int64 &, bool &);
template void igl::copyleft::cgal::outer_facet<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, 3, 1, -1, 3>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned __int64>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 1, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, unsigned __int64 &, bool &);
#endif
#endif

View File

@ -17,54 +17,23 @@ namespace igl
{
namespace cgal
{
// Find a facet that is reachable from infinity without crossing any faces.
// Such facet is called "outer facet."
//
// Precondition: The input mesh must have all self-intersection resolved. I.e
// there is no duplicated vertices, no overlapping edge and no intersecting
// faces (the only exception is there could be topologically duplicated faces).
// See cgal::remesh_self_intersections.h for how to obtain such input.
//
// This function differ from igl::outer_facet() in the fact this
// function is more robust because it does not rely on facet normals.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices into V
// I #I list of facets to consider
// Outputs:
// f Index of the outer facet.
// flipped true iff the normal of f points inwards.
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType
>
IGL_INLINE void outer_facet(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::PlainObjectBase<DerivedI> & I,
IndexType & f,
bool & flipped);
// Find a facet that is reachable from infinity without crossing any faces.
// Such facet is called "outer facet."
//
// Precondition: The input mesh must have all self-intersection resolved.
// I.e there is no duplicated vertices, no overlapping edge and no
// intersecting faces (the only exception is there could be topologically
// duplicated faces). See cgal::remesh_self_intersections.h for how to
// obtain such input.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices into V
// N #N by 3 list of face normals
// I #I list of facets to consider
// Outputs:
// f Index of the outer facet.
// flipped true iff the normal of f points inwards.
/// Find a facet that is reachable from infinity without crossing any faces.
/// Such facet is called "outer facet."
///
/// \pre The input mesh must have all self-intersection resolved. I.e
/// there is no duplicated vertices, no overlapping edge and no intersecting
/// faces (the only exception is there could be topologically duplicated faces).
/// See cgal::remesh_self_intersections.h for how to obtain such input.
///
/// This function differ from igl::outer_facet() in the fact this
/// function is more robust because it does not rely on facet normals.
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @param[in] I #I list of facets to consider
/// @param[in] N #N by 3 list of face normals
/// @param[out] f Index of the outer facet.
/// @param[out] flipped true iff the normal of f points inwards.
template<
typename DerivedV,
typename DerivedF,
@ -73,13 +42,25 @@ namespace igl
typename IndexType
>
IGL_INLINE void outer_facet(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::PlainObjectBase<DerivedN> & N,
const Eigen::PlainObjectBase<DerivedI> & I,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedN> & N,
const Eigen::MatrixBase<DerivedI> & I,
IndexType & f,
bool & flipped);
/// \overload
template<
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType
>
IGL_INLINE void outer_facet(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedI> & I,
IndexType & f,
bool & flipped);
}
}

View File

@ -25,8 +25,8 @@ template <
typename DerivedJ,
typename Derivedflip>
IGL_INLINE void igl::copyleft::cgal::outer_hull(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedHV> & HV,
Eigen::PlainObjectBase<DerivedHF> & HF,
Eigen::PlainObjectBase<DerivedJ> & J,
@ -101,435 +101,9 @@ IGL_INLINE void igl::copyleft::cgal::outer_hull(
}
}
#include "points_inside_component.h"
#include "order_facets_around_edges.h"
#include "outer_facet.h"
#include "../../sortrows.h"
#include "../../facet_components.h"
#include "../../winding_number.h"
#include "../../triangle_triangle_adjacency.h"
#include "../../unique_edge_map.h"
#include "../../barycenter.h"
#include "../../per_face_normals.h"
#include "../../sort_angles.h"
#include <Eigen/Geometry>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <type_traits>
#include <CGAL/number_utils.h>
//#define IGL_OUTER_HULL_DEBUG
template <
typename DerivedV,
typename DerivedF,
typename DerivedG,
typename DerivedJ,
typename Derivedflip>
IGL_INLINE void igl::copyleft::cgal::outer_hull_legacy(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedG> & G,
Eigen::PlainObjectBase<DerivedJ> & J,
Eigen::PlainObjectBase<Derivedflip> & flip)
{
#ifdef IGL_OUTER_HULL_DEBUG
std::cerr << "Extracting outer hull" << std::endl;
#endif
using namespace Eigen;
using namespace std;
typedef typename DerivedF::Index Index;
Matrix<Index,DerivedF::RowsAtCompileTime,1> C;
typedef Matrix<typename DerivedV::Scalar,Dynamic,DerivedV::ColsAtCompileTime> MatrixXV;
//typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
const Index m = F.rows();
// UNUSED:
//const auto & duplicate_simplex = [&F](const int f, const int g)->bool
//{
// return
// (F(f,0) == F(g,0) && F(f,1) == F(g,1) && F(f,2) == F(g,2)) ||
// (F(f,1) == F(g,0) && F(f,2) == F(g,1) && F(f,0) == F(g,2)) ||
// (F(f,2) == F(g,0) && F(f,0) == F(g,1) && F(f,1) == F(g,2)) ||
// (F(f,0) == F(g,2) && F(f,1) == F(g,1) && F(f,2) == F(g,0)) ||
// (F(f,1) == F(g,2) && F(f,2) == F(g,1) && F(f,0) == F(g,0)) ||
// (F(f,2) == F(g,2) && F(f,0) == F(g,1) && F(f,1) == F(g,0));
//};
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"outer hull..."<<endl;
#endif
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"edge map..."<<endl;
#endif
typedef Matrix<typename DerivedF::Scalar,Dynamic,2> MatrixX2I;
typedef Matrix<typename DerivedF::Index,Dynamic,1> VectorXI;
//typedef Matrix<typename DerivedV::Scalar, 3, 1> Vector3F;
MatrixX2I E,uE;
VectorXI EMAP;
vector<vector<typename DerivedF::Index> > uE2E;
unique_edge_map(F,E,uE,EMAP,uE2E);
#ifdef IGL_OUTER_HULL_DEBUG
for (size_t ui=0; ui<uE.rows(); ui++) {
std::cout << ui << ": " << uE2E[ui].size() << " -- (";
for (size_t i=0; i<uE2E[ui].size(); i++) {
std::cout << uE2E[ui][i] << ", ";
}
std::cout << ")" << std::endl;
}
#endif
std::vector<std::vector<typename DerivedF::Index> > uE2oE;
std::vector<std::vector<bool> > uE2C;
order_facets_around_edges(V, F, uE, uE2E, uE2oE, uE2C);
uE2E = uE2oE;
VectorXI diIM(3*m);
for (auto ue : uE2E) {
for (size_t i=0; i<ue.size(); i++) {
auto fe = ue[i];
diIM[fe] = i;
}
}
vector<vector<vector<Index > > > TT,_1;
triangle_triangle_adjacency(E,EMAP,uE2E,false,TT,_1);
VectorXI counts;
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"facet components..."<<endl;
#endif
facet_components(TT,C,counts);
assert(C.maxCoeff()+1 == counts.rows());
const size_t ncc = counts.rows();
G.resize(0,F.cols());
J.resize(0,1);
flip.setConstant(m,1,false);
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"reindex..."<<endl;
#endif
// H contains list of faces on outer hull;
vector<bool> FH(m,false);
vector<bool> EH(3*m,false);
vector<MatrixXG> vG(ncc);
vector<MatrixXJ> vJ(ncc);
vector<MatrixXJ> vIM(ncc);
//size_t face_count = 0;
for(size_t id = 0;id<ncc;id++)
{
vIM[id].resize(counts[id],1);
}
// current index into each IM
vector<size_t> g(ncc,0);
// place order of each face in its respective component
for(Index f = 0;f<m;f++)
{
vIM[C(f)](g[C(f)]++) = f;
}
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"barycenters..."<<endl;
#endif
// assumes that "resolve" has handled any coplanar cases correctly and nearly
// coplanar cases can be sorted based on barycenter.
MatrixXV BC;
barycenter(V,F,BC);
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"loop over CCs (="<<ncc<<")..."<<endl;
#endif
for(Index id = 0;id<(Index)ncc;id++)
{
auto & IM = vIM[id];
// starting face that's guaranteed to be on the outer hull and in this
// component
int f;
bool f_flip;
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"outer facet..."<<endl;
#endif
igl::copyleft::cgal::outer_facet(V,F,IM,f,f_flip);
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"outer facet: "<<f<<endl;
//cout << V.row(F(f, 0)) << std::endl;
//cout << V.row(F(f, 1)) << std::endl;
//cout << V.row(F(f, 2)) << std::endl;
#endif
int FHcount = 1;
FH[f] = true;
// Q contains list of face edges to continue traversing upong
queue<int> Q;
Q.push(f+0*m);
Q.push(f+1*m);
Q.push(f+2*m);
flip(f) = f_flip;
//std::cout << "face " << face_count++ << ": " << f << std::endl;
//std::cout << "f " << F.row(f).array()+1 << std::endl;
//cout<<"flip("<<f<<") = "<<(flip(f)?"true":"false")<<endl;
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"BFS..."<<endl;
#endif
while(!Q.empty())
{
// face-edge
const int e = Q.front();
Q.pop();
// face
const int f = e%m;
// corner
const int c = e/m;
#ifdef IGL_OUTER_HULL_DEBUG
std::cout << "edge: " << e << ", ue: " << EMAP(e) << std::endl;
std::cout << "face: " << f << std::endl;
std::cout << "corner: " << c << std::endl;
std::cout << "consistent: " << uE2C[EMAP(e)][diIM[e]] << std::endl;
#endif
// Should never see edge again...
if(EH[e] == true)
{
continue;
}
EH[e] = true;
// source of edge according to f
const int fs = flip(f)?F(f,(c+2)%3):F(f,(c+1)%3);
// destination of edge according to f
const int fd = flip(f)?F(f,(c+1)%3):F(f,(c+2)%3);
// edge valence
const size_t val = uE2E[EMAP(e)].size();
#ifdef IGL_OUTER_HULL_DEBUG
//std::cout << "vd: " << V.row(fd) << std::endl;
//std::cout << "vs: " << V.row(fs) << std::endl;
//std::cout << "edge: " << V.row(fd) - V.row(fs) << std::endl;
for (size_t i=0; i<val; i++) {
if (i == diIM(e)) {
std::cout << "* ";
} else {
std::cout << " ";
}
std::cout << i << ": "
<< " (e: " << uE2E[EMAP(e)][i] << ", f: "
<< uE2E[EMAP(e)][i] % m * (uE2C[EMAP(e)][i] ? 1:-1) << ")" << std::endl;
}
#endif
// is edge consistent with edge of face used for sorting
const int e_cons = (uE2C[EMAP(e)][diIM(e)] ? 1: -1);
int nfei = -1;
// Loop once around trying to find suitable next face
for(size_t step = 1; step<val+2;step++)
{
const int nfei_new = (diIM(e) + 2*val + e_cons*step*(flip(f)?-1:1))%val;
const int nf = uE2E[EMAP(e)][nfei_new] % m;
{
#ifdef IGL_OUTER_HULL_DEBUG
//cout<<"Next facet: "<<(f+1)<<" --> "<<(nf+1)<<", |"<<
// di[EMAP(e)][diIM(e)]<<" - "<<di[EMAP(e)][nfei_new]<<"| = "<<
// abs(di[EMAP(e)][diIM(e)] - di[EMAP(e)][nfei_new])
// <<endl;
#endif
// Only use this face if not already seen
if(!FH[nf])
{
nfei = nfei_new;
//} else {
// std::cout << "skipping face " << nfei_new << " because it is seen before"
// << std::endl;
}
break;
//} else {
// std::cout << di[EMAP(e)][diIM(e)].transpose() << std::endl;
// std::cout << di[EMAP(e)][diIM(nfei_new)].transpose() << std::endl;
// std::cout << "skipping face " << nfei_new << " with identical dihedral angle"
// << std::endl;
}
//#ifdef IGL_OUTER_HULL_DEBUG
// cout<<"Skipping co-planar facet: "<<(f+1)<<" --> "<<(nf+1)<<endl;
//#endif
}
int max_ne = -1;
if(nfei >= 0)
{
max_ne = uE2E[EMAP(e)][nfei];
}
if(max_ne>=0)
{
// face of neighbor
const int nf = max_ne%m;
#ifdef IGL_OUTER_HULL_DEBUG
if(!FH[nf])
{
// first time seeing face
cout<<(f+1)<<" --> "<<(nf+1)<<endl;
}
#endif
FH[nf] = true;
//std::cout << "face " << face_count++ << ": " << nf << std::endl;
//std::cout << "f " << F.row(nf).array()+1 << std::endl;
FHcount++;
// corner of neighbor
const int nc = max_ne/m;
const int nd = F(nf,(nc+2)%3);
const bool cons = (flip(f)?fd:fs) == nd;
flip(nf) = (cons ? flip(f) : !flip(f));
//cout<<"flip("<<nf<<") = "<<(flip(nf)?"true":"false")<<endl;
const int ne1 = nf+((nc+1)%3)*m;
const int ne2 = nf+((nc+2)%3)*m;
if(!EH[ne1])
{
Q.push(ne1);
}
if(!EH[ne2])
{
Q.push(ne2);
}
}
}
{
vG[id].resize(FHcount,3);
vJ[id].resize(FHcount,1);
//nG += FHcount;
size_t h = 0;
assert(counts(id) == IM.rows());
for(int i = 0;i<counts(id);i++)
{
const size_t f = IM(i);
//if(f_flip)
//{
// flip(f) = !flip(f);
//}
if(FH[f])
{
vG[id].row(h) = (flip(f)?F.row(f).reverse().eval():F.row(f));
vJ[id](h,0) = f;
h++;
}
}
assert((int)h == FHcount);
}
}
// Is A inside B? Assuming A and B are consistently oriented but closed and
// non-intersecting.
const auto & has_overlapping_bbox = [](
const Eigen::PlainObjectBase<DerivedV> & V,
const MatrixXG & A,
const MatrixXG & B)->bool
{
const auto & bounding_box = [](
const Eigen::PlainObjectBase<DerivedV> & V,
const MatrixXG & F)->
DerivedV
{
DerivedV BB(2,3);
BB<<
1e26,1e26,1e26,
-1e26,-1e26,-1e26;
const size_t m = F.rows();
for(size_t f = 0;f<m;f++)
{
for(size_t c = 0;c<3;c++)
{
const auto & vfc = V.row(F(f,c)).eval();
BB(0,0) = std::min(BB(0,0), vfc(0,0));
BB(0,1) = std::min(BB(0,1), vfc(0,1));
BB(0,2) = std::min(BB(0,2), vfc(0,2));
BB(1,0) = std::max(BB(1,0), vfc(0,0));
BB(1,1) = std::max(BB(1,1), vfc(0,1));
BB(1,2) = std::max(BB(1,2), vfc(0,2));
}
}
return BB;
};
// A lot of the time we're dealing with unrelated, distant components: cull
// them.
DerivedV ABB = bounding_box(V,A);
DerivedV BBB = bounding_box(V,B);
if( (BBB.row(0)-ABB.row(1)).maxCoeff()>0 ||
(ABB.row(0)-BBB.row(1)).maxCoeff()>0 )
{
// bounding boxes do not overlap
return false;
} else {
return true;
}
};
// Reject components which are completely inside other components
vector<bool> keep(ncc,true);
size_t nG = 0;
// This is O( ncc * ncc * m)
for(size_t id = 0;id<ncc;id++)
{
if (!keep[id]) continue;
std::vector<size_t> unresolved;
for(size_t oid = 0;oid<ncc;oid++)
{
if(id == oid || !keep[oid])
{
continue;
}
if (has_overlapping_bbox(V, vG[id], vG[oid])) {
unresolved.push_back(oid);
}
}
const size_t num_unresolved_components = unresolved.size();
DerivedV query_points(num_unresolved_components, 3);
for (size_t i=0; i<num_unresolved_components; i++) {
const size_t oid = unresolved[i];
DerivedF f = vG[oid].row(0);
query_points(i,0) = (V(f(0,0), 0) + V(f(0,1), 0) + V(f(0,2), 0))/3.0;
query_points(i,1) = (V(f(0,0), 1) + V(f(0,1), 1) + V(f(0,2), 1))/3.0;
query_points(i,2) = (V(f(0,0), 2) + V(f(0,1), 2) + V(f(0,2), 2))/3.0;
}
Eigen::VectorXi inside;
igl::copyleft::cgal::points_inside_component(V, vG[id], query_points, inside);
assert((size_t)inside.size() == num_unresolved_components);
for (size_t i=0; i<num_unresolved_components; i++) {
if (inside(i, 0)) {
const size_t oid = unresolved[i];
keep[oid] = false;
}
}
}
for (size_t id = 0; id<ncc; id++) {
if (keep[id]) {
nG += vJ[id].rows();
}
}
// collect G and J across components
G.resize(nG,3);
J.resize(nG,1);
{
size_t off = 0;
for(Index id = 0;id<(Index)ncc;id++)
{
if(keep[id])
{
assert(vG[id].rows() == vJ[id].rows());
G.block(off,0,vG[id].rows(),vG[id].cols()) = vG[id];
J.block(off,0,vJ[id].rows(),vJ[id].cols()) = vJ[id];
off += vG[id].rows();
}
}
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::copyleft::cgal::outer_hull<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>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_hull_legacy< Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &);
template void igl::copyleft::cgal::outer_hull_legacy< Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::outer_hull_legacy<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_hull_legacy<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_hull<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>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#ifdef WIN32
#endif
#endif

View File

@ -15,18 +15,16 @@ namespace igl
{
namespace cgal
{
// Compute the "outer hull" of a piecewise constant winding number induce
// triangle mesh (V,F).
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices into V
// Outputs:
// HV #HV by 3 list of output vertex positions
// HF #HF by 3 list of output triangle indices into HV
// J #HF list of indices into F
// flip #HF list of whether facet was flipped when added to HF
//
/// Compute the "outer hull" of a piecewise constant winding number induce
/// triangle mesh (V,F).
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @param[out] HV #HV by 3 list of output vertex positions
/// @param[out] HF #HF by 3 list of output triangle indices into HV
/// @param[out] J #HF list of indices into F
/// @param[out] flip #HF list of whether facet was flipped when added to HF
///
template <
typename DerivedV,
typename DerivedF,
@ -35,45 +33,12 @@ namespace igl
typename DerivedJ,
typename Derivedflip>
IGL_INLINE void outer_hull(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedHV> & HV,
Eigen::PlainObjectBase<DerivedHF> & HF,
Eigen::PlainObjectBase<DerivedJ> & J,
Eigen::PlainObjectBase<Derivedflip> & flip);
// Compute the "outer hull" of a potentially non-manifold mesh (V,F) whose
// intersections have been "resolved" (e.g. using `cork` or
// `igl::copyleft::cgal::selfintersect`). The outer hull is defined to be all facets
// (regardless of orientation) for which there exists some path from infinity
// to the face without intersecting any other facets. For solids, this is the
// surface of the solid. In general this includes any thin "wings" or
// "flaps". This implementation largely follows Section 3.6 of "Direct
// repair of self-intersecting meshes" [Attene 2014].
//
// Note: This doesn't require the input mesh to be piecewise constant
// winding number, but won't handle multiple non-nested connected
// components.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices into V
// Outputs:
// G #G by 3 list of output triangle indices into V
// J #G list of indices into F
// flip #F list of whether facet was added to G **and** flipped orientation
// (false for faces not added to G)
template <
typename DerivedV,
typename DerivedF,
typename DerivedG,
typename DerivedJ,
typename Derivedflip>
IGL_INLINE void outer_hull_legacy(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedG> & G,
Eigen::PlainObjectBase<DerivedJ> & J,
Eigen::PlainObjectBase<Derivedflip> & flip);
}
}
}

View File

@ -0,0 +1,453 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "outer_hull_legacy.h"
#include "extract_cells.h"
#include "remesh_self_intersections.h"
#include "assign.h"
#include "../../remove_unreferenced.h"
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_triangle_primitive.h>
#include <CGAL/intersections.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include "points_inside_component.h"
#include "order_facets_around_edges.h"
#include "outer_facet.h"
#include "../../sortrows.h"
#include "../../facet_components.h"
#include "../../winding_number.h"
#include "../../triangle_triangle_adjacency.h"
#include "../../unique_edge_map.h"
#include "../../barycenter.h"
#include "../../per_face_normals.h"
#include "../../PlainMatrix.h"
#include "../../sort_angles.h"
#include <Eigen/Geometry>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <type_traits>
#include <CGAL/number_utils.h>
//#define IGL_OUTER_HULL_DEBUG
template <
typename DerivedV,
typename DerivedF,
typename DerivedG,
typename DerivedJ,
typename Derivedflip>
IGL_INLINE void igl::copyleft::cgal::outer_hull_legacy(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedG> & G,
Eigen::PlainObjectBase<DerivedJ> & J,
Eigen::PlainObjectBase<Derivedflip> & flip)
{
#ifdef IGL_OUTER_HULL_DEBUG
std::cerr << "Extracting outer hull" << std::endl;
#endif
using namespace Eigen;
using namespace std;
typedef typename DerivedF::Index Index;
Matrix<Index,DerivedF::RowsAtCompileTime,1> C;
typedef Matrix<typename DerivedV::Scalar,Dynamic,DerivedV::ColsAtCompileTime> MatrixXV;
//typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
const Index m = F.rows();
// UNUSED:
//const auto & duplicate_simplex = [&F](const int f, const int g)->bool
//{
// return
// (F(f,0) == F(g,0) && F(f,1) == F(g,1) && F(f,2) == F(g,2)) ||
// (F(f,1) == F(g,0) && F(f,2) == F(g,1) && F(f,0) == F(g,2)) ||
// (F(f,2) == F(g,0) && F(f,0) == F(g,1) && F(f,1) == F(g,2)) ||
// (F(f,0) == F(g,2) && F(f,1) == F(g,1) && F(f,2) == F(g,0)) ||
// (F(f,1) == F(g,2) && F(f,2) == F(g,1) && F(f,0) == F(g,0)) ||
// (F(f,2) == F(g,2) && F(f,0) == F(g,1) && F(f,1) == F(g,0));
//};
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"outer hull..."<<endl;
#endif
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"edge map..."<<endl;
#endif
typedef Matrix<typename DerivedF::Scalar,Dynamic,2> MatrixX2I;
typedef Matrix<typename DerivedF::Index,Dynamic,1> VectorXI;
//typedef Matrix<typename DerivedV::Scalar, 3, 1> Vector3F;
MatrixX2I E,uE;
VectorXI EMAP;
vector<vector<typename DerivedF::Index> > uE2E;
unique_edge_map(F,E,uE,EMAP,uE2E);
#ifdef IGL_OUTER_HULL_DEBUG
for (size_t ui=0; ui<uE.rows(); ui++) {
std::cout << ui << ": " << uE2E[ui].size() << " -- (";
for (size_t i=0; i<uE2E[ui].size(); i++) {
std::cout << uE2E[ui][i] << ", ";
}
std::cout << ")" << std::endl;
}
#endif
std::vector<std::vector<typename DerivedF::Index> > uE2oE;
std::vector<std::vector<bool> > uE2C;
order_facets_around_edges(V, F, uE, uE2E, uE2oE, uE2C);
uE2E = uE2oE;
VectorXI diIM(3*m);
for (auto ue : uE2E) {
for (size_t i=0; i<ue.size(); i++) {
auto fe = ue[i];
diIM[fe] = i;
}
}
vector<vector<vector<Index > > > TT,_1;
triangle_triangle_adjacency(E,EMAP,uE2E,false,TT,_1);
VectorXI counts;
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"facet components..."<<endl;
#endif
facet_components(TT,C,counts);
assert(C.maxCoeff()+1 == counts.rows());
const size_t ncc = counts.rows();
G.resize(0,F.cols());
J.resize(0,1);
flip.setConstant(m,1,false);
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"reindex..."<<endl;
#endif
// H contains list of faces on outer hull;
vector<bool> FH(m,false);
vector<bool> EH(3*m,false);
vector<MatrixXG> vG(ncc);
vector<MatrixXJ> vJ(ncc);
vector<MatrixXJ> vIM(ncc);
//size_t face_count = 0;
for(size_t id = 0;id<ncc;id++)
{
vIM[id].resize(counts[id],1);
}
// current index into each IM
vector<size_t> g(ncc,0);
// place order of each face in its respective component
for(Index f = 0;f<m;f++)
{
vIM[C(f)](g[C(f)]++) = f;
}
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"barycenters..."<<endl;
#endif
// assumes that "resolve" has handled any coplanar cases correctly and nearly
// coplanar cases can be sorted based on barycenter.
MatrixXV BC;
barycenter(V,F,BC);
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"loop over CCs (="<<ncc<<")..."<<endl;
#endif
for(Index id = 0;id<(Index)ncc;id++)
{
auto & IM = vIM[id];
// starting face that's guaranteed to be on the outer hull and in this
// component
int f;
bool f_flip;
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"outer facet..."<<endl;
#endif
igl::copyleft::cgal::outer_facet(V,F,IM,f,f_flip);
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"outer facet: "<<f<<endl;
//cout << V.row(F(f, 0)) << std::endl;
//cout << V.row(F(f, 1)) << std::endl;
//cout << V.row(F(f, 2)) << std::endl;
#endif
int FHcount = 1;
FH[f] = true;
// Q contains list of face edges to continue traversing upong
queue<int> Q;
Q.push(f+0*m);
Q.push(f+1*m);
Q.push(f+2*m);
flip(f) = f_flip;
//std::cout << "face " << face_count++ << ": " << f << std::endl;
//std::cout << "f " << F.row(f).array()+1 << std::endl;
//cout<<"flip("<<f<<") = "<<(flip(f)?"true":"false")<<endl;
#ifdef IGL_OUTER_HULL_DEBUG
cout<<"BFS..."<<endl;
#endif
while(!Q.empty())
{
// face-edge
const int e = Q.front();
Q.pop();
// face
const int f = e%m;
// corner
const int c = e/m;
#ifdef IGL_OUTER_HULL_DEBUG
std::cout << "edge: " << e << ", ue: " << EMAP(e) << std::endl;
std::cout << "face: " << f << std::endl;
std::cout << "corner: " << c << std::endl;
std::cout << "consistent: " << uE2C[EMAP(e)][diIM[e]] << std::endl;
#endif
// Should never see edge again...
if(EH[e] == true)
{
continue;
}
EH[e] = true;
// source of edge according to f
const int fs = flip(f)?F(f,(c+2)%3):F(f,(c+1)%3);
// destination of edge according to f
const int fd = flip(f)?F(f,(c+1)%3):F(f,(c+2)%3);
// edge valence
const size_t val = uE2E[EMAP(e)].size();
#ifdef IGL_OUTER_HULL_DEBUG
//std::cout << "vd: " << V.row(fd) << std::endl;
//std::cout << "vs: " << V.row(fs) << std::endl;
//std::cout << "edge: " << V.row(fd) - V.row(fs) << std::endl;
for (size_t i=0; i<val; i++) {
if (i == diIM(e)) {
std::cout << "* ";
} else {
std::cout << " ";
}
std::cout << i << ": "
<< " (e: " << uE2E[EMAP(e)][i] << ", f: "
<< uE2E[EMAP(e)][i] % m * (uE2C[EMAP(e)][i] ? 1:-1) << ")" << std::endl;
}
#endif
// is edge consistent with edge of face used for sorting
const int e_cons = (uE2C[EMAP(e)][diIM(e)] ? 1: -1);
int nfei = -1;
// Loop once around trying to find suitable next face
for(size_t step = 1; step<val+2;step++)
{
const int nfei_new = (diIM(e) + 2*val + e_cons*step*(flip(f)?-1:1))%val;
const int nf = uE2E[EMAP(e)][nfei_new] % m;
{
#ifdef IGL_OUTER_HULL_DEBUG
//cout<<"Next facet: "<<(f+1)<<" --> "<<(nf+1)<<", |"<<
// di[EMAP(e)][diIM(e)]<<" - "<<di[EMAP(e)][nfei_new]<<"| = "<<
// abs(di[EMAP(e)][diIM(e)] - di[EMAP(e)][nfei_new])
// <<endl;
#endif
// Only use this face if not already seen
if(!FH[nf])
{
nfei = nfei_new;
//} else {
// std::cout << "skipping face " << nfei_new << " because it is seen before"
// << std::endl;
}
break;
//} else {
// std::cout << di[EMAP(e)][diIM(e)].transpose() << std::endl;
// std::cout << di[EMAP(e)][diIM(nfei_new)].transpose() << std::endl;
// std::cout << "skipping face " << nfei_new << " with identical dihedral angle"
// << std::endl;
}
//#ifdef IGL_OUTER_HULL_DEBUG
// cout<<"Skipping co-planar facet: "<<(f+1)<<" --> "<<(nf+1)<<endl;
//#endif
}
int max_ne = -1;
if(nfei >= 0)
{
max_ne = uE2E[EMAP(e)][nfei];
}
if(max_ne>=0)
{
// face of neighbor
const int nf = max_ne%m;
#ifdef IGL_OUTER_HULL_DEBUG
if(!FH[nf])
{
// first time seeing face
cout<<(f+1)<<" --> "<<(nf+1)<<endl;
}
#endif
FH[nf] = true;
//std::cout << "face " << face_count++ << ": " << nf << std::endl;
//std::cout << "f " << F.row(nf).array()+1 << std::endl;
FHcount++;
// corner of neighbor
const int nc = max_ne/m;
const int nd = F(nf,(nc+2)%3);
const bool cons = (flip(f)?fd:fs) == nd;
flip(nf) = (cons ? flip(f) : !flip(f));
//cout<<"flip("<<nf<<") = "<<(flip(nf)?"true":"false")<<endl;
const int ne1 = nf+((nc+1)%3)*m;
const int ne2 = nf+((nc+2)%3)*m;
if(!EH[ne1])
{
Q.push(ne1);
}
if(!EH[ne2])
{
Q.push(ne2);
}
}
}
{
vG[id].resize(FHcount,3);
vJ[id].resize(FHcount,1);
//nG += FHcount;
size_t h = 0;
assert(counts(id) == IM.rows());
for(int i = 0;i<counts(id);i++)
{
const size_t f = IM(i);
//if(f_flip)
//{
// flip(f) = !flip(f);
//}
if(FH[f])
{
vG[id].row(h) = (flip(f)?F.row(f).reverse().eval():F.row(f));
vJ[id](h,0) = f;
h++;
}
}
assert((int)h == FHcount);
}
}
// Is A inside B? Assuming A and B are consistently oriented but closed and
// non-intersecting.
const auto & has_overlapping_bbox = [](
const Eigen::MatrixBase<DerivedV> & V,
const MatrixXG & A,
const MatrixXG & B)->bool
{
const auto & bounding_box = [](
const Eigen::MatrixBase<DerivedV> & V,
const MatrixXG & F)->
PlainMatrix<DerivedV,2,3>
{
PlainMatrix<DerivedV,2,3> BB(2,3);
BB<<
1e26,1e26,1e26,
-1e26,-1e26,-1e26;
const size_t m = F.rows();
for(size_t f = 0;f<m;f++)
{
for(size_t c = 0;c<3;c++)
{
const auto & vfc = V.row(F(f,c)).eval();
BB(0,0) = std::min(BB(0,0), vfc(0,0));
BB(0,1) = std::min(BB(0,1), vfc(0,1));
BB(0,2) = std::min(BB(0,2), vfc(0,2));
BB(1,0) = std::max(BB(1,0), vfc(0,0));
BB(1,1) = std::max(BB(1,1), vfc(0,1));
BB(1,2) = std::max(BB(1,2), vfc(0,2));
}
}
return BB;
};
// A lot of the time we're dealing with unrelated, distant components: cull
// them.
PlainMatrix<DerivedV,2,3> ABB = bounding_box(V,A);
PlainMatrix<DerivedV,2,3> BBB = bounding_box(V,B);
if( (BBB.row(0)-ABB.row(1)).maxCoeff()>0 ||
(ABB.row(0)-BBB.row(1)).maxCoeff()>0 )
{
// bounding boxes do not overlap
return false;
} else {
return true;
}
};
// Reject components which are completely inside other components
vector<bool> keep(ncc,true);
size_t nG = 0;
// This is O( ncc * ncc * m)
for(size_t id = 0;id<ncc;id++)
{
if (!keep[id]) continue;
std::vector<size_t> unresolved;
for(size_t oid = 0;oid<ncc;oid++)
{
if(id == oid || !keep[oid])
{
continue;
}
if (has_overlapping_bbox(V, vG[id], vG[oid])) {
unresolved.push_back(oid);
}
}
const size_t num_unresolved_components = unresolved.size();
PlainMatrix<DerivedV,Eigen::Dynamic,3> query_points(num_unresolved_components, 3);
for (size_t i=0; i<num_unresolved_components; i++) {
const size_t oid = unresolved[i];
PlainMatrix<DerivedF,1> f = vG[oid].row(0);
query_points(i,0) = (V(f(0,0), 0) + V(f(0,1), 0) + V(f(0,2), 0))/3.0;
query_points(i,1) = (V(f(0,0), 1) + V(f(0,1), 1) + V(f(0,2), 1))/3.0;
query_points(i,2) = (V(f(0,0), 2) + V(f(0,1), 2) + V(f(0,2), 2))/3.0;
}
Eigen::VectorXi inside;
igl::copyleft::cgal::points_inside_component(V, vG[id], query_points, inside);
assert((size_t)inside.size() == num_unresolved_components);
for (size_t i=0; i<num_unresolved_components; i++) {
if (inside(i, 0)) {
const size_t oid = unresolved[i];
keep[oid] = false;
}
}
}
for (size_t id = 0; id<ncc; id++) {
if (keep[id]) {
nG += vJ[id].rows();
}
}
// collect G and J across components
G.resize(nG,3);
J.resize(nG,1);
{
size_t off = 0;
for(Index id = 0;id<(Index)ncc;id++)
{
if(keep[id])
{
assert(vG[id].rows() == vJ[id].rows());
G.block(off,0,vG[id].rows(),vG[id].cols()) = vG[id];
J.block(off,0,vJ[id].rows(),vJ[id].cols()) = vJ[id];
off += vG[id].rows();
}
}
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::outer_hull_legacy<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_hull_legacy< Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &);
template void igl::copyleft::cgal::outer_hull_legacy<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#ifdef WIN32
#endif
#endif

View File

@ -0,0 +1,57 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_COPYLEFT_CGAL_OUTER_HULL_LEGACY_H
#define IGL_COPYLEFT_CGAL_OUTER_HULL_LEGACY_H
#include "../../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace copyleft
{
namespace cgal
{
/// Compute the "outer hull" of a potentially non-manifold mesh (V,F) whose
/// intersections have been "resolved" (e.g. using `cork` or
/// `igl::copyleft::cgal::selfintersect`). The outer hull is defined to be all facets
/// (regardless of orientation) for which there exists some path from infinity
/// to the face without intersecting any other facets. For solids, this is the
/// surface of the solid. In general this includes any thin "wings" or
/// "flaps". This implementation largely follows Section 3.6 of "Direct
/// repair of self-intersecting meshes" [Attene 2014].
///
/// \note This doesn't require the input mesh to be piecewise constant
/// winding number, but won't handle multiple non-nested connected
/// components.
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @param[out] G #G by 3 list of output triangle indices into V
/// @param[out] J #G list of indices into F
/// @param[out] flip #F list of whether facet was added to G **and** flipped orientation
/// (false for faces not added to G)
template <
typename DerivedV,
typename DerivedF,
typename DerivedG,
typename DerivedJ,
typename Derivedflip>
IGL_INLINE void outer_hull_legacy(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedG> & G,
Eigen::PlainObjectBase<DerivedJ> & J,
Eigen::PlainObjectBase<Derivedflip> & flip);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "outer_hull_legacy.cpp"
#endif
#endif

View File

@ -0,0 +1,103 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
// Copyright (C) 2021 Alec Jacobson <jacobson@cs.toronto.edu>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "outer_vertex.h"
#include "outer_edge.h"
#include <iostream>
#include <vector>
template <
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType,
typename DerivedA
>
IGL_INLINE void igl::copyleft::cgal::outer_vertex(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedI> & I,
IndexType & v_index,
Eigen::PlainObjectBase<DerivedA> & A)
{
// Algorithm:
// Find an outer vertex (i.e. vertex reachable from infinity)
// Return the vertex with the largest X value.
// If there is a tie, pick the one with largest Y value.
// If there is still a tie, pick the one with the largest Z value.
// If there is still a tie, then there are duplicated vertices within the
// mesh, which violates the precondition.
typedef typename DerivedF::Scalar Index;
const Index INVALID = std::numeric_limits<Index>::max();
const size_t num_selected_faces = I.rows();
std::vector<size_t> candidate_faces;
Index outer_vid = INVALID;
typename DerivedV::Scalar outer_val = 0;
for (size_t i=0; i<num_selected_faces; i++)
{
size_t f = I(i);
for (size_t j=0; j<3; j++)
{
Index v = F(f, j);
auto vx = V(v, 0);
if (outer_vid == INVALID || vx > outer_val)
{
outer_val = vx;
outer_vid = v;
candidate_faces = {f};
} else if (v == outer_vid)
{
candidate_faces.push_back(f);
} else if (vx == outer_val)
{
// Break tie.
auto vy = V(v,1);
auto vz = V(v, 2);
auto outer_y = V(outer_vid, 1);
auto outer_z = V(outer_vid, 2);
assert(!(vy == outer_y && vz == outer_z));
bool replace = (vy > outer_y) ||
((vy == outer_y) && (vz > outer_z));
if (replace)
{
outer_val = vx;
outer_vid = v;
candidate_faces = {f};
}
}
}
}
assert(outer_vid != INVALID);
assert(candidate_faces.size() > 0);
v_index = outer_vid;
A.resize(candidate_faces.size());
std::copy(candidate_faces.begin(), candidate_faces.end(), A.data());
}
#ifdef IGL_STATIC_LIBRARY
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
// Explicit template instantiation
// generated by autoexplicit.sh
#include <cstdint>
template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
// Linux
template void igl::copyleft::cgal::outer_vertex<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t, Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, Eigen::PlainObjectBase<Eigen::Matrix<std::ptrdiff_t, -1, 1, 0, -1, 1> >&);
#ifdef WIN32
template void __cdecl igl::copyleft::cgal::outer_vertex<class Eigen::Matrix<class CGAL::Epeck::FT,-1,-1,0,-1,-1>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<long,-1,1,0,-1,1>,__int64,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::MatrixBase<class Eigen::Matrix<class CGAL::Epeck::FT,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<long,-1,1,0,-1,1> > const &,__int64 &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
template void __cdecl igl::copyleft::cgal::outer_vertex<class Eigen::Matrix<double,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,1,0,-1,1>,__int64,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::MatrixBase<class Eigen::Matrix<double,-1,3,0,-1,3> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,3,0,-1,3> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,1,0,-1,1> > const &,__int64 &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
template void __cdecl igl::copyleft::cgal::outer_vertex<class Eigen::Matrix<double,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,3,0,-1,3>,class Eigen::Matrix<long,-1,1,0,-1,1>,__int64,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::MatrixBase<class Eigen::Matrix<double,-1,3,0,-1,3> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,3,0,-1,3> > const &,class Eigen::MatrixBase<class Eigen::Matrix<long,-1,1,0,-1,1> > const &,__int64 &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
#endif
#endif

View File

@ -0,0 +1,52 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Qingan Zhou <qnzhou@gmail.com>
// Copyright (C) 2021 Alec Jacobson <jacobson@cs.toronto.edu>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_COPYLEFT_CGAL_OUTER_VERTEX_H
#define IGL_COPYLEFT_CGAL_OUTER_VERTEX_H
#include "../../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace copyleft
{
namespace cgal
{
/// Find a vertex that is reachable from infinite without crossing any faces.
/// Such vertex is called "outer vertex."
///
/// \pre The input mesh must have all self-intersection resolved and
/// no duplicated vertices. See cgal::remesh_self_intersections.h for how to
/// obtain such input.
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @param[in] I #I list of facets to consider
/// @param[out] v_index index of outer vertex
/// @param[out] A #A list of facets incident to the outer vertex
template <
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename IndexType,
typename DerivedA
>
IGL_INLINE void outer_vertex(
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedI> & I,
IndexType & v_index,
Eigen::PlainObjectBase<DerivedA> & A);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "outer_vertex.cpp"
#endif
#endif

View File

@ -1,12 +1,12 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "peel_outer_hull_layers.h"
#include "outer_hull.h"
#include "outer_hull_legacy.h"
#include "../../LinSpaced.h"
#include <vector>
#include <iostream>
@ -22,19 +22,18 @@ template <
typename DerivedF,
typename DerivedI,
typename Derivedflip>
IGL_INLINE size_t igl::copyleft::cgal::peel_outer_hull_layers(
const Eigen::PlainObjectBase<DerivedV > & V,
const Eigen::PlainObjectBase<DerivedF > & F,
IGL_INLINE int igl::copyleft::cgal::peel_outer_hull_layers(
const Eigen::MatrixBase<DerivedV > & V,
const Eigen::MatrixBase<DerivedF > & F,
Eigen::PlainObjectBase<DerivedI> & I,
Eigen::PlainObjectBase<Derivedflip > & flip)
{
using namespace Eigen;
using namespace std;
typedef typename DerivedF::Index Index;
typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
typedef Matrix<Index,Dynamic,1> MatrixXI;
typedef Matrix<int,Dynamic,1> MatrixXI;
typedef Matrix<typename Derivedflip::Scalar,Dynamic,Derivedflip::ColsAtCompileTime> MatrixXflip;
const Index m = F.rows();
const int m = F.rows();
#ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
cout<<"peel outer hull layers..."<<endl;
#endif
@ -54,7 +53,7 @@ IGL_INLINE size_t igl::copyleft::cgal::peel_outer_hull_layers(
MatrixXI IM = igl::LinSpaced<MatrixXI >(m,0,m-1);
// This is O(n * layers)
MatrixXI P(m,1);
Index iter = 0;
int iter = 0;
while(Fr.size() > 0)
{
assert(Fr.rows() == IM.rows());
@ -84,7 +83,7 @@ IGL_INLINE size_t igl::copyleft::cgal::peel_outer_hull_layers(
assert(Fo.rows() == Jo.rows());
// all faces in Fo of Fr
vector<bool> in_outer(Fr.rows(),false);
for(Index g = 0;g<Jo.rows();g++)
for(int g = 0;g<Jo.rows();g++)
{
I(IM(Jo(g))) = iter;
P(IM(Jo(g))) = iter;
@ -98,8 +97,8 @@ IGL_INLINE size_t igl::copyleft::cgal::peel_outer_hull_layers(
Fr.resize(prev_Fr.rows() - Fo.rows(),F.cols());
IM.resize(Fr.rows());
{
Index g = 0;
for(Index f = 0;f<prev_Fr.rows();f++)
int g = 0;
for(int f = 0;f<prev_Fr.rows();f++)
{
if(!in_outer[f])
{
@ -116,9 +115,8 @@ IGL_INLINE size_t igl::copyleft::cgal::peel_outer_hull_layers(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
template unsigned long igl::copyleft::cgal::peel_outer_hull_layers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template size_t igl::copyleft::cgal::peel_outer_hull_layers<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
// generated by autoexplicit.sh
template int igl::copyleft::cgal::peel_outer_hull_layers<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#endif

View File

@ -15,26 +15,24 @@ namespace igl
{
namespace cgal
{
// Computes necessary generic information for boolean operations by
// successively "peeling" off the "outer hull" of a mesh (V,F) resulting from
// "resolving" all (self-)intersections.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices into V
// Outputs:
// I #F list of which peel Iation a facet belongs
// flip #F list of whether a facet's orientation was flipped when facet
// "peeled" into its associated outer hull layer.
// Returns number of peels
/// Computes necessary generic information for boolean operations by
/// successively "peeling" off the "outer hull" of a mesh (V,F) resulting from
/// "resolving" all (self-)intersections.
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @param[out] I #F list of which peel Iation a facet belongs
/// @param[out] flip #F list of whether a facet's orientation was flipped when facet
/// "peeled" into its associated outer hull layer.
/// @return number of peels
template <
typename DerivedV,
typename DerivedF,
typename DerivedI,
typename Derivedflip>
IGL_INLINE size_t peel_outer_hull_layers(
const Eigen::PlainObjectBase<DerivedV > & V,
const Eigen::PlainObjectBase<DerivedF > & F,
IGL_INLINE int peel_outer_hull_layers(
const Eigen::MatrixBase<DerivedV > & V,
const Eigen::MatrixBase<DerivedF > & F,
Eigen::PlainObjectBase<DerivedI > & I,
Eigen::PlainObjectBase<Derivedflip > & flip);
}

View File

@ -9,8 +9,8 @@ typename DerivedV,
typename DerivedF,
typename DerivedW >
IGL_INLINE size_t igl::copyleft::cgal::peel_winding_number_layers(
const Eigen::PlainObjectBase<DerivedV > & V,
const Eigen::PlainObjectBase<DerivedF > & F,
const Eigen::MatrixBase<DerivedV > & V,
const Eigen::MatrixBase<DerivedF > & F,
Eigen::PlainObjectBase<DerivedW>& W) {
const size_t num_faces = F.rows();
Eigen::VectorXi labels(num_faces);

View File

@ -6,14 +6,19 @@
namespace igl {
namespace copyleft {
namespace cgal {
template<
typename DerivedV,
typename DerivedF,
typename DerivedW >
IGL_INLINE size_t peel_winding_number_layers(
const Eigen::PlainObjectBase<DerivedV > & V,
const Eigen::PlainObjectBase<DerivedF > & F,
Eigen::PlainObjectBase<DerivedW>& W);
/// Peel Winding number layers from a mesh
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @param[out] W #V by 1 list of winding numbers
template<
typename DerivedV,
typename DerivedF,
typename DerivedW >
IGL_INLINE size_t peel_winding_number_layers(
const Eigen::MatrixBase<DerivedV > & V,
const Eigen::MatrixBase<DerivedF > & F,
Eigen::PlainObjectBase<DerivedW>& W);
}
}
}

View File

@ -13,8 +13,8 @@
template < typename DerivedV, typename DerivedF>
IGL_INLINE bool igl::copyleft::cgal::piecewise_constant_winding_number(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F)
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F)
{
Eigen::Matrix<CGAL::Epeck::FT,Eigen::Dynamic,3> VV;
Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,3> FF;
@ -25,3 +25,9 @@ IGL_INLINE bool igl::copyleft::cgal::piecewise_constant_winding_number(
remesh_self_intersections(V,F,{false,false,true},VV,FF,IF,J,IM);
return igl::piecewise_constant_winding_number(FF);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::piecewise_constant_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
#endif

View File

@ -16,21 +16,19 @@ namespace igl
{
namespace cgal
{
// PIECEWISE_CONSTANT_WINDING_NUMBER Determine if a given mesh induces a
// piecewise constant winding number field: Is this mesh valid input to
// solid set operations.
//
// Inputs:
// V #V by 3 list of mesh vertex positions
// F #F by 3 list of triangle indices into V
// Returns true if the mesh _combinatorially_ induces a piecewise
// constant winding number field.
/// Determine if a given mesh induces a piecewise constant winding number
/// field: Is this mesh valid input to solid set operations.
///
/// @param[in] V #V by 3 list of mesh vertex positions
/// @param[in] F #F by 3 list of triangle indices into V
/// @return true if the mesh _combinatorially_ induces a piecewise
/// constant winding number field.
template <
typename DerivedV,
typename DerivedF>
IGL_INLINE bool piecewise_constant_winding_number(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF>& F);
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF>& F);
}
}
}

View File

@ -1,10 +1,9 @@
#include "point_areas.h"
#include "delaunay_triangulation.h"
#include "../../colon.h"
#include "../../slice.h"
#include "../../slice_mask.h"
#include "../../find.h"
#include "../../parallel_for.h"
#include "../../placeholders.h"
#include "CGAL/Exact_predicates_inexact_constructions_kernel.h"
#include "CGAL/Triangulation_vertex_base_with_info_2.h"
@ -49,12 +48,9 @@ namespace igl {
typedef typename DerivedN::Scalar scalarN;
typedef typename DerivedA::Scalar scalarA;
typedef Eigen::Matrix<real,1,3> RowVec3;
typedef Eigen::Matrix<real,1,2> RowVec2;
typedef Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> MatrixP;
typedef Eigen::Matrix<scalarN, Eigen::Dynamic, Eigen::Dynamic> MatrixN;
typedef Eigen::Matrix<typename DerivedN::Scalar,
Eigen::Dynamic, Eigen::Dynamic> VecotorO;
typedef Eigen::Matrix<typename DerivedI::Scalar,
Eigen::Dynamic, Eigen::Dynamic> MatrixI;
@ -72,19 +68,18 @@ namespace igl {
T.setZero(n,3);
igl::parallel_for(P.rows(),[&](int i)
{
MatrixI neighbor_index = I.row(i);
MatrixP neighbors;
igl::slice(P,neighbor_index,1,neighbors);
neighbors = P(I.row(i),igl::placeholders::all);
if(N.rows() && neighbors.rows() > 1){
MatrixN neighbor_normals;
igl::slice(N,neighbor_index,1,neighbor_normals);
neighbor_normals = N(I.row(i),igl::placeholders::all);
Eigen::Matrix<scalarN,1,3> poi_normal = neighbor_normals.row(0);
Eigen::Matrix<scalarN,Eigen::Dynamic,1> dotprod =
poi_normal(0)*neighbor_normals.col(0)
+ poi_normal(1)*neighbor_normals.col(1)
+ poi_normal(2)*neighbor_normals.col(2);
Eigen::Array<bool,Eigen::Dynamic,1> keep = dotprod.array() > 0;
igl::slice_mask(Eigen::MatrixXd(neighbors),keep,1,neighbors);
neighbors = neighbors(igl::find(keep),igl::placeholders::all).eval();
}
if(neighbors.rows() <= 2){
A(i) = 0;
@ -102,9 +97,7 @@ namespace igl {
T.row(i) *= -1;
}
MatrixP plane;
igl::slice(scores,igl::colon<int>(0,scores.rows()-1),
igl::colon<int>(0,1),plane);
MatrixP plane = scores(igl::placeholders::all,{0,1});
std::vector< std::pair<Point,unsigned> > points;
//This is where we obtain a delaunay triangulation of the points
@ -179,3 +172,8 @@ namespace igl {
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::point_areas<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<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
#endif

View File

@ -16,56 +16,46 @@ namespace igl
{
namespace cgal
{
// Given a 3D set of points P, each with a list of k-nearest-neighbours,
// estimate the geodesic voronoi area associated with each point.
//
// The k nearest neighbours may be known from running igl::knn_octree on
// the output data from igl::octree. We reccomend using a k value
// between 15 and 20 inclusive for accurate area estimation.
//
// N is used filter the neighbours, to ensure area estimation only occurs
// using neighbors that are on the same side of the surface (ie for thin
// sheets), as well as to solve the orientation ambiguity of the tangent
// plane normal.
//
// Note: This function *should* be implemented by pre-filtering I, rather
// than filtering in this function using N. In this case, the function
// would only take P and I as input.
//
// Inputs:
// P #P by 3 list of point locations
// I #P by k list of k-nearest-neighbor indices into P
// N #P by 3 list of point normals
// Outputs:
// A #P list of estimated areas
template <typename DerivedP, typename DerivedI, typename DerivedN,
typename DerivedA>
IGL_INLINE void point_areas(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedN>& N,
Eigen::PlainObjectBase<DerivedA> & A);
// This version can be used to output the tangent plane normal at each
// point. Since we area already fitting a plane to each point's neighbour
// set, the tangent plane normals come "for free"
//
// Inputs:
// P #P by 3 list of point locations
// I #P by k list of k-nearest-neighbor indices into P
// N #P by 3 list of point normals
// Outputs:
// A #P list of estimated areas
// T #P by 3 list of tangent plane normals for each point
template <typename DerivedP, typename DerivedI, typename DerivedN,
typename DerivedA, typename DerivedT>
IGL_INLINE void point_areas(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedN>& N,
Eigen::PlainObjectBase<DerivedA> & A,
Eigen::PlainObjectBase<DerivedT> & T);
/// Given a 3D set of points P, each with a list of k-nearest-neighbours,
/// estimate the geodesic voronoi area associated with each point.
///
/// The k nearest neighbours may be known from running igl::knn_octree on
/// the output data from igl::octree. We reccomend using a k value
/// between 15 and 20 inclusive for accurate area estimation.
///
/// N is used filter the neighbours, to ensure area estimation only occurs
/// using neighbors that are on the same side of the surface (ie for thin
/// sheets), as well as to solve the orientation ambiguity of the tangent
/// plane normal.
///
/// \note This function *should* be implemented by pre-filtering I, rather
/// than filtering in this function using N. In this case, the function
/// would only take P and I as input.
///
/// @param[in] P #P by 3 list of point locations
/// @param[in] I #P by k list of k-nearest-neighbor indices into P
/// @param[in] N #P by 3 list of point normals
/// @param[out] A #P list of estimated areas
// @param[out] T #P by 3 list of tangent plane normals for each point
///
/// \see igl::knn
template <typename DerivedP, typename DerivedI, typename DerivedN,
typename DerivedA, typename DerivedT>
IGL_INLINE void point_areas(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedN>& N,
Eigen::PlainObjectBase<DerivedA> & A,
Eigen::PlainObjectBase<DerivedT> & T);
/// \overload
template <typename DerivedP, typename DerivedI, typename DerivedN,
typename DerivedA>
IGL_INLINE void point_areas(
const Eigen::MatrixBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedN>& N,
Eigen::PlainObjectBase<DerivedA> & A);
}
}
}

View File

@ -8,6 +8,7 @@
#include "point_mesh_squared_distance.h"
#include "mesh_to_cgal_triangle_list.h"
#include "assign_scalar.h"
#include "../../parallel_for.h"
template <
typename Kernel,
@ -18,9 +19,9 @@ template <
typename DerivedI,
typename DerivedC>
IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
const Eigen::PlainObjectBase<DerivedP> & P,
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedP> & P,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
Eigen::PlainObjectBase<DerivedI> & I,
Eigen::PlainObjectBase<DerivedC> & C)
@ -39,8 +40,8 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
template <typename Kernel, typename DerivedV, typename DerivedF>
IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance_precompute(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
CGAL::AABB_tree<
CGAL::AABB_traits<Kernel,
CGAL::AABB_triangle_primitive<Kernel,
@ -52,12 +53,7 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance_precompute(
{
using namespace std;
typedef CGAL::Triangle_3<Kernel> Triangle_3;
typedef CGAL::Point_3<Kernel> Point_3;
typedef typename std::vector<Triangle_3>::iterator Iterator;
typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
// Must be 3D
assert(V.cols() == 3);
@ -92,7 +88,7 @@ template <
typename DerivedI,
typename DerivedC>
IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
const Eigen::PlainObjectBase<DerivedP> & P,
const Eigen::MatrixBase<DerivedP> & P,
const CGAL::AABB_tree<
CGAL::AABB_traits<Kernel,
CGAL::AABB_triangle_primitive<Kernel,
@ -117,7 +113,8 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
sqrD.resize(n,1);
I.resize(n,1);
C.resize(n,P.cols());
for(int p = 0;p < n;p++)
//for(int p = 0;p < n;p++)
igl::parallel_for(n,[&](const int p)
{
Point_3 query(P(p,0),P(p,1),P(p,2));
// Find closest point and primitive id
@ -128,11 +125,16 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
assign_scalar(closest_point[2],C(p,2));
assign_scalar((closest_point-query).squared_length(),sqrD(p));
I(p) = pp.second - T.begin();
}
},1000);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -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&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, 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<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Simple_cartesian<double>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&);
template void igl::copyleft::cgal::point_mesh_squared_distance_precompute<CGAL::Simple_cartesian<double>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> >&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
template void igl::copyleft::cgal::point_mesh_squared_distance_precompute<CGAL::Simple_cartesian<double>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> >&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
#endif

View File

@ -17,22 +17,19 @@ namespace igl
{
namespace cgal
{
// Compute distances from a set of points P to a triangle mesh (V,F)
//
// Templates:
// Kernal CGAL computation and construction kernel (e.g.
// CGAL::Simple_cartesian<double>)
// Inputs:
// P #P by 3 list of query point positions
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices
// Outputs:
// sqrD #P list of smallest squared distances
// I #P list of facet indices corresponding to smallest distances
// C #P by 3 list of closest points
//
// Known bugs: This only computes distances to triangles. So unreferenced
// vertices and degenerate triangles (segments) are ignored.
/// Compute distances from a set of points P to a triangle mesh (V,F)
///
/// @tparam Kernal CGAL computation and construction kernel (e.g.
/// CGAL::Simple_cartesian<double>)
/// @param[in] P #P by 3 list of query point positions
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices
/// @param[out] sqrD #P list of smallest squared distances
/// @param[out] I #P list of facet indices corresponding to smallest distances
/// @param[out] C #P by 3 list of closest points
///
/// \bug This only computes distances to triangles. So unreferenced
/// vertices and degenerate triangles (segments) are ignored.
template <
typename Kernel,
typename DerivedP,
@ -42,26 +39,29 @@ namespace igl
typename DerivedI,
typename DerivedC>
IGL_INLINE void point_mesh_squared_distance(
const Eigen::PlainObjectBase<DerivedP> & P,
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedP> & P,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedsqrD> & sqrD,
Eigen::PlainObjectBase<DerivedI> & I,
Eigen::PlainObjectBase<DerivedC> & C);
// Probably can do this in a way that we don't pass around `tree` and `T`
//
// Outputs:
// tree CGAL's AABB tree
// T list of CGAL triangles in order of F (for determining which was found
// in computation)
/// precomputation for point_mesh_squared_distance
///
/// @param[in] V #V by 3 list of vertex positions
/// @param[in] F #F by 3 list of triangle indices
/// @param[out] tree CGAL's AABB tree
/// @param[out] T list of CGAL triangles in order of F (for determining which was found
/// in computation)
///
/// \fileinfo
template <
typename Kernel,
typename DerivedV,
typename DerivedF
>
IGL_INLINE void point_mesh_squared_distance_precompute(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
CGAL::AABB_tree<
CGAL::AABB_traits<Kernel,
CGAL::AABB_triangle_primitive<Kernel,
@ -70,10 +70,16 @@ namespace igl
>
> & tree,
std::vector<CGAL::Triangle_3<Kernel> > & T);
// Inputs:
// see above
// Outputs:
// see above
/// Compute distances from a set of points P to a triangle mesh (V,F)
/// using precomputed trees.
///
/// @param[in] P #P by 3 list of query point positions
/// @param[in] tree CGAL's AABB tree
/// @param[in] T list of CGAL triangles in order of F (for determining which was found
/// in computation)
/// @param[out] sqrD #P list of smallest squared distances
/// @param[out] I #P list of facet indices corresponding to smallest distances
/// @param[out] C #P by 3 list of closest points
template <
typename Kernel,
typename DerivedP,
@ -81,7 +87,7 @@ namespace igl
typename DerivedI,
typename DerivedC>
IGL_INLINE void point_mesh_squared_distance(
const Eigen::PlainObjectBase<DerivedP> & P,
const Eigen::MatrixBase<DerivedP> & P,
const CGAL::AABB_tree<
CGAL::AABB_traits<Kernel,
CGAL::AABB_triangle_primitive<Kernel,

View File

@ -16,22 +16,19 @@ namespace igl
{
namespace cgal
{
// Given a point P1 and segment S2 find the points on each of closest
// approach and the squared distance thereof.
//
// Inputs:
// P1 point
// S2 segment
// Outputs:
// P2 point on S2 closest to P1
// d distance betwee P1 and S2
/// Given a point P1 and segment S2 find the points on each of closest
/// approach and the squared distance thereof.
///
/// @param[in] P1 point
/// @param[in] S2 segment
/// @param[out] P2 point on S2 closest to P1
/// @param[out] d distance betwee P1 and S2
template < typename Kernel>
IGL_INLINE void point_segment_squared_distance(
const CGAL::Point_3<Kernel> & P1,
const CGAL::Segment_3<Kernel> & S2,
CGAL::Point_3<Kernel> & P2,
typename Kernel::FT & d
);
typename Kernel::FT & d);
}
}

View File

@ -8,8 +8,12 @@
#include "point_solid_signed_squared_distance.h"
#include "points_inside_component.h"
#include "point_mesh_squared_distance.h"
#include "../../get_seconds.h"
#include "../../list_to_matrix.h"
#include "../../slice_mask.h"
#include "../../find.h"
#include "../../placeholders.h"
#include "../../parallel_for.h"
#include "../../PlainMatrix.h"
#include <vector>
#include <Eigen/Core>
@ -19,20 +23,19 @@ template <
typename DerivedFB,
typename DerivedD>
IGL_INLINE void igl::copyleft::cgal::point_solid_signed_squared_distance(
const Eigen::PlainObjectBase<DerivedQ> & Q,
const Eigen::PlainObjectBase<DerivedVB> & VB,
const Eigen::PlainObjectBase<DerivedFB> & FB,
const Eigen::MatrixBase<DerivedQ> & Q,
const Eigen::MatrixBase<DerivedVB> & VB,
const Eigen::MatrixBase<DerivedFB> & FB,
Eigen::PlainObjectBase<DerivedD> & D)
{
// compute unsigned distances
Eigen::VectorXi I;
DerivedVB C;
PlainMatrix<DerivedVB,Eigen::Dynamic> C;
point_mesh_squared_distance<CGAL::Epeck>(Q,VB,FB,D,I,C);
// Collect queries that have non-zero distance
Eigen::Array<bool,Eigen::Dynamic,1> NZ = D.array()!=0;
// Compute sign for non-zero distance queries
DerivedQ QNZ;
slice_mask(Q,NZ,1,QNZ);
PlainMatrix<DerivedQ,Eigen::Dynamic> QNZ = Q(igl::find(NZ),igl::placeholders::all);
Eigen::Array<bool,Eigen::Dynamic,1> DNZ;
igl::copyleft::cgal::points_inside_component(VB,FB,QNZ,DNZ);
// Apply sign to distances
@ -51,6 +54,5 @@ IGL_INLINE void igl::copyleft::cgal::point_solid_signed_squared_distance(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::point_solid_signed_squared_distance<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, 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<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::point_solid_signed_squared_distance<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 1, 0, -1, 1> >&);
#endif

View File

@ -16,26 +16,24 @@ namespace igl
{
namespace cgal
{
// POINT_SOLID_SIGNED_SQUARED_DISTANCE Given a set of points (Q) and the
// boundary mesh (VB,FB) of a solid (as defined in [Zhou et al. 2016],
// determine the signed squared distance for each point q in Q so that d(q,B) is
// negative if inside and positive if outside.
//
// Inputs:
// Q #Q by 3 list of query point positions
// VB #VB by 3 list of mesh vertex positions of B
// FB #FB by 3 list of mesh triangle indices into VB
// Outputs:
// D
/// Given a set of points (Q) and the boundary mesh (VB,FB) of a solid (as
/// defined in [Zhou et al. 2016], determine the signed squared distance
/// for each point q in Q so that d(q,B) is negative if inside and positive
/// if outside.
///
/// @param[in] Q #Q by 3 list of query point positions
/// @param[in] VB #VB by 3 list of mesh vertex positions of B
/// @param[in] FB #FB by 3 list of mesh triangle indices into VB
/// @param[out] D #Q list of signed squared distances
template <
typename DerivedQ,
typename DerivedVB,
typename DerivedFB,
typename DerivedD>
IGL_INLINE void point_solid_signed_squared_distance(
const Eigen::PlainObjectBase<DerivedQ> & Q,
const Eigen::PlainObjectBase<DerivedVB> & VB,
const Eigen::PlainObjectBase<DerivedFB> & FB,
const Eigen::MatrixBase<DerivedQ> & Q,
const Eigen::MatrixBase<DerivedVB> & VB,
const Eigen::MatrixBase<DerivedFB> & FB,
Eigen::PlainObjectBase<DerivedD> & D);
}
}

View File

@ -16,15 +16,13 @@ namespace igl
{
namespace cgal
{
// Given a point P1 and triangle T2 find the points on each of closest
// approach and the squared distance thereof.
//
// Inputs:
// P1 point
// T2 triangle
// Outputs:
// P2 point on T2 closest to P1
// d distance betwee P1 and T2
/// Given a point P1 and triangle T2 find the points on each of closest
/// approach and the squared distance thereof.
///
/// @param[in] P1 point
/// @param[in] T2 triangle
/// @param[out] P2 point on T2 closest to P1
/// @param[out] d distance betwee P1 and T2
template < typename Kernel>
IGL_INLINE void point_triangle_squared_distance(
const CGAL::Point_3<Kernel> & P1,

View File

@ -7,6 +7,8 @@
// obtain one at http://mozilla.org/MPL/2.0/.
#include "points_inside_component.h"
#include "../../LinSpaced.h"
#include "../../parallel_for.h"
#include "../../PlainMatrix.h"
#include "order_facets_around_edge.h"
#include "assign_scalar.h"
@ -39,13 +41,13 @@ namespace igl {
template<typename DerivedF, typename DerivedI>
void extract_adj_faces(
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const size_t s, const size_t d,
std::vector<int>& adj_faces) {
const size_t num_faces = I.rows();
for (size_t i=0; i<num_faces; i++) {
Eigen::Vector3i f = F.row(I(i, 0));
Eigen::Matrix<typename DerivedF::Scalar,3,1> f = F.row(I(i, 0));
if (((size_t)f[0] == s && (size_t)f[1] == d) ||
((size_t)f[1] == s && (size_t)f[2] == d) ||
((size_t)f[2] == s && (size_t)f[0] == d)) {
@ -63,13 +65,13 @@ namespace igl {
template<typename DerivedF, typename DerivedI>
void extract_adj_vertices(
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const size_t v, std::vector<int>& adj_vertices) {
std::set<size_t> unique_adj_vertices;
const size_t num_faces = I.rows();
for (size_t i=0; i<num_faces; i++) {
Eigen::Vector3i f = F.row(I(i, 0));
Eigen::Matrix<typename DerivedF::Scalar,3,1> f = F.row(I(i, 0));
if ((size_t)f[0] == v) {
unique_adj_vertices.insert(f[1]);
unique_adj_vertices.insert(f[2]);
@ -89,9 +91,9 @@ namespace igl {
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 Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Point_3& query, size_t s, size_t d) {
// Algorithm:
//
@ -131,11 +133,12 @@ namespace igl {
const size_t num_adj_faces = adj_faces.size();
assert(num_adj_faces > 0);
DerivedV pivot_point(1, 3);
PlainMatrix<DerivedV,1> pivot_point(1, 3);
igl::copyleft::cgal::assign_scalar(query.x(), pivot_point(0, 0));
igl::copyleft::cgal::assign_scalar(query.y(), pivot_point(0, 1));
igl::copyleft::cgal::assign_scalar(query.z(), pivot_point(0, 2));
Eigen::VectorXi order;
using VectorXI = Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, 1>;
VectorXI order;
order_facets_around_edge(V, F, s, d,
adj_faces, pivot_point, order);
assert((size_t)order.size() == num_adj_faces);
@ -154,9 +157,9 @@ namespace igl {
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 Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Point_3& query, size_t s) {
std::vector<int> adj_vertices;
extract_adj_vertices(F, I, s, adj_vertices);
@ -173,7 +176,6 @@ namespace igl {
auto is_on_exterior = [&](const Plane_3& separator) -> bool{
size_t positive=0;
size_t negative=0;
size_t coplanar=0;
for (const auto& point : adj_points) {
switch(separator.oriented_side(point)) {
case CGAL::ON_POSITIVE_SIDE:
@ -183,7 +185,6 @@ namespace igl {
negative++;
break;
case CGAL::ON_ORIENTED_BOUNDARY:
coplanar++;
break;
default:
throw "Unknown plane-point orientation";
@ -223,14 +224,14 @@ namespace igl {
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 Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Point_3& query, size_t fid) {
// Algorithm: A point is on the inside of a face if the
// tetrahedron formed by them is negatively oriented.
Eigen::Vector3i f = F.row(I(fid, 0));
Eigen::Matrix<typename DerivedF::Scalar,3,1> f = F.row(I(fid, 0));
const Point_3 v0(V(f[0], 0), V(f[0], 1), V(f[0], 2));
const Point_3 v1(V(f[1], 0), V(f[1], 1), V(f[1], 2));
const Point_3 v2(V(f[2], 0), V(f[2], 1), V(f[2], 2));
@ -248,10 +249,10 @@ namespace igl {
template<typename DerivedV, typename DerivedF, typename DerivedI,
typename DerivedP, typename DerivedB>
IGL_INLINE void igl::copyleft::cgal::points_inside_component(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedI>& I,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedP>& P,
Eigen::PlainObjectBase<DerivedB>& inside) {
using namespace igl::copyleft::cgal::points_inside_component_helper;
if (F.rows() <= 0 || I.rows() <= 0) {
@ -261,7 +262,7 @@ IGL_INLINE void igl::copyleft::cgal::points_inside_component(
const size_t num_faces = I.rows();
std::vector<Triangle> triangles;
for (size_t i=0; i<num_faces; i++) {
const Eigen::Vector3i f = F.row(I(i, 0));
const Eigen::Matrix<typename DerivedF::Scalar,3,1> f = F.row(I(i, 0));
triangles.emplace_back(
Point_3(V(f[0], 0), V(f[0], 1), V(f[0], 2)),
Point_3(V(f[1], 0), V(f[1], 1), V(f[1], 2)),
@ -276,7 +277,7 @@ IGL_INLINE void igl::copyleft::cgal::points_inside_component(
enum ElementType { VERTEX, EDGE, FACE };
auto determine_element_type = [&](
size_t fid, const Point_3& p, size_t& element_index) -> ElementType{
const Eigen::Vector3i f = F.row(I(fid, 0));
const Eigen::Matrix<typename DerivedF::Scalar,3,1> f = F.row(I(fid, 0));
const Point_3 p0(V(f[0], 0), V(f[0], 1), V(f[0], 2));
const Point_3 p1(V(f[1], 0), V(f[1], 1), V(f[1], 2));
const Point_3 p2(V(f[2], 0), V(f[2], 1), V(f[2], 2));
@ -294,7 +295,8 @@ IGL_INLINE void igl::copyleft::cgal::points_inside_component(
const size_t num_queries = P.rows();
inside.resize(num_queries, 1);
for (size_t i=0; i<num_queries; i++) {
//for (size_t i=0; i<num_queries; i++) {
igl::parallel_for(num_queries, [&](const int i) {
const Point_3 query(P(i,0), P(i,1), P(i,2));
auto projection = tree.closest_point_and_primitive(query);
auto closest_point = projection.first;
@ -305,7 +307,7 @@ IGL_INLINE void igl::copyleft::cgal::points_inside_component(
case VERTEX:
{
const size_t s = F(I(fid, 0), element_index);
inside(i,0) = determine_point_vertex_orientation(
inside(i) = determine_point_vertex_orientation(
V, F, I, query, s);
}
break;
@ -313,38 +315,42 @@ IGL_INLINE void igl::copyleft::cgal::points_inside_component(
{
const size_t s = F(I(fid, 0), (element_index+1)%3);
const size_t d = F(I(fid, 0), (element_index+2)%3);
inside(i,0) = determine_point_edge_orientation(
inside(i) = determine_point_edge_orientation(
V, F, I, query, s, d);
}
break;
case FACE:
inside(i,0) = determine_point_face_orientation(V, F, I, query, fid);
inside(i) = determine_point_face_orientation(V, F, I, query, fid);
break;
default:
throw "Unknown closest element type!";
}
}
}, 1000);
}
template<typename DerivedV, typename DerivedF, typename DerivedP,
typename DerivedB>
IGL_INLINE void igl::copyleft::cgal::points_inside_component(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedP>& P,
Eigen::PlainObjectBase<DerivedB>& inside) {
Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi>(F.rows(), 0, F.rows()-1);
using VectorXI = Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, 1>;
VectorXI I = igl::LinSpaced<VectorXI>(F.rows(), 0, F.rows()-1);
igl::copyleft::cgal::points_inside_component(V, F, I, P, inside);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Array<bool, -1, 1, 0, -1, 1> >(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<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::points_inside_component< Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix< int, -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> > ( 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&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::points_inside_component< 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> > ( 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> >&);
template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::points_inside_component<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<int, -1, 1, 0, -1, 1> >(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<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::points_inside_component<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> >(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> >&);
template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::points_inside_component<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>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
// generated by autoexplicit.sh
template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1>>&);
template void igl::copyleft::cgal::points_inside_component< Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix< int, -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> > ( Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::points_inside_component< 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> > ( Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix< int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::points_inside_component<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, Eigen::Array<bool, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::points_inside_component<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> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::copyleft::cgal::points_inside_component<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<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#endif

View File

@ -17,25 +17,20 @@ namespace igl
namespace copyleft
{
namespace cgal {
// Determine if queries points P are inside of connected facet component
// (V, F, I), where I indicates a subset of facets that forms the
// component.
//
// Precondition:
// The input mesh must be a closed, self-intersection free,
// non-degenerated surface. Queries points must be either inside or
// outside of the mesh (i.e. not on the surface of the mesh).
//
// Inputs:
// V #V by 3 array of vertex positions.
// F #F by 3 array of triangles.
// I #I list of triangle indices to consider.
// P #P by 3 array of query points.
//
// Outputs:
// inside #P list of booleans that is true iff the corresponding
// query point is inside of the mesh.
/// Determine if queries points P are inside of connected facet component
/// (V, F, I), where I indicates a subset of facets that forms the
/// component.
///
/// \pre The input mesh must be a closed, self-intersection free,
/// non-degenerated surface. Queries points must be either inside or
/// outside of the mesh (i.e. not on the surface of the mesh).
///
/// @param[in] V #V by 3 array of vertex positions.
/// @param[in] F #F by 3 array of triangles.
/// @param[in] I #I list of triangle indices to consider.
/// @param[in] P #P by 3 array of query points.
/// @param[out] inside #P list of booleans that is true iff the
/// corresponding query point is inside of the mesh.
template<
typename DerivedV,
typename DerivedF,
@ -43,23 +38,21 @@ namespace igl
typename DerivedP,
typename DerivedB>
IGL_INLINE void points_inside_component(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedI>& I,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedI>& I,
const Eigen::MatrixBase<DerivedP>& P,
Eigen::PlainObjectBase<DerivedB>& inside);
// Determine if query points P is inside of the mesh (V, F).
// See above for precondition and I/O specs.
/// \overload
template<
typename DerivedV,
typename DerivedF,
typename DerivedP,
typename DerivedB>
IGL_INLINE void points_inside_component(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedP>& P,
Eigen::PlainObjectBase<DerivedB>& inside);
}
}

View File

@ -7,6 +7,7 @@
// obtain one at http://mozilla.org/MPL/2.0/.
#include "polyhedron_to_mesh.h"
#include <CGAL/Polyhedron_3.h>
#include "assign_scalar.h"
template <
typename Polyhedron,
@ -29,9 +30,9 @@ IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
p != poly.vertices_end();
p++)
{
V(v,0) = p->point().x();
V(v,1) = p->point().y();
V(v,2) = p->point().z();
assign_scalar(p->point().x(),V(v,0));
assign_scalar(p->point().y(),V(v,1));
assign_scalar(p->point().z(),V(v,2));
vertex_to_index[p] = v;
v++;
}
@ -61,9 +62,11 @@ IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> >, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> >, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >, Eigen::Matrix<double, -1, -1, 0,-1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0,-1, -1> >&);
#endif

View File

@ -16,15 +16,12 @@ namespace igl
{
namespace cgal
{
// Convert a CGAL Polyhedron to a mesh (V,F)
//
// Templates:
// Polyhedron CGAL Polyhedron type (e.g. Polyhedron_3)
// Inputs:
// poly cgal polyhedron
// Outputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices
/// Convert a CGAL Polyhedron to a mesh (V,F)
///
/// @tparam Polyhedron CGAL Polyhedron type (e.g. Polyhedron_3)
/// @param[in] poly cgal polyhedron
/// @param[out] V #V by 3 list of vertex positions
/// @param[out] F #F by 3 list of triangle indices
template <
typename Polyhedron,
typename DerivedV,

View File

@ -19,32 +19,31 @@ namespace igl
{
namespace cgal
{
// Given a list of objects (e.g., resulting from intersecting a triangle
// with many other triangles), construct a constrained Delaunay
// triangulation on a given plane (P), by inersting constraints for each
// object projected onto that plane.
//
// Inputs:
// objects list of objects. This should lie on the given plane (P),
// otherwise they are added to the cdt _after_ their non-trivial
// projection
// P plane upon which all objects lie and upon which the CDT is
// conducted
// Outputs:
// vertices list of vertices of the CDT mesh _back on the 3D plane_
// faces list of list of triangle indices into vertices
//
/// Given a list of objects (e.g., resulting from intersecting a triangle
/// with many other triangles), construct a constrained Delaunay
/// triangulation on a given plane (P), by inersting constraints for each
/// object projected onto that plane.
///
/// @param[in] objects list of objects. This should lie on the given plane (P),
/// otherwise they are added to the cdt _after_ their non-trivial
/// projection
/// @param[in] P plane upon which all objects lie and upon which the CDT is
/// conducted
/// @param[out] vertices list of vertices of the CDT mesh _back on the 3D plane_
/// @param[out] faces list of list of triangle indices into vertices
///
template <typename Kernel, typename Index>
IGL_INLINE void projected_cdt(
const std::vector<CGAL::Object> & objects,
const CGAL::Plane_3<Kernel> & P,
std::vector<CGAL::Point_3<Kernel> >& vertices,
std::vector<std::vector<Index> >& faces);
// Outputs:
// V #V by 3 list of vertices of the CDT mesh _back on the 3D plane_,
// **cast** from the number type of Kernel to the number type of
// DerivedV
// F #F by 3 list of triangle indices into V
/// \overload
///
/// @param[out] V #V by 3 list of vertices of the CDT mesh _back on the 3D plane_,
/// **cast** from the number type of Kernel to the number type of
/// DerivedV
/// @param[out] F #F by 3 list of triangle indices into V
template < typename Kernel, typename DerivedV, typename DerivedF>
IGL_INLINE void projected_cdt(
const std::vector<CGAL::Object> & objects,

View File

@ -6,7 +6,6 @@
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "projected_delaunay.h"
#include "../../REDRUM.h"
#include <iostream>
#include <cassert>
@ -82,7 +81,6 @@ IGL_INLINE void igl::copyleft::cgal::projected_delaunay(
} else if(const std::vector<Point_3 > *polyp =
CGAL::object_cast< std::vector<Point_3 > >(&obj))
{
//cerr<<REDRUM("Poly...")<<endl;
const std::vector<Point_3 > & poly = *polyp;
const Index m = poly.size();
assert(m>=2);
@ -93,8 +91,7 @@ IGL_INLINE void igl::copyleft::cgal::projected_delaunay(
}
}else
{
cerr<<REDRUM("What is this object?!")<<endl;
assert(false);
assert(false && "What is this object?!");
}
}
}

View File

@ -15,17 +15,15 @@ namespace igl
{
namespace cgal
{
// Compute 2D delaunay triangulation of a given 3d triangle and a list of
// intersection objects (points,segments,triangles). CGAL uses an affine
// projection rather than an isometric projection, so we're not guaranteed
// that the 2D delaunay triangulation here will be a delaunay triangulation
// in 3D.
//
// Inputs:
// A triangle in 3D
// A_objects_3 updated list of intersection objects for A
// Outputs:
// cdt Contrained delaunay triangulation in projected 2D plane
/// Compute 2D delaunay triangulation of a given 3d triangle and a list of
/// intersection objects (points,segments,triangles). CGAL uses an affine
/// projection rather than an isometric projection, so we're not guaranteed
/// that the 2D delaunay triangulation here will be a delaunay triangulation
/// in 3D.
///
/// @param[in] A triangle in 3D
/// @param[in] A_objects_3 updated list of intersection objects for A
/// @param[out] cdt Contrained delaunay triangulation in projected 2D plane
template <typename Kernel>
IGL_INLINE void projected_delaunay(
const CGAL::Triangle_3<Kernel> & A,

View File

@ -16,9 +16,7 @@
#include "../../writePLY.h"
#include "../../get_seconds.h"
#include "../../LinSpaced.h"
#include "order_facets_around_edge.h"
#include "outer_facet.h"
#include "closest_facet.h"
#include "assign.h"
#include "extract_cells.h"
#include "cell_adjacency.h"
@ -37,11 +35,15 @@ template<
typename DerivedL,
typename DerivedW>
IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedL>& labels,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedL>& labels,
Eigen::PlainObjectBase<DerivedW>& W)
{
using Index = typename DerivedF::Scalar;
using MatrixXI = Eigen::Matrix<Index, Eigen::Dynamic, Eigen::Dynamic>;
using VectorXI = Eigen::Matrix<Index, Eigen::Dynamic, 1>;
#ifdef PROPAGATE_WINDING_NUMBER_TIMING
const auto & tictoc = []() -> double
{
@ -57,24 +59,22 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
tictoc();
#endif
Eigen::MatrixXi E, uE;
Eigen::VectorXi EMAP;
std::vector<std::vector<size_t> > uE2E;
igl::unique_edge_map(F, E, uE, EMAP, uE2E);
MatrixXI E, uE;
VectorXI EMAP, uEC, uEE;
igl::unique_edge_map(F, E, uE, EMAP, uEC, uEE);
Eigen::VectorXi P;
const size_t num_patches = igl::extract_manifold_patches(F, EMAP, uE2E, P);
VectorXI P;
const size_t num_patches = igl::extract_manifold_patches(F,EMAP,uEC,uEE,P);
DerivedW per_patch_cells;
const size_t num_cells =
igl::copyleft::cgal::extract_cells(
V, F, P, E, uE, uE2E, EMAP, per_patch_cells);
extract_cells(V,F,P,uE,EMAP,uEC,uEE,per_patch_cells);
#ifdef PROPAGATE_WINDING_NUMBER_TIMING
log_time("cell_extraction");
#endif
return propagate_winding_numbers(V, F,
uE, uE2E,
uE, uEC, uEE,
num_patches, P,
num_cells, per_patch_cells,
labels, W);
@ -85,23 +85,28 @@ template<
typename DerivedV,
typename DerivedF,
typename DeriveduE,
typename uE2EType,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedP,
typename DerivedC,
typename DerivedL,
typename DerivedW>
IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DeriveduE>& uE,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
const size_t num_patches,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedP>& P,
const size_t num_cells,
const Eigen::PlainObjectBase<DerivedC>& C,
const Eigen::PlainObjectBase<DerivedL>& labels,
const Eigen::MatrixBase<DerivedC>& C,
const Eigen::MatrixBase<DerivedL>& labels,
Eigen::PlainObjectBase<DerivedW>& W)
{
using Index = typename DerivedF::Scalar;
using MatrixXI = Eigen::Matrix<Index, Eigen::Dynamic, Eigen::Dynamic>;
using VectorXI = Eigen::Matrix<Index, Eigen::Dynamic, 1>;
#ifdef PROPAGATE_WINDING_NUMBER_TIMING
const auto & tictoc = []() -> double
{
@ -119,10 +124,9 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
bool valid = true;
// https://github.com/libigl/libigl/issues/674
if (!igl::piecewise_constant_winding_number(F, uE, uE2E))
if (!igl::piecewise_constant_winding_number(F, uE, uEC, uEE))
{
assert(false && "Input mesh is not PWN");
std::cerr << "Input mesh is not PWN!" << std::endl;
valid = false;
}
@ -134,6 +138,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
log_time("cell_connectivity");
#endif
#ifdef IGL_COPYLEFT_CGAL_PROPAGATE_WINDING_NUMBERS_DEBUG
auto save_cell = [&](const std::string& filename, size_t cell_id) -> void{
std::vector<size_t> faces;
for (size_t i=0; i<num_patches; i++) {
@ -145,7 +150,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
}
}
}
Eigen::MatrixXi cell_faces(faces.size(), 3);
MatrixXI cell_faces(faces.size(), 3);
for (size_t i=0; i<faces.size(); i++) {
cell_faces.row(i) = F.row(faces[i]);
}
@ -153,13 +158,14 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
assign(V,vertices);
writePLY(filename, vertices, cell_faces);
};
#endif
#ifndef NDEBUG
#ifdef IGL_COPYLEFT_CGAL_PROPAGATE_WINDING_NUMBERS_DEBUG
{
// Check for odd cycle.
Eigen::VectorXi cell_labels(num_cells);
VectorXI cell_labels(num_cells);
cell_labels.setZero();
Eigen::VectorXi parents(num_cells);
VectorXI parents(num_cells);
parents.setConstant(-1);
auto trace_parents = [&](size_t idx) -> std::list<size_t> {
std::list<size_t> path;
@ -220,9 +226,9 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
}
#endif
size_t outer_facet;
Eigen::Index outer_facet;
bool flipped;
Eigen::VectorXi I = igl::LinSpaced<Eigen::VectorXi>(num_faces, 0, num_faces-1);
VectorXI I = igl::LinSpaced<VectorXI>(num_faces, 0, num_faces-1);
igl::copyleft::cgal::outer_facet(V, F, I, outer_facet, flipped);
#ifdef PROPAGATE_WINDING_NUMBER_TIMING
log_time("outer_facet");
@ -231,7 +237,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
const size_t outer_patch = P[outer_facet];
const size_t infinity_cell = C(outer_patch, flipped?1:0);
Eigen::VectorXi patch_labels(num_patches);
VectorXI patch_labels(num_patches);
const int INVALID = std::numeric_limits<int>::max();
patch_labels.setConstant(INVALID);
for (size_t i=0; i<num_faces; i++) {
@ -244,7 +250,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
assert((patch_labels.array() != INVALID).all());
const size_t num_labels = patch_labels.maxCoeff()+1;
Eigen::MatrixXi per_cell_W(num_cells, num_labels);
MatrixXI per_cell_W(num_cells, num_labels);
per_cell_W.setConstant(INVALID);
per_cell_W.row(infinity_cell).setZero();
std::queue<size_t> Q;
@ -266,7 +272,7 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
}
Q.push(neighbor_cell);
} else {
#ifndef NDEBUG
#ifdef IGL_COPYLEFT_CGAL_PROPAGATE_WINDING_NUMBERS_DEBUG
// Checking for winding number consistency.
// This check would inevitably fail for meshes that contain open
// boundary or non-orientable. However, the inconsistent winding number
@ -274,16 +280,18 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
// is local and embedded within the volume. This, unfortunately, is the
// best we can do because the problem of computing integer winding
// number is ill-defined for open and non-orientable surfaces.
for (size_t i=0; i<num_labels; i++) {
if ((int)i == patch_labels[patch_idx]) {
int inc = direction ? -1:1;
//assert(per_cell_W(neighbor_cell, i) ==
// per_cell_W(curr_cell, i) + inc);
} else {
//assert(per_cell_W(neighbor_cell, i) ==
// per_cell_W(curr_cell, i));
}
}
//
// Commented this out because it wasn't actually calling the asserts...
//for (size_t i=0; i<num_labels; i++) {
// if ((int)i == patch_labels[patch_idx]) {
// int inc = direction ? -1:1;
// //assert(per_cell_W(neighbor_cell, i) ==
// // per_cell_W(curr_cell, i) + inc);
// } else {
// //assert(per_cell_W(neighbor_cell, i) ==
// // per_cell_W(curr_cell, i));
// }
//}
#endif
}
}
@ -312,13 +320,9 @@ IGL_INLINE bool igl::copyleft::cgal::propagate_winding_numbers(
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -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> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -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&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -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> >&);
template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, size_t, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, size_t, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, size_t, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, size_t, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template bool igl::copyleft::cgal::propagate_winding_numbers<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#ifdef WIN32
template bool igl::copyleft::cgal::propagate_winding_numbers<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned __int64, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, unsigned __int64, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, unsigned __int64, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &);
template bool igl::copyleft::cgal::propagate_winding_numbers<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>, class Eigen::Matrix<int, -1, 3, 1, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned __int64, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>>(class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 1, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 3, 1, -1, 3>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class std::vector<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>, class std::allocator<class std::vector<unsigned __int64, class std::allocator<unsigned __int64>>>> const &, unsigned __int64, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, unsigned __int64, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &);
#endif
#endif

View File

@ -25,73 +25,65 @@ namespace igl
{
namespace cgal
{
// TODO: This shouldn't need to be in igl::copyleft::cgal, it should
// instead take as input an index of the ambient cell and the winding
// number vector there.
//
// Compute winding number on each side of the face. The input mesh
// could contain multiple connected components. The input mesh must
// represent the boundary of a valid 3D volume, which means it is
// closed, consistently oriented and induces integer winding numbers.
//
// Inputs:
// V #V by 3 list of vertex positions.
// F #F by 3 list of triangle indices into V.
// labels #F list of facet labels ranging from 0 to k-1.
// Output:
// W #F by k*2 list of winding numbers. ``W(i,j*2)`` is the winding
// number on the positive side of facet ``i`` with respect to the
// facets labeled ``j``. Similarly, ``W(i,j*2+1)`` is the winding
// number on the negative side of facet ``i`` with respect to the
// facets labeled ``j``.
// Returns true iff the input induces a piecewise-constant winding number
// field.
/// Compute winding number on each side of the face. The input mesh
/// could contain multiple connected components. The input mesh must
/// represent the boundary of a valid 3D volume, which means it is
/// closed, consistently oriented and induces integer winding numbers.
///
/// @param[in] V #V by 3 list of vertex positions.
/// @param[in] F #F by 3 list of triangle indices into V.
/// @param[in] labels #F list of facet labels ranging from 0 to k-1.
/// @param[out] W #F by k*2 list of winding numbers. ``W(i,j*2)`` is the winding
/// number on the positive side of facet ``i`` with respect to the
/// facets labeled ``j``. Similarly, ``W(i,j*2+1)`` is the winding
/// number on the negative side of facet ``i`` with respect to the
/// facets labeled ``j``.
/// @return true iff the input induces a piecewise-constant winding number
/// field.
///
/// \note This shouldn't need to be in igl::copyleft::cgal, it should
/// instead take as input an index of the ambient cell and the winding
/// number vector there.
template<
typename DerivedV,
typename DerivedF,
typename DerivedL,
typename DerivedW>
IGL_INLINE bool propagate_winding_numbers(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedL>& labels,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedL>& labels,
Eigen::PlainObjectBase<DerivedW>& W);
// Inputs:
// V #V by 3 list of vertex positions.
// F #F by 3 list of triangle indices into V.
// uE #uE by 2 list of vertex_indices, represents undirected edges.
// uE2E #uE list of lists that maps uE to E. (a one-to-many map)
// num_patches number of patches
// P #F list of patch ids.
// num_cells number of cells
// C #P by 2 list of cell ids on each side of each patch.
// labels #F list of facet labels ranging from 0 to k-1.
// Output:
// W #F by k*2 list of winding numbers. ``W(i,j*2)`` is the winding
// number on the positive side of facet ``i`` with respect to the
// facets labeled ``j``. Similarly, ``W(i,j*2+1)`` is the winding
// number on the negative side of facet ``i`` with respect to the
// facets labeled ``j``.
// \overload
//
// @param[in] uE #uE by 2 list of vertex_indices, represents undirected edges.
// @param[in] uEC #uE+1 list of cumsums of directed edges sharing each unique edge
// @param[in] uEE #E list of indices into E (see `igl::unique_edge_map`)
// @param[in] num_patches number of patches
// @param[in] P #F list of patch ids.
// @param[in] num_cells number of cells
// @param[in] C #P by 2 list of cell ids on each side of each patch.
template<
typename DerivedV,
typename DerivedF,
typename DeriveduE,
typename uE2EType,
typename DeriveduEC,
typename DeriveduEE,
typename DerivedP,
typename DerivedC,
typename DerivedL,
typename DerivedW>
IGL_INLINE bool propagate_winding_numbers(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DeriveduE>& uE,
const std::vector<std::vector<uE2EType> >& uE2E,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DeriveduE>& uE,
const Eigen::MatrixBase<DeriveduEC>& uEC,
const Eigen::MatrixBase<DeriveduEE>& uEE,
const size_t num_patches,
const Eigen::PlainObjectBase<DerivedP>& P,
const Eigen::MatrixBase<DerivedP>& P,
const size_t num_cells,
const Eigen::PlainObjectBase<DerivedC>& C,
const Eigen::PlainObjectBase<DerivedL>& labels,
const Eigen::MatrixBase<DerivedC>& C,
const Eigen::MatrixBase<DerivedL>& labels,
Eigen::PlainObjectBase<DerivedW>& W);
}
}

Some files were not shown because too many files have changed in this diff Show More