rm vector overloads and simplify api (#2290) [ci skip]
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)<<
|
||||
|
||||
Reference in New Issue
Block a user