|
@@ -42,128 +42,75 @@ extern "C"
|
|
|
# define VOID IGL_PREVIOUSLY_DEFINED_VOID
|
|
|
#endif
|
|
|
|
|
|
+template <
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedE,
|
|
|
+ typename DerivedH,
|
|
|
+ typename DerivedV2,
|
|
|
+ typename DerivedF2>
|
|
|
IGL_INLINE void igl::triangle::triangulate(
|
|
|
- const Eigen::MatrixXd& V,
|
|
|
- const Eigen::MatrixXi& E,
|
|
|
- const Eigen::MatrixXd& H,
|
|
|
+ const Eigen::MatrixBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixBase<DerivedE> & E,
|
|
|
+ const Eigen::MatrixBase<DerivedH> & H,
|
|
|
const std::string flags,
|
|
|
- Eigen::MatrixXd& V2,
|
|
|
- Eigen::MatrixXi& F2)
|
|
|
+ Eigen::PlainObjectBase<DerivedV2> & V2,
|
|
|
+ Eigen::PlainObjectBase<DerivedF2> & F2)
|
|
|
{
|
|
|
- using namespace std;
|
|
|
- using namespace Eigen;
|
|
|
-
|
|
|
- // Prepare the flags
|
|
|
- string full_flags = flags + "pzB";
|
|
|
-
|
|
|
- // Prepare the input struct
|
|
|
- triangulateio in;
|
|
|
-
|
|
|
- assert(V.cols() == 2);
|
|
|
-
|
|
|
- in.numberofpoints = V.rows();
|
|
|
- in.pointlist = (double*)calloc(V.rows()*2,sizeof(double));
|
|
|
- for (unsigned i=0;i<V.rows();++i)
|
|
|
- for (unsigned j=0;j<2;++j)
|
|
|
- in.pointlist[i*2+j] = V(i,j);
|
|
|
-
|
|
|
- in.numberofpointattributes = 0;
|
|
|
- in.pointmarkerlist = (int*)calloc(V.rows(),sizeof(int));
|
|
|
- for (unsigned i=0;i<V.rows();++i)
|
|
|
- in.pointmarkerlist[i] = 1;
|
|
|
-
|
|
|
- in.trianglelist = NULL;
|
|
|
- in.numberoftriangles = 0;
|
|
|
- in.numberofcorners = 0;
|
|
|
- in.numberoftriangleattributes = 0;
|
|
|
- in.triangleattributelist = NULL;
|
|
|
-
|
|
|
- in.numberofsegments = E.rows();
|
|
|
- in.segmentlist = (int*)calloc(E.rows()*2,sizeof(int));
|
|
|
- for (unsigned i=0;i<E.rows();++i)
|
|
|
- for (unsigned j=0;j<2;++j)
|
|
|
- in.segmentlist[i*2+j] = E(i,j);
|
|
|
- in.segmentmarkerlist = (int*)calloc(E.rows(),sizeof(int));
|
|
|
- for (unsigned i=0;i<E.rows();++i)
|
|
|
- in.segmentmarkerlist[i] = 1;
|
|
|
-
|
|
|
- in.numberofholes = H.rows();
|
|
|
- in.holelist = (double*)calloc(H.rows()*2,sizeof(double));
|
|
|
- for (unsigned i=0;i<H.rows();++i)
|
|
|
- for (unsigned j=0;j<2;++j)
|
|
|
- in.holelist[i*2+j] = H(i,j);
|
|
|
- in.numberofregions = 0;
|
|
|
-
|
|
|
- // Prepare the output struct
|
|
|
- triangulateio out;
|
|
|
-
|
|
|
- out.pointlist = NULL;
|
|
|
- out.trianglelist = NULL;
|
|
|
- out.segmentlist = NULL;
|
|
|
-
|
|
|
- // Call triangle
|
|
|
- ::triangulate(const_cast<char*>(full_flags.c_str()), &in, &out, 0);
|
|
|
-
|
|
|
- // Return the mesh
|
|
|
- V2.resize(out.numberofpoints,2);
|
|
|
- for (unsigned i=0;i<V2.rows();++i)
|
|
|
- for (unsigned j=0;j<2;++j)
|
|
|
- V2(i,j) = out.pointlist[i*2+j];
|
|
|
-
|
|
|
- F2.resize(out.numberoftriangles,3);
|
|
|
- for (unsigned i=0;i<F2.rows();++i)
|
|
|
- for (unsigned j=0;j<3;++j)
|
|
|
- F2(i,j) = out.trianglelist[i*3+j];
|
|
|
-
|
|
|
- // Cleanup in
|
|
|
- free(in.pointlist);
|
|
|
- free(in.pointmarkerlist);
|
|
|
- free(in.segmentlist);
|
|
|
- free(in.segmentmarkerlist);
|
|
|
- free(in.holelist);
|
|
|
-
|
|
|
- // Cleanup out
|
|
|
- free(out.pointlist);
|
|
|
- free(out.trianglelist);
|
|
|
- free(out.segmentlist);
|
|
|
-
|
|
|
+ Eigen::VectorXi VM,EM,VM2,EM2;
|
|
|
+ return triangulate(V,E,H,VM,EM,flags,V2,F2,VM2,EM2);
|
|
|
}
|
|
|
|
|
|
-// Allows use of markers
|
|
|
+template <
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedE,
|
|
|
+ typename DerivedH,
|
|
|
+ typename DerivedVM,
|
|
|
+ typename DerivedEM,
|
|
|
+ typename DerivedV2,
|
|
|
+ typename DerivedF2,
|
|
|
+ typename DerivedVM2,
|
|
|
+ typename DerivedEM2>
|
|
|
IGL_INLINE void igl::triangle::triangulate(
|
|
|
- const Eigen::MatrixXd& V,
|
|
|
- const Eigen::MatrixXi& E,
|
|
|
- const Eigen::MatrixXd& H,
|
|
|
- const Eigen::VectorXi& VM,
|
|
|
- const Eigen::VectorXi& EM,
|
|
|
+ const Eigen::MatrixBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixBase<DerivedE> & E,
|
|
|
+ const Eigen::MatrixBase<DerivedH> & H,
|
|
|
+ const Eigen::MatrixBase<DerivedVM> & VM,
|
|
|
+ const Eigen::MatrixBase<DerivedEM> & EM,
|
|
|
const std::string flags,
|
|
|
- Eigen::MatrixXd& V2,
|
|
|
- Eigen::MatrixXi& F2,
|
|
|
- Eigen::VectorXi& M2)
|
|
|
+ Eigen::PlainObjectBase<DerivedV2> & V2,
|
|
|
+ Eigen::PlainObjectBase<DerivedF2> & F2,
|
|
|
+ Eigen::PlainObjectBase<DerivedVM2> & VM2,
|
|
|
+ Eigen::PlainObjectBase<DerivedEM2> & EM2)
|
|
|
{
|
|
|
using namespace std;
|
|
|
using namespace Eigen;
|
|
|
|
|
|
+ assert( (VM.size() == 0 || V.rows() == VM.size()) &&
|
|
|
+ "Vertex markers must be empty or same size as V");
|
|
|
+ assert( (EM.size() == 0 || E.rows() == EM.size()) &&
|
|
|
+ "Segment markers must be empty or same size as E");
|
|
|
+ assert(V.cols() == 2);
|
|
|
+ assert(E.size() == 0 || E.cols() == 2);
|
|
|
+ assert(H.size() == 0 || H.cols() == 2);
|
|
|
+
|
|
|
// Prepare the flags
|
|
|
- string full_flags = flags + "pz";
|
|
|
+ string full_flags = flags + "pz" + (EM.size() || VM.size() ? "B" : "");
|
|
|
+
|
|
|
+ typedef Map< Matrix<double,Dynamic,Dynamic,RowMajor> > MapXdr;
|
|
|
+ typedef Map< Matrix<int,Dynamic,Dynamic,RowMajor> > MapXir;
|
|
|
|
|
|
// Prepare the input struct
|
|
|
triangulateio in;
|
|
|
-
|
|
|
- assert(V.cols() == 2);
|
|
|
-
|
|
|
in.numberofpoints = V.rows();
|
|
|
- in.pointlist = (double*)calloc(V.rows()*2,sizeof(double));
|
|
|
- for (unsigned i=0;i<V.rows();++i)
|
|
|
- for (unsigned j=0;j<2;++j)
|
|
|
- in.pointlist[i*2+j] = V(i,j);
|
|
|
+ in.pointlist = (double*)calloc(V.size(),sizeof(double));
|
|
|
+ {
|
|
|
+ MapXdr inpl(in.pointlist,V.rows(),V.cols());
|
|
|
+ inpl = V.template cast<double>();
|
|
|
+ }
|
|
|
|
|
|
in.numberofpointattributes = 0;
|
|
|
- in.pointmarkerlist = (int*)calloc(VM.rows(),sizeof(int));
|
|
|
-
|
|
|
- for (unsigned i=0;i<VM.rows();++i) {
|
|
|
- in.pointmarkerlist[i] = VM(i);
|
|
|
- }
|
|
|
+ in.pointmarkerlist = (int*)calloc(VM.size(),sizeof(int));
|
|
|
+ for(unsigned i=0;i<VM.rows();++i) in.pointmarkerlist[i] = VM.size()?VM(i):1;
|
|
|
|
|
|
in.trianglelist = NULL;
|
|
|
in.numberoftriangles = 0;
|
|
@@ -171,25 +118,25 @@ IGL_INLINE void igl::triangle::triangulate(
|
|
|
in.numberoftriangleattributes = 0;
|
|
|
in.triangleattributelist = NULL;
|
|
|
|
|
|
- in.numberofsegments = E.rows();
|
|
|
- in.segmentlist = (int*)calloc(E.rows()*2,sizeof(int));
|
|
|
- for (unsigned i=0;i<E.rows();++i)
|
|
|
- for (unsigned j=0;j<2;++j)
|
|
|
- in.segmentlist[i*2+j] = E(i,j);
|
|
|
+ in.numberofsegments = E.size()?E.rows():0;
|
|
|
+ in.segmentlist = (int*)calloc(E.size(),sizeof(int));
|
|
|
+ {
|
|
|
+ MapXir insl(in.segmentlist,E.rows(),E.cols());
|
|
|
+ insl = E.template cast<int>();
|
|
|
+ }
|
|
|
in.segmentmarkerlist = (int*)calloc(E.rows(),sizeof(int));
|
|
|
- for (unsigned i=0;i<E.rows();++i)
|
|
|
- in.segmentmarkerlist[i] = EM(i);
|
|
|
-
|
|
|
- in.numberofholes = H.rows();
|
|
|
- in.holelist = (double*)calloc(H.rows()*2,sizeof(double));
|
|
|
- for (unsigned i=0;i<H.rows();++i)
|
|
|
- for (unsigned j=0;j<2;++j)
|
|
|
- in.holelist[i*2+j] = H(i,j);
|
|
|
+ for (unsigned i=0;i<E.rows();++i) in.segmentmarkerlist[i] = EM.size()?EM(i):1;
|
|
|
+
|
|
|
+ in.numberofholes = H.size()?H.rows():0;
|
|
|
+ in.holelist = (double*)calloc(H.size(),sizeof(double));
|
|
|
+ {
|
|
|
+ MapXdr inhl(in.holelist,H.rows(),H.cols());
|
|
|
+ inhl = H.template cast<double>();
|
|
|
+ }
|
|
|
in.numberofregions = 0;
|
|
|
|
|
|
// Prepare the output struct
|
|
|
triangulateio out;
|
|
|
-
|
|
|
out.pointlist = NULL;
|
|
|
out.trianglelist = NULL;
|
|
|
out.segmentlist = NULL;
|
|
@@ -200,19 +147,15 @@ IGL_INLINE void igl::triangle::triangulate(
|
|
|
::triangulate(const_cast<char*>(full_flags.c_str()), &in, &out, 0);
|
|
|
|
|
|
// Return the mesh
|
|
|
- V2.resize(out.numberofpoints,2);
|
|
|
- for (unsigned i=0;i<V2.rows();++i)
|
|
|
- for (unsigned j=0;j<2;++j)
|
|
|
- V2(i,j) = out.pointlist[i*2+j];
|
|
|
-
|
|
|
- F2.resize(out.numberoftriangles,3);
|
|
|
- for (unsigned i=0;i<F2.rows();++i)
|
|
|
- for (unsigned j=0;j<3;++j)
|
|
|
- F2(i,j) = out.trianglelist[i*3+j];
|
|
|
-
|
|
|
- M2.resize(out.numberofpoints);
|
|
|
- for (unsigned int i = 0; i < out.numberofpoints; ++i) {
|
|
|
- M2(i) = out.pointmarkerlist[i];
|
|
|
+ V2 = MapXdr(out.pointlist,out.numberofpoints,2).cast<typename DerivedV2::Scalar>();
|
|
|
+ F2 = MapXir(out.trianglelist,out.numberoftriangles,3).cast<typename DerivedF2::Scalar>();
|
|
|
+ if(VM.size())
|
|
|
+ {
|
|
|
+ VM2 = MapXir(out.pointmarkerlist,out.numberofpoints,1).cast<typename DerivedVM2::Scalar>();
|
|
|
+ }
|
|
|
+ if(EM.size())
|
|
|
+ {
|
|
|
+ EM2 = MapXir(out.segmentmarkerlist,out.numberofsegments,1).cast<typename DerivedEM2::Scalar>();
|
|
|
}
|
|
|
|
|
|
// Cleanup in
|
|
@@ -221,7 +164,6 @@ IGL_INLINE void igl::triangle::triangulate(
|
|
|
free(in.segmentlist);
|
|
|
free(in.segmentmarkerlist);
|
|
|
free(in.holelist);
|
|
|
-
|
|
|
// Cleanup out
|
|
|
free(out.pointlist);
|
|
|
free(out.trianglelist);
|
|
@@ -232,4 +174,6 @@ IGL_INLINE void igl::triangle::triangulate(
|
|
|
|
|
|
#ifdef IGL_STATIC_LIBRARY
|
|
|
// Explicit template instantiation
|
|
|
+// generated by autoexplicit.sh
|
|
|
+template void igl::triangle::triangulate<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::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&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
|
|
#endif
|