fix bugs, update tetgen libigl files

This commit is contained in:
PavelMikus 2022-06-15 12:28:34 +02:00
parent 843a441d73
commit 33ec896b10
7 changed files with 572 additions and 91 deletions

View File

@ -13,6 +13,94 @@
// STL includes
#include <cassert>
IGL_INLINE bool igl::copyleft::tetgen::mesh_to_tetgenio(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
const std::vector<std::vector<REAL> > & H,
const std::vector<std::vector<REAL> > & R,
tetgenio & in)
{
using namespace std;
in.firstnumber = 0;
in.numberofpoints = V.size();
in.pointlist = new REAL[in.numberofpoints * 3];
//loop over points
for(size_t i = 0; i < (size_t)V.size(); i++)
{
assert(V[i].size() == 3);
in.pointlist[i*3+0] = V[i][0];
in.pointlist[i*3+1] = V[i][1];
in.pointlist[i*3+2] = V[i][2];
}
in.numberoffacets = F.size();
in.facetlist = new tetgenio::facet[in.numberoffacets];
in.facetmarkerlist = new int[in.numberoffacets];
// loop over face
for(size_t i = 0;i < (size_t)F.size(); i++)
{
in.facetmarkerlist[i] = i;
tetgenio::facet * f = &in.facetlist[i];
f->numberofpolygons = 1;
f->polygonlist = new tetgenio::polygon[f->numberofpolygons];
f->numberofholes = 0;
f->holelist = NULL;
tetgenio::polygon * p = &f->polygonlist[0];
p->numberofvertices = F[i].size();
p->vertexlist = new int[p->numberofvertices];
// loop around face
for(int j = 0;j < (int)F[i].size(); j++)
{
p->vertexlist[j] = F[i][j];
}
}
in.numberofholes = H.size();
in.holelist = new double[3 * in.numberofholes];
// loop over holes
for(size_t holeID = 0, nHoles = H.size(); holeID < nHoles; holeID++)
{
in.holelist[holeID * 3 + 0] = H[holeID][0];
in.holelist[holeID * 3 + 1] = H[holeID][1];
in.holelist[holeID * 3 + 2] = H[holeID][2];
}
in.numberofregions = R.size();
in.regionlist = new REAL[ 5 * in.numberofregions];
// loop over regions
for(size_t regionID = 0, nRegions = R.size(); regionID < nRegions; regionID++)
{
in.regionlist[regionID * 5 + 0] = R[regionID][0];
in.regionlist[regionID * 5 + 1] = R[regionID][1];
in.regionlist[regionID * 5 + 2] = R[regionID][2];
in.regionlist[regionID * 5 + 3] = R[regionID][3];
in.regionlist[regionID * 5 + 4] = R[regionID][4];
}
return true;
}
template <typename DerivedV, typename DerivedF, typename DerivedH, typename DerivedR>
IGL_INLINE bool igl::copyleft::tetgen::mesh_to_tetgenio(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedH>& H,
const Eigen::PlainObjectBase<DerivedR>& R,
tetgenio & in)
{
using namespace std;
vector<vector<REAL> > vV, vH, vR;
vector<vector<int> > vF;
matrix_to_list(V,vV);
matrix_to_list(F,vF);
matrix_to_list(H, vH);
matrix_to_list(R, vR);
return mesh_to_tetgenio(vV,vF,vH,vR,in);
}
IGL_INLINE bool igl::copyleft::tetgen::mesh_to_tetgenio(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,

View File

@ -43,6 +43,38 @@ namespace igl
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
tetgenio & in);
// Load a vertex list and face list into a tetgenio object
// Inputs:
// V #V by 3 vertex position list
// F #F list of polygon face indices into V (0-indexed)
// H #H list of seed point inside each hole
// R #R list of seed point inside each region
// Outputs:
// in tetgenio input object
// Returns true on success, false on error
IGL_INLINE bool mesh_to_tetgenio(
const std::vector<std::vector<REAL> > & V,
const std::vector<std::vector<int> > & F,
const std::vector<std::vector<REAL > > & H,
const std::vector<std::vector<REAL > > & R,
tetgenio & in);
// Wrapper with Eigen types
// Templates:
// DerivedV real-value: i.e. from MatrixXd
// DerivedF integer-value: i.e. from MatrixXi
// DerivedH real-value
// DerivedR real-value
template <typename DerivedV, typename DerivedF, typename DerivedH, typename DerivedR>
IGL_INLINE bool mesh_to_tetgenio(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedH>& H,
const Eigen::PlainObjectBase<DerivedR>& R,
tetgenio& in);
}
}
}

View File

@ -63,14 +63,12 @@ IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
assert(max_index >= 0);
assert(max_index < (int)V.size());
cout<<out.numberoftrifaces<<endl;
// When would this not be 4?
F.clear();
// loop over tetrahedra
for(int i = 0; i < out.numberoftrifaces; i++)
{
if(out.trifacemarkerlist[i]>=0)
if (out.trifacemarkerlist && out.trifacemarkerlist[i] >= 0)
{
vector<int> face(3);
for(int j = 0; j<3; j++)
@ -84,12 +82,13 @@ IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
return true;
}
template <typename DerivedV, typename DerivedT>
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
const tetgenio & out,
std::vector<std::vector<REAL > > & V,
std::vector<std::vector<int> > & T)
Eigen::PlainObjectBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedT>& T)
{
std::vector<std::vector<int> > F;
Eigen::Matrix<typename DerivedT::Scalar,Eigen::Dynamic,3> F;
return tetgenio_to_tetmesh(out,V,T,F);
}
@ -130,16 +129,151 @@ IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
return true;
}
template <typename DerivedV, typename DerivedT>
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
const tetgenio & out,
Eigen::PlainObjectBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedT>& T)
std::vector<std::vector<REAL > > & V,
std::vector<std::vector<int> > & T)
{
Eigen::Matrix<typename DerivedT::Scalar,Eigen::Dynamic,3> F;
std::vector<std::vector<int> > F;
return tetgenio_to_tetmesh(out,V,T,F);
}
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
const tetgenio & out,
std::vector<std::vector<REAL > > & V,
std::vector<std::vector<int> > & T,
std::vector<std::vector<int > > & F,
std::vector<std::vector<REAL > >& R,
std::vector<std::vector<int > >& N,
std::vector<std::vector<int > >& PT,
std::vector<std::vector<int > >& FT,
size_t & nR )
{
using namespace std;
// process points
if(out.pointlist == NULL)
{
cerr<<"^tetgenio_to_tetmesh Error: point list is NULL\n"<<endl;
return false;
}
V.resize(out.numberofpoints,vector<REAL>(3));
// loop over points
for(int i = 0;i < out.numberofpoints; i++)
{
V[i][0] = out.pointlist[i*3+0];
V[i][1] = out.pointlist[i*3+1];
V[i][2] = out.pointlist[i*3+2];
}
// process tets
if(out.tetrahedronlist == NULL)
{
cerr<<"^tetgenio_to_tetmesh Error: tet list is NULL\n"<<endl;
return false;
}
// When would this not be 4?
assert(out.numberofcorners == 4);
T.resize(out.numberoftetrahedra,vector<int>(out.numberofcorners));
int min_index = 1e7;
int max_index = -1e7;
// loop over tetrahedra
for(int i = 0; i < out.numberoftetrahedra; i++)
{
for(int j = 0; j<out.numberofcorners; j++)
{
int index = out.tetrahedronlist[i * out.numberofcorners + j];
T[i][j] = index;
min_index = (min_index > index ? index : min_index);
max_index = (max_index < index ? index : max_index);
}
}
assert(min_index >= 0);
assert(max_index >= 0);
assert(max_index < (int)V.size());
// When would this not be 4?
F.clear();
// loop over tetrahedra
for(int i = 0; i < out.numberoftrifaces; i++)
{
if(out.trifacemarkerlist[i]>=0)
{
vector<int> face(3);
for(int j = 0; j<3; j++)
{
face[j] = out.trifacelist[i * 3 + j];
}
F.push_back(face);
}
}
if(out.tetrahedronattributelist)
{
R.resize(out.numberoftetrahedra, vector<REAL>(1));
unordered_map<REAL, REAL> hashUniqueRegions;
for(size_t i = 0; i < out.numberoftetrahedra; i++)
{
R[i][0] = out.tetrahedronattributelist[i];
hashUniqueRegions[R[i][0]] = i;
}
// extract region marks
nR = hashUniqueRegions.size();
}else
{
R.clear();
nR = 0;
}
// extract neighbor list
if(out.neighborlist)
{
N.resize(out.numberoftetrahedra, vector<int>(4));
for (size_t i = 0; i < out.numberoftetrahedra; i++)
{
for (size_t j = 0; j < 4; j++)
N[i][j] = out.neighborlist[i * 4 + j];
}
}else
{
N.clear();
}
// extract point 2 tetrahedron list
if(out.point2tetlist)
{
PT.resize(out.numberofpoints, vector<int>(1));
for (size_t i = 0; i < out.numberofpoints; i++)
{
PT[i][0] = out.point2tetlist[i];
}
}else
{
PT.clear();
}
//extract face to tetrahedron list
if(out.face2tetlist)
{
FT.resize(out.numberoftrifaces, vector<int>(2));
int triface;
for (size_t i = 0; i < out.numberoftrifaces; i++)
{
for (size_t j = 0; j < 2; j++)
{
FT[i][j] = out.face2tetlist[0];
}
}
}else
{
FT.clear();
}
return true;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template bool igl::copyleft::tetgen::tetgenio_to_tetmesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(tetgenio const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);

View File

@ -14,6 +14,7 @@
#endif
#include "tetgen.h" // Defined tetgenio, REAL
#include <vector>
#include <unordered_map>
#include <Eigen/Core>
namespace igl
{
@ -34,6 +35,7 @@ namespace igl
std::vector<std::vector<REAL > > & V,
std::vector<std::vector<int> > & T,
std::vector<std::vector<int> > & F);
IGL_INLINE bool tetgenio_to_tetmesh(
const tetgenio & out,
std::vector<std::vector<REAL > > & V,
@ -49,12 +51,38 @@ namespace igl
Eigen::PlainObjectBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedT>& T,
Eigen::PlainObjectBase<DerivedF>& F);
template <typename DerivedV, typename DerivedT>
IGL_INLINE bool tetgenio_to_tetmesh(
const tetgenio & out,
Eigen::PlainObjectBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedT>& T);
}
// Extract a tetrahedral mesh from a tetgenio object
// Inputs:
// out tetgenio output object
// Outputs:
// V #V by 3 vertex position list
// T #T by 4 list of tetrahedra indices into V
// F #F by 3 list of marked facets
// R #T list of region IDs for tetrahedra
// N #T by 2 list of neighbors for each tetrahedron
// PT #V list of incident tetrahedron for each vertex
// FT #F by 2 list of tetrahedra sharing each face
// nR number of regions in output mesh
// Returns true on success, false on error
IGL_INLINE bool tetgenio_to_tetmesh(
const tetgenio & out,
std::vector<std::vector<REAL > > & V,
std::vector<std::vector<int> > & T,
std::vector<std::vector<int> > & F,
std::vector<std::vector<REAL> > & R,// region marks for tetrahedrons
std::vector<std::vector<int > > &N, // neighborlist per tet
std::vector<std::vector<int > > &PT, // Point to tet list per point
std::vector<std::vector<int > > &FT, // face to tet list
size_t & nR); // number of regions
}
}
}

View File

@ -55,7 +55,7 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
{
return -1;
}
//boundary_facets(TT,TF);
boundary_facets(TT,TF);
return 0;
}
@ -66,8 +66,8 @@ template <
typename DerivedTT,
typename DerivedTF>
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const std::string switches,
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
@ -110,10 +110,10 @@ template <
typename DerivedTF,
typename DerivedTM>
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedVM>& VM,
const Eigen::PlainObjectBase<DerivedFM>& FM,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedVM>& VM,
const Eigen::MatrixBase<DerivedFM>& FM,
const std::string switches,
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
@ -127,8 +127,8 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
matrix_to_list(V,vV);
matrix_to_list(F,vF);
vector<int> vVM = matrix_to_list(VM);
vector<int> vFM = matrix_to_list(FM);
vector<int> vVM = matrix_to_list(VM);
vector<int> vFM = matrix_to_list(FM);
int e = tetrahedralize(vV,vF,vVM,vFM,switches,vTV,vTT,vTF,vTM);
if(e == 0)
{
@ -155,6 +155,7 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
}
return e;
}
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
@ -208,13 +209,138 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
for (int i = 0; i < out.numberofpoints; ++i) {
TM[i] = out.pointmarkerlist[i];
}
//boundary_facets(TT,TF);
boundary_facets(TT,TF);
return 0;
}
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
const std::vector<std::vector<REAL > > & H,
const std::vector<std::vector<REAL > > & R,
const std::string switches,
std::vector<std::vector<REAL > > & TV,
std::vector<std::vector<int > > & TT,
std::vector<std::vector<int > > & TF,
std::vector<std::vector<REAL > > &TR,
std::vector<std::vector<int > > & TN,
std::vector<std::vector<int > > & PT,
std::vector<std::vector<int > > & FT,
size_t & numRegions)
{
using namespace std;
tetgenio in,out;
bool success;
success = mesh_to_tetgenio(V, F, H, R, in);
if(!success)
{
return -1;
}
try
{
char * cswitches = new char[switches.size() + 1];
strcpy(cswitches, switches.c_str());
::tetrahedralize(cswitches, &in, &out);
delete[] cswitches;
}catch(int e)
{
cerr <<"^"<<__FUNCTION__<<": TETGEN CRASHED...KABOOM!!"<<endl;
return 1;
}
if(out.numberoftetrahedra == 0)
{
cerr<<"^"<<__FUNCTION__<<": Tetgen failed to create tets"<<endl;
return 2;
}
success = tetgenio_to_tetmesh(out, TV, TT, TF, TR, TN, PT, FT, numRegions
);
if(!success)
{
return -1;
}
return 0;
}
template <
typename DerivedV,
typename DerivedF,
typename DerivedH,
typename DerivedR,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTR>
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedH>& H,
const Eigen::MatrixBase<DerivedR>& R,
const std::string switches,
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
Eigen::PlainObjectBase<DerivedTF>& TF,
Eigen::PlainObjectBase<DerivedTR>& TR,
Eigen::PlainObjectBase<DerivedTT>& TN,
Eigen::PlainObjectBase<DerivedTT>& PT,
Eigen::PlainObjectBase<DerivedTT>& FT,
size_t & numRegions)
{
using namespace std;
vector<vector<REAL> > vV, vH, vR, vTV, vTR;
vector<vector<int> > vF,vTT,vTF, vTN, vPT, vFT;
matrix_to_list(V,vV);
matrix_to_list(F,vF);
matrix_to_list(H, vH);
matrix_to_list(R, vR);
int e = tetrahedralize(vV,vF,vH,vR,switches,vTV,vTT,vTF,vTR,vTN,vPT,vFT, numRegions);
if(e == 0)
{
bool TV_rect = list_to_matrix(vTV,TV);
if(!TV_rect)
{
return 3;
}
bool TT_rect = list_to_matrix(vTT,TT);
if(!TT_rect)
{
return 3;
}
bool TF_rect = list_to_matrix(vTF,TF);
if(!TF_rect)
{
return 3;
}
bool TR_rect = list_to_matrix(vTR, TR);
if(!TR_rect)
{
return 3;
}
bool TN_rect = list_to_matrix(vTN, TN);
if(!TN_rect)
{
return 3;
}
bool PT_rect = list_to_matrix(vPT, PT);
if(!PT_rect)
{
return 3;
}
bool FT_rect = list_to_matrix(vFT, FT);
if(!FT_rect)
{
return 3;
}
}
return e;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template int igl::copyleft::tetgen::tetrahedralize<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::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template int igl::copyleft::tetgen::tetrahedralize<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<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> >(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 Eigen::PlainObjectBase<Eigen::Matrix<int, -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> > &,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &);
template int igl::copyleft::tetgen::tetrahedralize<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<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<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template int igl::copyleft::tetgen::tetrahedralize<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&, 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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template int igl::copyleft::tetgen::tetrahedralize<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<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> >(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 Eigen::MatrixBase<Eigen::Matrix<int, -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> > &,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &);
template int igl::copyleft::tetgen::tetrahedralize<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<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::MatrixBase<Eigen::Matrix<int, -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> >, 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 int igl::copyleft::tetgen::tetrahedralize<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<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::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<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, 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> >&, unsigned long&);
#endif

View File

@ -15,7 +15,7 @@
#ifndef TETLIBRARY
#define TETLIBRARY
#endif
#include "tetgen.h" // Defined REAL
#include <tetgen.h> // Defined REAL
namespace igl
{
@ -61,19 +61,19 @@ namespace igl
typename DerivedTT,
typename DerivedTF>
IGL_INLINE int tetrahedralize(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const std::string switches,
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
Eigen::PlainObjectBase<DerivedTF>& TF);
// Mesh the interior of a surface mesh (V,F) using tetgen
// Mesh the interior of a surface mesh (V,F) using tetgen
//
// Inputs:
// V #V by 3 vertex position list
// F #F list of polygon face indices into V (0-indexed)
// M #V list of markers for vertices
// M #V list of markers for vertices
// switches string of tetgen options (See tetgen documentation) e.g.
// "pq1.414a0.01" tries to mesh the interior of a given surface with
// quality and area constraints
@ -82,7 +82,7 @@ namespace igl
// TV #V by 3 vertex position list
// TT #T by 4 list of tet face indices
// TF #F by 3 list of triangle face indices
// TM #V list of markers for vertices
// TM #V list of markers for vertices
// Returns status:
// 0 success
// 1 tetgen threw exception
@ -92,14 +92,13 @@ namespace igl
IGL_INLINE int tetrahedralize(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
const std::vector<int> & VM,
const std::vector<int> & FM,
const std::vector<int> & VM,
const std::vector<int> & FM,
const std::string switches,
std::vector<std::vector<REAL > > & TV,
std::vector<std::vector<int > > & TT,
std::vector<std::vector<int> > & TF,
std::vector<int> & TM);
std::vector<int> & TM);
// Wrapper with Eigen types
// Templates:
// DerivedV real-value: i.e. from MatrixXd
@ -107,23 +106,90 @@ namespace igl
template <
typename DerivedV,
typename DerivedF,
typename DerivedVM,
typename DerivedFM,
typename DerivedVM,
typename DerivedFM,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTM>
IGL_INLINE int tetrahedralize(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedVM>& VM,
const Eigen::PlainObjectBase<DerivedFM>& FM,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedVM>& VM,
const Eigen::MatrixBase<DerivedFM>& FM,
const std::string switches,
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
Eigen::PlainObjectBase<DerivedTF>& TF,
Eigen::PlainObjectBase<DerivedTM>& TM);
}
// Mesh the interior of a surface mesh (V,F) using tetgen
//
// Inputs:
// V #V by 3 vertex position list
// F #F list of polygon face indices into V (0-indexed)
// H #H by 3 list of seed points inside holes
// R #R by 5 list of region attributes
// switches string of tetgen options (See tetgen documentation) e.g.
// "pq1.414a0.01" tries to mesh the interior of a given surface with
// quality and area constraints
// "" will mesh the convex hull constrained to pass through V (ignores F)
// Outputs:
// TV #TV by 3 vertex position list
// TT #TT by 4 list of tet face indices
// TF #TF by 3 list of triangle face indices
// TR #TT list of region ID for each tetrahedron
// TN #TT by 4 list of indices neighbors for each tetrahedron
// PT #TV list of incident tetrahedron for a vertex
// FT #TF by 2 list of tetrahedrons sharing a triface
// numRegions Number of regions in output mesh
// Returns status:
// 0 success
// 1 tetgen threw exception
// 2 tetgen did not crash but could not create any tets (probably there are
// holes, duplicate faces etc.)
// -1 other error
IGL_INLINE int tetrahedralize(
const std::vector<std::vector<REAL> > &V,
const std::vector<std::vector<int> > &F,
const std::vector<std::vector<REAL> > &H,
const std::vector<std::vector<REAL> > &R,
const std::string switches,
std::vector<std::vector<REAL > > & TV,
std::vector<std::vector<int > > & TT,
std::vector<std::vector<int > > & TF,
std::vector<std::vector<REAL > > &TR,
std::vector<std::vector<int > > &TN,
std::vector<std::vector<int > > &PT,
std::vector<std::vector<int > > &FT,
size_t & numRegions);
// Wrapper with Eigen types
// Templates:
// DerivedV real-value: i.e. from MatrixXd
// DerivedF integer-value: i.e. from MatrixXi
template <
typename DerivedV,
typename DerivedF,
typename DerivedH,
typename DerivedR,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTR>
IGL_INLINE int tetrahedralize(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedH>& H,
const Eigen::MatrixBase<DerivedR>& R,
const std::string switches,
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
Eigen::PlainObjectBase<DerivedTF>& TF,
Eigen::PlainObjectBase<DerivedTR>& TR,
Eigen::PlainObjectBase<DerivedTT>& TN,
Eigen::PlainObjectBase<DerivedTT>& PT,
Eigen::PlainObjectBase<DerivedTT>& FT,
size_t & numRegions);
}
}
}

View File

@ -6,14 +6,15 @@
#include "libigl/igl/copyleft/marching_cubes.h"
#include "libigl/igl/voxel_grid.h"
#include "libigl/igl/for_each.h"
#include "libigl/igl/barycenter.h"
#include "libigl/igl/remove_unreferenced.h"
#include "libigl/igl/copyleft/cgal/remesh_self_intersections.h"
#include "libigl/igl/winding_number.h"
#include "libigl/igl/boundary_facets.h"
#include "libigl/igl/copyleft/cgal/convex_hull.h"
#include "libigl/igl/copyleft/cgal/outer_hull.h"
#include "libigl/igl/copyleft/tetgen/tetrahedralize.h"
#include "libigl/igl/copyleft/tetgen/cdt.h"
#include <algorithm>
#include <string.h>
@ -37,7 +38,6 @@
#include <wx/msgdlg.h>
#include <wx/progdlg.h>
namespace Slic3r {
class RepairCanceledException: public std::exception {
@ -54,14 +54,13 @@ public:
}
};
namespace detail {
indexed_triangle_set fix_model_volume_mesh(const indexed_triangle_set &mesh) {
//first compute convex hull
Eigen::MatrixXd vertices;
Eigen::MatrixXi faces;
Eigen::MatrixXi hull_faces;
// Eigen::MatrixXi hull_faces;
{
Eigen::MatrixXf orig_v(mesh.vertices.size(), 3);
Eigen::MatrixXi orig_f(mesh.indices.size(), 3);
@ -77,37 +76,50 @@ indexed_triangle_set fix_model_volume_mesh(const indexed_triangle_set &mesh) {
std::cout << "orig vertices: " << orig_v.rows() << std::endl;
std::cout << "orig faces: " << orig_f.rows() << std::endl;
Eigen::VectorXi I;
Eigen::MatrixXi IF;
Eigen::VectorXi J;
Eigen::VectorXi IM;
//resolve self intersections
igl::copyleft::cgal::remesh_self_intersections(orig_v, orig_f, { }, vertices, faces, IF, J, I);
igl::copyleft::cgal::remesh_self_intersections(orig_v, orig_f, { }, vertices, faces, IF, J, IM);
std::cout << "remeshed vertices: " << vertices.rows() << std::endl;
std::cout << "remeshed faces: " << faces.rows() << std::endl;
// compute hull
igl::copyleft::cgal::convex_hull(vertices, hull_faces);
// _apply_ duplicate vertex mapping IM to FF
for (int i = 0; i < faces.size(); ++i) {
faces.data()[i] = IM(faces.data()[i]);
}
std::cout << " hull faces: " << hull_faces.rows() << std::endl;
Eigen::MatrixXd tmpV;
Eigen::MatrixXi tmpF;
// remove any vertices now unreferenced after duplicate mapping.
igl::remove_unreferenced(vertices, faces, tmpV, tmpF, IM);
// Now (SV,SF) is ready to extract outer hull
Eigen::VectorXi flip;
igl::copyleft::cgal::outer_hull(tmpV, tmpF, vertices, faces, J, flip);
// // compute hull
// igl::copyleft::cgal::convex_hull(vertices, hull_faces);
// std::cout << " hull faces: " << hull_faces.rows() << std::endl;
}
std::cout << "tetrahedronize convex hull " << std::endl;
Eigen::MatrixXd tets_v;
Eigen::MatrixXi tets_t;
Eigen::MatrixXi tets_f;
int result = igl::copyleft::tetgen::tetrahedralize(vertices, hull_faces, "pq1.414NEF", tets_v, tets_t, tets_f);
int result = igl::copyleft::tetgen::tetrahedralize(vertices, faces, "cY", tets_v, tets_t, tets_f);
if (result != 0) {
std::cout << "Tetrahedronization failed " << std::endl;
std::cout << "Tetrahedronization failed " << result << std::endl;
indexed_triangle_set fixed_mesh;
fixed_mesh.vertices.resize(vertices.rows());
fixed_mesh.indices.resize(hull_faces.rows());
fixed_mesh.indices.resize(faces.rows());
for (int v = 0; v < vertices.rows(); ++v) {
fixed_mesh.vertices[v] = vertices.row(v).cast<float>();
}
for (int f = 0; f < hull_faces.rows(); ++f) {
fixed_mesh.indices[f] = hull_faces.row(f);
for (int f = 0; f < faces.rows(); ++f) {
fixed_mesh.indices[f] = faces.row(f);
}
return fixed_mesh;
}
@ -121,7 +133,6 @@ indexed_triangle_set fix_model_volume_mesh(const indexed_triangle_set &mesh) {
std::cout << "barycenters count: " << barycenters.rows() << std::endl;
// Compute generalized winding number at all barycenters from remeshed input
std::cout << "Computing winding number over all " << tets_t.rows() << " tets..." << std::endl;
Eigen::VectorXd W;
@ -129,8 +140,6 @@ indexed_triangle_set fix_model_volume_mesh(const indexed_triangle_set &mesh) {
std::cout << "winding numbers count: " << W.rows() << std::endl;
std::cout << "Extracting internal tetrahedra " << std::endl;
Eigen::MatrixXi CT((W.array() > 0.5).count(), 4);
{
@ -145,7 +154,7 @@ indexed_triangle_set fix_model_volume_mesh(const indexed_triangle_set &mesh) {
std::cout << "Extracting boundary faces from " << CT.rows() << " internal tetrahedra" << std::endl;
Eigen::MatrixXi new_faces;
igl::boundary_facets(tets_t, new_faces);
igl::boundary_facets(CT, new_faces);
// boundary_facets seems to be reversed...
new_faces = new_faces.rowwise().reverse().eval();
@ -170,8 +179,6 @@ indexed_triangle_set fix_model_volume_mesh(const indexed_triangle_set &mesh) {
}
bool fix_model_by_tetrahedrons(ModelObject &model_object, int volume_idx, wxProgressDialog &progress_dlg,
const wxString &msg_header, std::string &fix_result) {
std::mutex mtx;