rm vector overloads and simplify api (#2290) [ci skip]

This commit is contained in:
Alec Jacobson
2023-09-25 16:27:01 -04:00
committed by GitHub
parent 64c2740230
commit 1b07ebcf9e
9 changed files with 296 additions and 864 deletions
+54 -114
View File
@@ -13,154 +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,
template <
typename DerivedV,
typename DerivedF,
typename DerivedH,
typename DerivedVM,
typename DerivedFM,
typename DerivedR>
IGL_INLINE void igl::copyleft::tetgen::mesh_to_tetgenio(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedH>& H,
const Eigen::MatrixBase<DerivedVM>& VM,
const Eigen::MatrixBase<DerivedFM>& FM,
const Eigen::MatrixBase<DerivedR>& R,
tetgenio & in)
{
using namespace std;
assert(V.cols() == 3 && "V should have 3 columns");
assert((VM.size() == 0 || VM.size() == V.rows()) && "VM should be empty or #V by 1");
assert((FM.size() == 0 || FM.size() == F.rows()) && "FM should be empty or #F by 1");
in.firstnumber = 0;
in.numberofpoints = V.size();
in.numberofpoints = V.rows();
in.pointlist = new REAL[in.numberofpoints * 3];
//loop over points
for(size_t i = 0; i < (size_t)V.size(); i++)
if(VM.size())
{
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.pointmarkerlist = new int[VM.size()];
}
in.numberoffacets = F.size();
//loop over points
for(int i = 0; i < V.rows(); i++)
{
in.pointlist[i*3+0] = V(i,0);
in.pointlist[i*3+1] = V(i,1);
in.pointlist[i*3+2] = V(i,2);
if(VM.size())
{
in.pointmarkerlist[i] = VM(i);
}
}
in.numberoffacets = F.rows();
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++)
for(int i = 0;i < F.rows(); i++)
{
in.facetmarkerlist[i] = i;
in.facetmarkerlist[i] = FM.size() ? FM(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->numberofvertices = F.cols();
p->vertexlist = new int[p->numberofvertices];
// loop around face
for(int j = 0;j < (int)F[i].size(); j++)
for(int j = 0;j < F.cols(); j++)
{
p->vertexlist[j] = F[i][j];
p->vertexlist[j] = F(i,j);
}
}
in.numberofholes = H.size();
in.holelist = new double[3 * in.numberofholes];
in.numberofholes = H.rows();
in.holelist = new REAL[3 * in.numberofholes];
// loop over holes
for(size_t holeID = 0, nHoles = H.size(); holeID < nHoles; holeID++)
for(int holeID = 0; holeID < H.rows(); 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.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.numberofregions = R.rows();
in.regionlist = new REAL[ 5 * in.numberofregions];
// loop over regions
for(size_t regionID = 0, nRegions = R.size(); regionID < nRegions; regionID++)
for(int regionID = 0; regionID < R.rows(); 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];
}
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,
tetgenio & in)
{
using namespace std;
// all indices start from 0
in.firstnumber = 0;
in.numberofpoints = V.size();
in.pointlist = new REAL[in.numberofpoints * 3];
// loop over points
for(int i = 0; i < (int)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(int i = 0;i < (int)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];
}
}
return true;
}
template <typename DerivedV, typename DerivedF>
IGL_INLINE bool igl::copyleft::tetgen::mesh_to_tetgenio(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
tetgenio & in)
{
using namespace std;
vector<vector<REAL> > vV;
vector<vector<int> > vF;
matrix_to_list(V,vV);
matrix_to_list(F,vF);
return mesh_to_tetgenio(vV,vF,in);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template bool igl::copyleft::tetgen::mesh_to_tetgenio<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&, tetgenio&);
// generated by autoexplicit.sh
template void igl::copyleft::tetgen::mesh_to_tetgenio<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<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<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&, tetgenio&);
#endif
+15 -25
View File
@@ -28,32 +28,22 @@ namespace igl
/// @param[in] F #F list of polygon face indices into V (0-indexed)
/// @param[out] in tetgenio input object
/// @param[out] H #H list of seed point inside each hole
/// @param[out] R #R list of seed point inside each region
/// @return 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);
IGL_INLINE bool mesh_to_tetgenio(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
/// @param[out] R #R list of seed point inside each region
template <
typename DerivedV,
typename DerivedF,
typename DerivedH,
typename DerivedVM,
typename DerivedFM,
typename DerivedR>
IGL_INLINE void mesh_to_tetgenio(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedH>& H,
const Eigen::MatrixBase<DerivedVM>& VM,
const Eigen::MatrixBase<DerivedFM>& FM,
const Eigen::MatrixBase<DerivedR>& R,
tetgenio & in);
/// \overload
template <typename DerivedV, typename DerivedF>
IGL_INLINE bool mesh_to_tetgenio(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
tetgenio & in);
/// \overload
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);
}
}
}
@@ -1,74 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 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 "read_into_tetgenio.h"
#include "mesh_to_tetgenio.h"
// IGL includes
#include "../../pathinfo.h"
#ifndef IGL_NO_EIGEN
# define IGL_NO_EIGEN_WAS_NOT_ALREADY_DEFINED
# define IGL_NO_EIGEN
#endif
// Include igl headers without including Eigen
#include "../../readOBJ.h"
#ifdef IGL_NO_EIGEN_WAS_NOT_ALREADY_DEFINED
# undef IGL_NO_EIGEN
#endif
// STL includes
#include <algorithm>
#include <iostream>
#include <vector>
IGL_INLINE bool igl::copyleft::tetgen::read_into_tetgenio(
const std::string & path,
tetgenio & in)
{
using namespace std;
// get file extension
string dirname,basename,ext,filename;
pathinfo(path,dirname,basename,ext,filename);
// convert to lower case for easy comparison
transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
bool success = false;
char basename_char[1024];
strcpy(basename_char,basename.c_str());
if(ext == "obj")
{
// read obj into vertex list and face list
vector<vector<REAL> > V,TC,N;
vector<vector<int> > F,FTC,FN;
success = readOBJ(path,V,TC,N,F,FTC,FN);
success &= mesh_to_tetgenio(V,F,in);
}else if(ext == "off")
{
success = in.load_off(basename_char);
}else if(ext == "node")
{
success = in.load_node(basename_char);
}else
{
if(ext.length() > 0)
{
cerr<<"^read_into_tetgenio Warning: Unsupported extension ("<<ext<<
"): try to load as basename..."<<endl;
}
// This changed as of (the so far unreleased) tetgen 1.5
//success = in.load_tetmesh(basename_char);
//int object = tetgenbehavior::NODES;
//if(ext == "mesh")
//{
// object = tetgenbehavior::MEDIT;
//}
success = in.load_tetmesh(basename_char,!tetgenbehavior::MEDIT);
}
return success;
}
@@ -1,60 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 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_TETGEN_READ_INTO_TETGENIO_H
#define IGL_COPYLEFT_TETGEN_READ_INTO_TETGENIO_H
#include "../../igl_inline.h"
#include <string>
#ifndef TETLIBRARY
#define TETLIBRARY
#endif
#include "tetgen.h" // Defined tetgenio, REAL
namespace igl
{
namespace copyleft
{
namespace tetgen
{
/// Read a mesh or point set into tetgenio (input object for calling
/// tetgen). Many file formats are already supported by tetgen:
/// .off
/// .ply
/// .node
/// .ply
/// .medit
/// .vtk
/// etc.
/// Notably it does not support .obj which is loaded by hand here (also
/// demonstrating how to load points/faces programmatically)
///
/// If the file extension is not recognized the filename is assumed to be
/// the basename of a collection describe a tetmesh, (of which at least
/// the .node file must exist):
/// [filename].node
/// [filename].ele
/// [filename].face
/// [filename].edge
/// [filename].vol
///
/// @param[in] path path to file or basename to files
/// @param[out] in tetgenio input object
/// @return true on success, false on error
IGL_INLINE bool read_into_tetgenio(
const std::string & path,
tetgenio & in);
}
}
}
#ifndef IGL_STATIC_LIBRARY
# include "read_into_tetgenio.cpp"
#endif
#endif
@@ -13,255 +13,135 @@
// STL includes
#include <iostream>
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)
{
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++)
{
vector<int> face(3);
for(int j = 0; j<3; j++)
{
face[j] = out.trifacelist[i * 3 + j];
}
F.push_back(face);
}
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)
{
Eigen::Matrix<typename DerivedT::Scalar,Eigen::Dynamic,3> F;
return tetgenio_to_tetmesh(out,V,T,F);
}
template <typename DerivedV, typename DerivedT, typename DerivedF>
template <
typename DerivedV,
typename DerivedT,
typename DerivedF,
typename DerivedTM,
typename DerivedR,
typename DerivedN,
typename DerivedPT,
typename DerivedFT>
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
const tetgenio & out,
Eigen::PlainObjectBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedT>& T,
Eigen::PlainObjectBase<DerivedF>& F)
Eigen::PlainObjectBase<DerivedF>& F,
Eigen::PlainObjectBase<DerivedTM>& TM,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedN>& N,
Eigen::PlainObjectBase<DerivedPT>& PT,
Eigen::PlainObjectBase<DerivedFT>& FT,
int & num_regions)
{
using namespace std;
vector<vector<REAL> > vV;
vector<vector<int> > vT;
vector<vector<int> > vF;
bool success = tetgenio_to_tetmesh(out,vV,vT,vF);
if(!success)
{
return false;
}
bool V_rect = list_to_matrix(vV,V);
if(!V_rect)
{
// igl::list_to_matrix(vV,V) already printed error message to std err
return false;
}
bool T_rect = list_to_matrix(vT,T);
if(!T_rect)
{
// igl::list_to_matrix(vT,T) already printed error message to std err
return false;
}
bool F_rect = list_to_matrix(vF,F);
if(!F_rect)
{
return false;
}
return true;
}
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;
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;
std::cerr<<"^tetgenio_to_tetmesh Error: point list is NULL\n"<<std::endl;
return false;
}
V.resize(out.numberofpoints,vector<REAL>(3));
V.resize(out.numberofpoints,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];
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;
std::cerr<<"^tetgenio_to_tetmesh Error: tet list is NULL\n"<<std::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;
T.resize(out.numberoftetrahedra,out.numberofcorners);
// 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);
T(i,j) = out.tetrahedronlist[i * out.numberofcorners + j];
}
}
assert(min_index >= 0);
assert(max_index >= 0);
assert(max_index < (int)V.size());
assert(T.maxCoeff() >= 0);
assert(T.minCoeff() >= 0);
assert(T.maxCoeff() < V.rows());
// When would this not be 4?
F.clear();
F.resize(out.numberoftrifaces,3);
// loop over tetrahedra
for(int i = 0; i < out.numberoftrifaces; i++)
{
vector<int> face(3);
for(int j = 0; j<3; j++)
F(i,0) = out.trifacelist[i * 3 + 0];
F(i,1) = out.trifacelist[i * 3 + 1];
F(i,2) = out.trifacelist[i * 3 + 2];
}
if(out.pointmarkerlist)
{
assert(out.numberofpoints == out.numberofpointmarkers);
TM.resize(out.numberofpoints);
for (int i = 0; i < out.numberofpoints; ++i)
{
face[j] = out.trifacelist[i * 3 + j];
TM(i) = out.pointmarkerlist[i];
}
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.resize(out.numberoftetrahedra);
std::unordered_map<REAL, REAL> hashUniqueRegions;
for(int i = 0; i < out.numberoftetrahedra; i++)
{
R[i][0] = out.tetrahedronattributelist[i];
hashUniqueRegions[R[i][0]] = i;
R(i) = out.tetrahedronattributelist[i];
hashUniqueRegions[R(i)] = i;
}
// extract region marks
nR = hashUniqueRegions.size();
num_regions = hashUniqueRegions.size();
}else
{
R.clear();
nR = 0;
num_regions = 0;
}
// extract neighbor list
if(out.neighborlist)
{
N.resize(out.numberoftetrahedra, vector<int>(4));
for (size_t i = 0; i < out.numberoftetrahedra; i++)
N.resize(out.numberoftetrahedra, 4);
for (int i = 0; i < out.numberoftetrahedra; i++)
{
for (size_t j = 0; j < 4; j++)
N[i][j] = out.neighborlist[i * 4 + j];
for (int 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.resize(out.numberofpoints);
for (int i = 0; i < out.numberofpoints; i++)
{
PT[i][0] = out.point2tetlist[i];
PT(i) = out.point2tetlist[i];
}
}else
{
PT.clear();
}
//extract face to tetrahedron list
if(out.face2tetlist)
{
FT.resize(out.numberoftrifaces, vector<int>(2));
FT.resize(out.numberoftrifaces,2);
int triface;
for (size_t i = 0; i < out.numberoftrifaces; i++)
for (int i = 0; i < out.numberoftrifaces; i++)
{
for (size_t j = 0; j < 2; j++)
for (int j = 0; j < 2; j++)
{
FT[i][j] = out.face2tetlist[0];
FT(i,j) = out.face2tetlist[i * 2 + j];
}
}
}else
{
FT.clear();
}
return true;
@@ -270,5 +150,6 @@ IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
#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> >&);
// generated by autoexplicit.sh
template bool igl::copyleft::tetgen::tetgenio_to_tetmesh<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::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -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>>&, 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>>&, 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>>&, int&);
#endif
@@ -22,54 +22,27 @@ namespace igl
{
namespace tetgen
{
/// Extract a tetrahedral mesh from a tetgenio object
///
/// @param[in] out tetgenio output object
/// @param[out] V #V by 3 vertex position list
/// @param[out] T #T by 4 list of tetrahedra indices into V
/// @param[out] F #F by 3 list of marked facets
/// @param[out] R #T list of region IDs for tetrahedra
/// @param[out] N #T by 2 list of neighbors for each tetrahedron
/// @param[out] PT #V list of incident tetrahedron for each vertex
/// @param[out] FT #F by 2 list of tetrahedra sharing each face
/// @param[out] nR number of regions in output mesh
/// @return 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
/// \overload
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);
/// \overload
IGL_INLINE bool tetgenio_to_tetmesh(
const tetgenio & out,
std::vector<std::vector<REAL > > & V,
std::vector<std::vector<int> > & T);
/// \overload
template <typename DerivedV, typename DerivedT, typename DerivedF>
template <
typename DerivedV,
typename DerivedT,
typename DerivedF,
typename DerivedTM,
typename DerivedR,
typename DerivedN,
typename DerivedPT,
typename DerivedFT>
IGL_INLINE bool tetgenio_to_tetmesh(
const tetgenio & out,
Eigen::PlainObjectBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedT>& T,
Eigen::PlainObjectBase<DerivedF>& F);
/// \overload
template <typename DerivedV, typename DerivedT>
IGL_INLINE bool tetgenio_to_tetmesh(
const tetgenio & out,
Eigen::PlainObjectBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedT>& T);
}
Eigen::PlainObjectBase<DerivedF>& F,
Eigen::PlainObjectBase<DerivedTM>& TM,
Eigen::PlainObjectBase<DerivedR>& R,
Eigen::PlainObjectBase<DerivedN>& N,
Eigen::PlainObjectBase<DerivedPT>& PT,
Eigen::PlainObjectBase<DerivedFT>& FT,
int & num_regions);
}
}
}
+55 -283
View File
@@ -18,22 +18,43 @@
#include <cassert>
#include <iostream>
template <
typename DerivedV,
typename DerivedF,
typename DerivedH,
typename DerivedVM,
typename DerivedFM,
typename DerivedR,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTM,
typename DerivedTR,
typename DerivedTN,
typename DerivedPT,
typename DerivedFT>
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedH>& H,
const Eigen::MatrixBase<DerivedVM>& VM,
const Eigen::MatrixBase<DerivedFM>& FM,
const Eigen::MatrixBase<DerivedR>& R,
const std::string switches,
std::vector<std::vector<REAL > > & TV,
std::vector<std::vector<int > > & TT,
std::vector<std::vector<int> > & TF)
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
Eigen::PlainObjectBase<DerivedTF>& TF,
Eigen::PlainObjectBase<DerivedTM>& TM,
Eigen::PlainObjectBase<DerivedTR>& TR,
Eigen::PlainObjectBase<DerivedTN>& TN,
Eigen::PlainObjectBase<DerivedPT>& PT,
Eigen::PlainObjectBase<DerivedFT>& FT,
int & num_regions)
{
using namespace std;
// REAL is what tetgen is using as floating point precision
// Prepare input
tetgenio in,out;
bool success;
success = mesh_to_tetgenio(V,F,in);
if(!success)
{
return -1;
}
mesh_to_tetgenio(V,F,H,VM,FM,R,in);
try
{
char * cswitches = new char[switches.size() + 1];
@@ -42,20 +63,27 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
delete[] cswitches;
}catch(int e)
{
cerr<<"^"<<__FUNCTION__<<": TETGEN CRASHED... KABOOOM!!!"<<endl;
std::cerr<<"^"<<__FUNCTION__<<": TETGEN CRASHED... KABOOOM!!!"<<std::endl;
return 1;
}
if(out.numberoftetrahedra == 0)
{
cerr<<"^"<<__FUNCTION__<<": Tetgen failed to create tets"<<endl;
std::cerr<<"^"<<__FUNCTION__<<": Tetgen failed to create tets"<<std::endl;
return 2;
}
success = tetgenio_to_tetmesh(out,TV,TT,TF);
if(!success)
// Prepare output
bool ret = tetgenio_to_tetmesh(out,TV,TT,TF,TM,TR,TN,PT,FT,num_regions);
if(!ret)
{
return -1;
}
boundary_facets(TT,TF);
if(TF.size() == 0)
{
boundary_facets(TT,TF);
}
return 0;
}
@@ -73,274 +101,18 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
Eigen::PlainObjectBase<DerivedTT>& TT,
Eigen::PlainObjectBase<DerivedTF>& TF)
{
using namespace std;
vector<vector<REAL> > vV,vTV;
vector<vector<int> > vF,vTT,vTF;
matrix_to_list(V,vV);
matrix_to_list(F,vF);
int e = tetrahedralize(vV,vF,switches,vTV,vTT,vTF);
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;
}
}
return e;
}
template <
typename DerivedV,
typename DerivedF,
typename DerivedVM,
typename DerivedFM,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTM>
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
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)
{
using namespace std;
vector<vector<REAL> > vV,vTV;
vector<vector<int> > vF,vTT,vTF;
vector<int> vTM;
matrix_to_list(V,vV);
matrix_to_list(F,vF);
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)
{
bool TV_rect = list_to_matrix(vTV,TV);
if(!TV_rect)
{
return false;
}
bool TT_rect = list_to_matrix(vTT,TT);
if(!TT_rect)
{
return false;
}
bool TF_rect = list_to_matrix(vTF,TF);
if(!TF_rect)
{
return false;
}
bool TM_rect = list_to_matrix(vTM,TM);
if(!TM_rect)
{
return false;
}
}
return e;
}
IGL_INLINE int igl::copyleft::tetgen::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::string switches,
std::vector<std::vector<REAL > > & TV,
std::vector<std::vector<int > > & TT,
std::vector<std::vector<int> > & TF,
std::vector<int> & TM)
{
using namespace std;
tetgenio in,out;
bool success;
success = mesh_to_tetgenio(V,F,in);
if(!success)
{
return -1;
}
in.pointmarkerlist = new int[VM.size()];
for (int i = 0; i < VM.size(); ++i) {
in.pointmarkerlist[i] = VM[i];
}
// These have already been created in mesh_to_tetgenio.
// Reset them here.
for (int i = 0; i < FM.size(); ++i) {
in.facetmarkerlist[i] = FM[i];
}
try
{
char * cswitches = new char[switches.size() + 1];
std::strcpy(cswitches,switches.c_str());
::tetrahedralize(cswitches,&in, &out);
delete[] cswitches;
}catch(int e)
{
cerr<<"^"<<__FUNCTION__<<": TETGEN CRASHED... KABOOOM!!!"<<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);
if(!success)
{
return -1;
}
TM.resize(out.numberofpoints);
for (int i = 0; i < out.numberofpoints; ++i) {
TM[i] = out.pointmarkerlist[i];
}
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;
Eigen::VectorXi VM,FM;
Eigen::MatrixXd H,R;
Eigen::VectorXi TM,TR,PT;
Eigen::MatrixXi FT,TN;
int numRegions;
return tetrahedralize(V,F,H,VM,FM,R,switches,TV,TT,TF,TM,TR,TN,PT,FT,numRegions);
}
#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::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&);
// generated by autoexplicit.sh
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>>&);
// generated by autoexplicit.sh
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::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<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<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&, 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>>&, 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>>&, 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>>&, int&);
#endif
+42 -84
View File
@@ -28,6 +28,8 @@ namespace igl
/// @param[in] V #V by 3 vertex position list
/// @param[in] F #F list of polygon face indices into V (0-indexed)
/// @param[in] H #H by 3 list of seed points inside holes
/// @param[in] VM #VM list of vertex markers
/// @param[in] FM #FM list of face markers
/// @param[in] R #R by 5 list of region attributes
/// @param[in] switches string of tetgen options (See tetgen documentation) e.g.
/// "pq1.414a0.01" tries to mesh the interior of a given surface with
@@ -35,46 +37,57 @@ namespace igl
/// "" will mesh the convex hull constrained to pass through V (ignores F)
/// @param[out] TV #TV by 3 vertex position list
/// @param[out] TT #TT by 4 list of tet face indices
/// @param[out] TF #TF by 3 list of triangle face indices
/// @param[out] TF #TF by 3 list of triangle face indices ('f', else
/// `boundary_facets` is called on TT)
/// @param[out] TR #TT list of region ID for each tetrahedron
/// @param[out] TN #TT by 4 list of indices neighbors for each tetrahedron
/// @param[out] PT #TV list of incident tetrahedron for a vertex
/// @param[out] FT #TF by 2 list of tetrahedrons sharing a triface
/// @param[out] numRegions Number of regions in output mesh
/// @param[out] TN #TT by 4 list of indices neighbors for each tetrahedron ('n')
/// @param[out] PT #TV list of incident tetrahedron for a vertex ('m')
/// @param[out] FT #TF by 2 list of tetrahedrons sharing a triface ('nn')
/// @param[out] num_regions Number of regions in output mesh
/// @return 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
template <
typename DerivedV,
typename DerivedF,
typename DerivedH,
typename DerivedVM,
typename DerivedFM,
typename DerivedR,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTM,
typename DerivedTR,
typename DerivedTN,
typename DerivedPT,
typename DerivedFT>
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);
/// \overload
IGL_INLINE int tetrahedralize(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F,
const Eigen::MatrixBase<DerivedH>& H,
const Eigen::MatrixBase<DerivedVM>& VM,
const Eigen::MatrixBase<DerivedFM>& FM,
const Eigen::MatrixBase<DerivedR>& R,
const std::string switches,
std::vector<std::vector<REAL > > & TV,
std::vector<std::vector<int > > & TT,
std::vector<std::vector<int> > & TF);
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
Eigen::PlainObjectBase<DerivedTF>& TF,
Eigen::PlainObjectBase<DerivedTM>& TM,
Eigen::PlainObjectBase<DerivedTR>& TR,
Eigen::PlainObjectBase<DerivedTN>& TN,
Eigen::PlainObjectBase<DerivedPT>& PT,
Eigen::PlainObjectBase<DerivedFT>& FT,
int & num_regions);
/// \overload
template <
typename DerivedV,
typename DerivedF,
typename DerivedTV,
typename DerivedTT,
typename DerivedV,
typename DerivedF,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF>
IGL_INLINE int tetrahedralize(
const Eigen::MatrixBase<DerivedV>& V,
@@ -83,61 +96,6 @@ namespace igl
Eigen::PlainObjectBase<DerivedTV>& TV,
Eigen::PlainObjectBase<DerivedTT>& TT,
Eigen::PlainObjectBase<DerivedTF>& TF);
/// \overload
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::string switches,
std::vector<std::vector<REAL > > & TV,
std::vector<std::vector<int > > & TT,
std::vector<std::vector<int> > & TF,
std::vector<int> & TM);
/// \overload
template <
typename DerivedV,
typename DerivedF,
typename DerivedVM,
typename DerivedFM,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTM>
IGL_INLINE int tetrahedralize(
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);
/// \overload
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);
}
}
}
@@ -2,6 +2,9 @@
#include <igl/setxor.h>
#include <igl/copyleft/tetgen/tetrahedralize.h>
#include <igl/unique_simplices.h>
#include <igl/matlab_format.h>
#include <iostream>
TEST_CASE("tetrahedralize: single_tet", "[igl/copyleft/tetgen]")
{
@@ -14,6 +17,7 @@ TEST_CASE("tetrahedralize: single_tet", "[igl/copyleft/tetgen]")
Eigen::MatrixXd TV;
Eigen::MatrixXi TT,TF;
igl::copyleft::tetgen::tetrahedralize(V,F,"cpQ",TV,TT,TF);
REQUIRE (4 == TV.rows());
REQUIRE (1 == TT.rows());
REQUIRE (4 == TF.rows());
@@ -26,6 +30,54 @@ TEST_CASE("tetrahedralize: single_tet", "[igl/copyleft/tetgen]")
test_common::assert_eq(TV,V);
}
TEST_CASE("tetrahedralize: two_tets", "[igl/copyleft/tetgen]")
{
const Eigen::MatrixXd V = (Eigen::MatrixXd(5,3)<<
2,1,0,
1,-1,0,
-1,-1,0,
-1,1,0,
0,0,1 ).finished();
Eigen::MatrixXi F(0,3);
Eigen::MatrixXd TV;
Eigen::MatrixXi TT,TF;
Eigen::MatrixXd H,R;
Eigen::VectorXi FM,PT,TM,TR;
Eigen::VectorXi VM = (Eigen::VectorXi(5)<< 0, 1, 2, 3, 4).finished();
Eigen::MatrixXi TN,FT;
int num_regions;
igl::copyleft::tetgen::tetrahedralize(
V,F,H,VM,FM,R,"cpnnfmQ",TV,TT,TF,TM,TR,TN,PT,FT,num_regions);
REQUIRE (5 == TV.rows());
REQUIRE (2 == TT.rows());
REQUIRE (7 == TF.rows());
REQUIRE (TV.rows() == TM.rows());
REQUIRE (TN.rows() == TT.rows());
REQUIRE (TN.cols() == 4);
REQUIRE((TN.row(0).array() == 1).any());
REQUIRE((TN.row(1).array() == 0).any());
REQUIRE(FT.rows() == TF.rows());
REQUIRE(PT.size() == TV.rows());
REQUIRE(PT(0) == 0);
REQUIRE(PT(2) == 1);
Eigen::MatrixXi TTcorrect(2,4);
TTcorrect<<
4,0,1,3,
4,3,1,2;
{
Eigen::MatrixXi TT_combined = Eigen::MatrixXi(TT.rows()+TTcorrect.rows(),TT.cols());
TT_combined<<TT,TTcorrect;
Eigen::MatrixXi TT_unique;
igl::unique_simplices(TT_combined,TT_unique);
REQUIRE(TT_unique.rows() == TT.rows());
}
test_common::assert_eq(TV,V);
}
TEST_CASE("tetrahedralize: schoenhardt", "[igl/copyleft/tetgen]")
{
const Eigen::MatrixXd V = (Eigen::MatrixXd(6,3)<<