#ifndef tetgenH
#define tetgenH
#define TETLIBRARY
#define REAL double
#define FILENAMESIZE 1024
#define INPUTLINESIZE 2048
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#include <vector>
#ifdef _MSC_VER
#define ULONG ptrdiff_t
#else
#include <stdint.h>
#define ULONG unsigned long
#endif
class tetgenio {
public:
typedef struct {
int *vertexlist;
int numberofvertices;
} polygon;
typedef struct {
polygon *polygonlist;
int numberofpolygons;
REAL *holelist;
int numberofholes;
} facet;
typedef struct {
int v1, v2;
REAL vnormal[3];
} voroedge;
typedef struct {
int c1, c2;
int *elist;
} vorofacet;
typedef struct {
REAL uv[2];
int tag;
int type; } pointparam;
typedef REAL (* GetVertexParamOnEdge)(void*, int, int);
typedef void (* GetSteinerOnEdge)(void*, int, REAL, REAL*);
typedef void (* GetVertexParamOnFace)(void*, int, int, REAL*);
typedef void (* GetEdgeSteinerParamOnFace)(void*, int, REAL, int, REAL*);
typedef void (* GetSteinerOnFace)(void*, int, REAL*, REAL*);
typedef bool (* TetSizeFunc)(REAL*, REAL*, REAL*, REAL*, REAL*, REAL);
int firstnumber;
int mesh_dim;
int useindex;
REAL *pointlist;
REAL *pointattributelist;
REAL *pointmtrlist;
int *pointmarkerlist;
pointparam *pointparamlist;
int numberofpoints;
int numberofpointattributes;
int numberofpointmtrs;
int *tetrahedronlist;
REAL *tetrahedronattributelist;
REAL *tetrahedronvolumelist;
int *neighborlist;
int numberoftetrahedra;
int numberofcorners;
int numberoftetrahedronattributes;
facet *facetlist;
int *facetmarkerlist;
int numberoffacets;
REAL *holelist;
int numberofholes;
REAL *regionlist;
int numberofregions;
REAL *facetconstraintlist;
int numberoffacetconstraints;
REAL *segmentconstraintlist;
int numberofsegmentconstraints;
int *trifacelist;
int *trifacemarkerlist;
int *o2facelist;
int *adjtetlist;
int numberoftrifaces;
typedef struct {
int points[6]; int marker; int cell; } marked_face_t;
std::vector<marked_face_t> marked_faces;
int *edgelist;
int *edgemarkerlist;
int *o2edgelist;
int *edgeadjtetlist;
int numberofedges;
REAL *vpointlist;
voroedge *vedgelist;
vorofacet *vfacetlist;
int **vcelllist;
int numberofvpoints;
int numberofvedges;
int numberofvfacets;
int numberofvcells;
void *geomhandle;
GetVertexParamOnEdge getvertexparamonedge;
GetSteinerOnEdge getsteineronedge;
GetVertexParamOnFace getvertexparamonface;
GetEdgeSteinerParamOnFace getedgesteinerparamonface;
GetSteinerOnFace getsteineronface;
TetSizeFunc tetunsuitable;
bool load_node_call(FILE* infile, int markers, int uvflag, char*);
bool load_node(char*);
bool load_edge(char*);
bool load_face(char*);
bool load_tet(char*);
bool load_vol(char*);
bool load_var(char*);
bool load_mtr(char*);
bool load_pbc(char*);
bool load_poly(char*);
bool load_off(char*);
bool load_ply(char*);
bool load_stl(char*);
bool load_vtk(char*);
bool load_medit(char*, int);
bool load_plc(char*, int);
bool load_tetmesh(char*, int);
void save_nodes(char*);
void save_elements(char*);
void save_faces(char*);
void save_edges(char*);
void save_neighbors(char*);
void save_poly(char*);
void save_faces2smesh(char*);
char *readline(char* string, FILE* infile, int *linenumber);
char *findnextfield(char* string);
char *readnumberline(char* string, FILE* infile, char* infilename);
char *findnextnumber(char* string);
static void init(polygon* p) {
p->vertexlist = (int *) NULL;
p->numberofvertices = 0;
}
static void init(facet* f) {
f->polygonlist = (polygon *) NULL;
f->numberofpolygons = 0;
f->holelist = (REAL *) NULL;
f->numberofholes = 0;
}
void initialize()
{
firstnumber = 0;
mesh_dim = 3;
useindex = 1;
pointlist = (REAL *) NULL;
pointattributelist = (REAL *) NULL;
pointmtrlist = (REAL *) NULL;
pointmarkerlist = (int *) NULL;
pointparamlist = (pointparam *) NULL;
numberofpoints = 0;
numberofpointattributes = 0;
numberofpointmtrs = 0;
tetrahedronlist = (int *) NULL;
tetrahedronattributelist = (REAL *) NULL;
tetrahedronvolumelist = (REAL *) NULL;
neighborlist = (int *) NULL;
numberoftetrahedra = 0;
numberofcorners = 4;
numberoftetrahedronattributes = 0;
trifacelist = (int *) NULL;
trifacemarkerlist = (int *) NULL;
o2facelist = (int *) NULL;
adjtetlist = (int *) NULL;
numberoftrifaces = 0;
edgelist = (int *) NULL;
edgemarkerlist = (int *) NULL;
o2edgelist = (int *) NULL;
edgeadjtetlist = (int *) NULL;
numberofedges = 0;
facetlist = (facet *) NULL;
facetmarkerlist = (int *) NULL;
numberoffacets = 0;
holelist = (REAL *) NULL;
numberofholes = 0;
regionlist = (REAL *) NULL;
numberofregions = 0;
facetconstraintlist = (REAL *) NULL;
numberoffacetconstraints = 0;
segmentconstraintlist = (REAL *) NULL;
numberofsegmentconstraints = 0;
vpointlist = (REAL *) NULL;
vedgelist = (voroedge *) NULL;
vfacetlist = (vorofacet *) NULL;
vcelllist = (int **) NULL;
numberofvpoints = 0;
numberofvedges = 0;
numberofvfacets = 0;
numberofvcells = 0;
tetunsuitable = NULL;
geomhandle = NULL;
getvertexparamonedge = NULL;
getsteineronedge = NULL;
getvertexparamonface = NULL;
getedgesteinerparamonface = NULL;
getsteineronface = NULL;
}
void deinitialize()
{
int i, j;
if (pointlist != (REAL *) NULL) {
delete [] pointlist;
}
if (pointattributelist != (REAL *) NULL) {
delete [] pointattributelist;
}
if (pointmtrlist != (REAL *) NULL) {
delete [] pointmtrlist;
}
if (pointmarkerlist != (int *) NULL) {
delete [] pointmarkerlist;
}
if (pointparamlist != (pointparam *) NULL) {
delete [] pointparamlist;
}
if (tetrahedronlist != (int *) NULL) {
delete [] tetrahedronlist;
}
if (tetrahedronattributelist != (REAL *) NULL) {
delete [] tetrahedronattributelist;
}
if (tetrahedronvolumelist != (REAL *) NULL) {
delete [] tetrahedronvolumelist;
}
if (neighborlist != (int *) NULL) {
delete [] neighborlist;
}
if (trifacelist != (int *) NULL) {
delete [] trifacelist;
}
if (trifacemarkerlist != (int *) NULL) {
delete [] trifacemarkerlist;
}
if (o2facelist != (int *) NULL) {
delete [] o2facelist;
}
if (adjtetlist != (int *) NULL) {
delete [] adjtetlist;
}
if (edgelist != (int *) NULL) {
delete [] edgelist;
}
if (edgemarkerlist != (int *) NULL) {
delete [] edgemarkerlist;
}
if (o2edgelist != (int *) NULL) {
delete [] o2edgelist;
}
if (edgeadjtetlist != (int *) NULL) {
delete [] edgeadjtetlist;
}
if (facetlist != (facet *) NULL) {
facet *f;
polygon *p;
for (i = 0; i < numberoffacets; i++) {
f = &facetlist[i];
for (j = 0; j < f->numberofpolygons; j++) {
p = &f->polygonlist[j];
delete [] p->vertexlist;
}
delete [] f->polygonlist;
if (f->holelist != (REAL *) NULL) {
delete [] f->holelist;
}
}
delete [] facetlist;
}
if (facetmarkerlist != (int *) NULL) {
delete [] facetmarkerlist;
}
if (holelist != (REAL *) NULL) {
delete [] holelist;
}
if (regionlist != (REAL *) NULL) {
delete [] regionlist;
}
if (facetconstraintlist != (REAL *) NULL) {
delete [] facetconstraintlist;
}
if (segmentconstraintlist != (REAL *) NULL) {
delete [] segmentconstraintlist;
}
if (vpointlist != (REAL *) NULL) {
delete [] vpointlist;
}
if (vedgelist != (voroedge *) NULL) {
delete [] vedgelist;
}
if (vfacetlist != (vorofacet *) NULL) {
for (i = 0; i < numberofvfacets; i++) {
delete [] vfacetlist[i].elist;
}
delete [] vfacetlist;
}
if (vcelllist != (int **) NULL) {
for (i = 0; i < numberofvcells; i++) {
delete [] vcelllist[i];
}
delete [] vcelllist;
}
}
tetgenio() {initialize();}
~tetgenio() {deinitialize();}
};
class tetgenbehavior {
public:
int plc; int psc; int refine; int quality; int nobisect; int coarsen; int weighted; int brio_hilbert; int incrflip; int flipinsert; int metric; int varvolume; int fixedvolume; int regionattrib; int conforming; int insertaddpoints; int diagnose; int convex; int nomergefacet; int nomergevertex; int noexact; int nostaticfilter; int zeroindex; int facesout; int edgesout; int neighout; int voroout; int meditview; int vtkview; int nobound; int nonodewritten; int noelewritten; int nofacewritten; int noiterationnum; int nojettison; int reversetetori; int docheck; int quiet; int verbose;
int vertexperblock; int tetrahedraperblock; int shellfaceperblock; int nobisect_param; int addsteiner_algo; int coarsen_param; int weighted_param; int fliplinklevel; int flipstarsize; int fliplinklevelinc; int reflevel; int optlevel; int optscheme; int delmaxfliplevel; int order; int steinerleft; int no_sort; int hilbert_order; int hilbert_limit; int brio_threshold; REAL brio_ratio; REAL facet_ang_tol; REAL maxvolume; REAL minratio; REAL mindihedral; REAL optmaxdihedral; REAL optminsmtdihed; REAL optminslidihed; REAL epsilon; REAL minedgelength; REAL coarsen_percent;
char commandline[1024];
char infilename[1024];
char outfilename[1024];
char addinfilename[1024];
char bgmeshfilename[1024];
enum objecttype {NODES, POLY, OFF, PLY, STL, MEDIT, VTK, MESH} object;
void syntax();
void usage();
bool parse_commandline(int argc, char const * const * argv);
bool parse_commandline(char const *switches) {
return parse_commandline(0, &switches);
}
tetgenbehavior()
{
plc = 0;
psc = 0;
refine = 0;
quality = 0;
nobisect = 0;
coarsen = 0;
metric = 0;
weighted = 0;
brio_hilbert = 1;
incrflip = 0;
flipinsert = 0;
varvolume = 0;
fixedvolume = 0;
noexact = 0;
nostaticfilter = 0;
insertaddpoints = 0;
regionattrib = 0;
conforming = 0;
diagnose = 0;
convex = 0;
zeroindex = 0;
facesout = 0;
edgesout = 0;
neighout = 0;
voroout = 0;
meditview = 0;
vtkview = 0;
nobound = 0;
nonodewritten = 0;
noelewritten = 0;
nofacewritten = 0;
noiterationnum = 0;
nomergefacet = 0;
nomergevertex = 0;
nojettison = 0;
reversetetori = 0;
docheck = 0;
quiet = 0;
verbose = 0;
vertexperblock = 4092;
tetrahedraperblock = 8188;
shellfaceperblock = 4092;
nobisect_param = 2;
addsteiner_algo = 1;
coarsen_param = 0;
weighted_param = 0;
fliplinklevel = -1; flipstarsize = -1; fliplinklevelinc = 1;
reflevel = 3;
optscheme = 7; optlevel = 2;
delmaxfliplevel = 1;
order = 1;
steinerleft = -1;
no_sort = 0;
hilbert_order = 52; hilbert_limit = 8;
brio_threshold = 64;
brio_ratio = 0.125;
facet_ang_tol = 179.9;
maxvolume = -1.0;
minratio = 2.0;
mindihedral = 0.0; optmaxdihedral = 165.00; optminsmtdihed = 179.00; optminslidihed = 179.00; epsilon = 1.0e-8;
minedgelength = 0.0;
coarsen_percent = 1.0;
object = NODES;
commandline[0] = '\0';
infilename[0] = '\0';
outfilename[0] = '\0';
addinfilename[0] = '\0';
bgmeshfilename[0] = '\0';
}
};
int exactinit(int, int, int, REAL, REAL, REAL);
REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd);
REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe);
REAL orient4d(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe,
REAL ah, REAL bh, REAL ch, REAL dh, REAL eh);
class tetgenmesh {
public:
typedef REAL **tetrahedron;
typedef REAL **shellface;
typedef REAL *point;
class triface {
public:
tetrahedron *tet;
int ver; triface() : tet(0), ver(0) {}
triface& operator=(const triface& t) {
tet = t.tet; ver = t.ver;
return *this;
}
};
class face {
public:
shellface *sh;
int shver; face() : sh(0), shver(0) {}
face& operator=(const face& s) {
sh = s.sh; shver = s.shver;
return *this;
}
};
class arraypool {
public:
int objectbytes;
int objectsperblock;
int log2objectsperblock;
int objectsperblockmark;
int toparraylen;
char **toparray;
long objects;
ULONG totalmemory;
void restart();
void poolinit(int sizeofobject, int log2objperblk);
char* getblock(int objectindex);
void* lookup(int objectindex);
int newindex(void **newptr);
arraypool(int sizeofobject, int log2objperblk);
~arraypool();
};
#define fastlookup(pool, index) \
(void *) ((pool)->toparray[(index) >> (pool)->log2objectsperblock] + \
((index) & (pool)->objectsperblockmark) * (pool)->objectbytes)
class memorypool {
public:
void **firstblock, **nowblock;
void *nextitem;
void *deaditemstack;
void **pathblock;
void *pathitem;
int alignbytes;
int itembytes, itemwords;
int itemsperblock;
long items, maxitems;
int unallocateditems;
int pathitemsleft;
memorypool();
memorypool(int, int, int, int);
~memorypool();
void poolinit(int, int, int, int);
void restart();
void *alloc();
void dealloc(void*);
void traversalinit();
void *traverse();
};
class badface {
public:
triface tt;
face ss;
REAL key, cent[6]; point forg, fdest, fapex, foppo, noppo;
badface *nextitem;
badface() : key(0), forg(0), fdest(0), fapex(0), foppo(0), noppo(0),
nextitem(0) {}
};
class insertvertexflags {
public:
int iloc; int bowywat, lawson;
int splitbdflag, validflag, respectbdflag;
int rejflag, chkencflag, cdtflag;
int assignmeshsize;
int sloc, sbowywat;
int refineflag; triface refinetet;
face refinesh;
int smlenflag; REAL smlen; point parentpt;
insertvertexflags() {
iloc = bowywat = lawson = 0;
splitbdflag = validflag = respectbdflag = 0;
rejflag = chkencflag = cdtflag = 0;
assignmeshsize = 0;
sloc = sbowywat = 0;
refineflag = 0;
refinetet.tet = NULL;
refinesh.sh = NULL;
smlenflag = 0;
smlen = 0.0;
}
};
class flipconstraints {
public:
int enqflag; int chkencflag;
int unflip; int collectnewtets; int collectencsegflag;
int remove_ndelaunay_edge; REAL bak_tetprism_vol; REAL tetprism_vol_sum;
int remove_large_angle; REAL cosdihed_in; REAL cosdihed_out;
int checkflipeligibility;
point seg[2]; point fac[3]; point remvert;
flipconstraints() {
enqflag = 0;
chkencflag = 0;
unflip = 0;
collectnewtets = 0;
collectencsegflag = 0;
remove_ndelaunay_edge = 0;
bak_tetprism_vol = 0.0;
tetprism_vol_sum = 0.0;
remove_large_angle = 0;
cosdihed_in = 0.0;
cosdihed_out = 0.0;
checkflipeligibility = 0;
seg[0] = NULL;
fac[0] = NULL;
remvert = NULL;
}
};
class optparameters {
public:
int max_min_volume; int max_min_aspectratio; int min_max_dihedangle;
REAL initval, imprval;
int numofsearchdirs;
REAL searchstep;
int maxiter; int smthiter;
optparameters() {
max_min_volume = 0;
max_min_aspectratio = 0;
min_max_dihedangle = 0;
initval = imprval = 0.0;
numofsearchdirs = 10;
searchstep = 0.01;
maxiter = -1; smthiter = 0;
}
};
enum verttype {UNUSEDVERTEX, DUPLICATEDVERTEX, RIDGEVERTEX, ACUTEVERTEX,
FACETVERTEX, VOLVERTEX, FREESEGVERTEX, FREEFACETVERTEX,
FREEVOLVERTEX, NREGULARVERTEX, DEADVERTEX};
enum interresult {DISJOINT, INTERSECT, SHAREVERT, SHAREEDGE, SHAREFACE,
TOUCHEDGE, TOUCHFACE, ACROSSVERT, ACROSSEDGE, ACROSSFACE,
COLLISIONFACE, ACROSSSEG, ACROSSSUB};
enum locateresult {UNKNOWN, OUTSIDE, INTETRAHEDRON, ONFACE, ONEDGE, ONVERTEX,
ENCVERTEX, ENCSEGMENT, ENCSUBFACE, NEARVERTEX, NONREGULAR,
INSTAR, BADELEMENT};
tetgenio *in, *addin;
tetgenbehavior *b;
tetgenmesh *bgm;
memorypool *tetrahedrons, *subfaces, *subsegs, *points;
memorypool *tet2subpool, *tet2segpool;
memorypool *badtetrahedrons, *badsubfacs, *badsubsegs;
memorypool *flippool;
arraypool *unflipqueue;
badface *flipstack;
arraypool *cavetetlist, *cavebdrylist, *caveoldtetlist;
arraypool *cavetetshlist, *cavetetseglist, *cavetetvertlist;
arraypool *caveencshlist, *caveencseglist;
arraypool *caveshlist, *caveshbdlist, *cavesegshlist;
arraypool *subsegstack, *subfacstack, *subvertstack;
arraypool *encseglist, *encshlist;
int *idx2facetlist;
point *facetverticeslist;
point *segmentendpointslist;
point dummypoint;
triface recenttet;
face recentsh;
static REAL PI;
point *highordertable;
int numpointattrib; int numelemattrib; int sizeoftensor; int pointmtrindex; int pointparamindex; int point2simindex; int pointmarkindex; int elemattribindex; int volumeboundindex; int elemmarkerindex; int shmarkindex; int areaboundindex; int checksubsegflag; int checksubfaceflag; int checkconstraints; int nonconvex; int autofliplinklevel; int useinsertradius; long samples; ULONG randomseed; REAL cosmaxdihed, cosmindihed; REAL cossmtdihed; REAL cosslidihed; REAL minfaceang, minfacetdihed; REAL tetprism_vol_sum; REAL longest; REAL xmax, xmin, ymax, ymin, zmax, zmin;
long insegments; long hullsize; long meshedges; long meshhulledges; long steinerleft; long dupverts; long unuverts; long nonregularcount; long st_segref_count, st_facref_count, st_volref_count; long fillregioncount, cavitycount, cavityexpcount;
long flip14count, flip26count, flipn2ncount;
long flip23count, flip32count, flip44count, flip41count;
long flip31count, flip22count;
ULONG totalworkmemory;
static int bondtbl[12][12], fsymtbl[12][12];
static int esymtbl[12], enexttbl[12], eprevtbl[12];
static int enextesymtbl[12], eprevesymtbl[12];
static int eorgoppotbl[12], edestoppotbl[12];
static int facepivot1[12], facepivot2[12][12];
static int orgpivot[12], destpivot[12], apexpivot[12], oppopivot[12];
static int tsbondtbl[12][6], stbondtbl[12][6];
static int tspivottbl[12][6], stpivottbl[12][6];
static int ver2edge[12], edge2ver[6], epivot[12];
static int sorgpivot [6], sdestpivot[6], sapexpivot[6];
static int snextpivot[6];
void inittables();
inline tetrahedron encode(triface& t);
inline tetrahedron encode2(tetrahedron* ptr, int ver);
inline void decode(tetrahedron ptr, triface& t);
inline void bond(triface& t1, triface& t2);
inline void dissolve(triface& t);
inline void esym(triface& t1, triface& t2);
inline void esymself(triface& t);
inline void enext(triface& t1, triface& t2);
inline void enextself(triface& t);
inline void eprev(triface& t1, triface& t2);
inline void eprevself(triface& t);
inline void enextesym(triface& t1, triface& t2);
inline void enextesymself(triface& t);
inline void eprevesym(triface& t1, triface& t2);
inline void eprevesymself(triface& t);
inline void eorgoppo(triface& t1, triface& t2);
inline void eorgoppoself(triface& t);
inline void edestoppo(triface& t1, triface& t2);
inline void edestoppoself(triface& t);
inline void fsym(triface& t1, triface& t2);
inline void fsymself(triface& t);
inline void fnext(triface& t1, triface& t2);
inline void fnextself(triface& t);
inline point org (triface& t);
inline point dest(triface& t);
inline point apex(triface& t);
inline point oppo(triface& t);
inline void setorg (triface& t, point p);
inline void setdest(triface& t, point p);
inline void setapex(triface& t, point p);
inline void setoppo(triface& t, point p);
inline REAL elemattribute(tetrahedron* ptr, int attnum);
inline void setelemattribute(tetrahedron* ptr, int attnum, REAL value);
inline REAL volumebound(tetrahedron* ptr);
inline void setvolumebound(tetrahedron* ptr, REAL value);
inline int elemindex(tetrahedron* ptr);
inline void setelemindex(tetrahedron* ptr, int value);
inline int elemmarker(tetrahedron* ptr);
inline void setelemmarker(tetrahedron* ptr, int value);
inline void infect(triface& t);
inline void uninfect(triface& t);
inline bool infected(triface& t);
inline void marktest(triface& t);
inline void unmarktest(triface& t);
inline bool marktested(triface& t);
inline void markface(triface& t);
inline void unmarkface(triface& t);
inline bool facemarked(triface& t);
inline void markedge(triface& t);
inline void unmarkedge(triface& t);
inline bool edgemarked(triface& t);
inline void marktest2(triface& t);
inline void unmarktest2(triface& t);
inline bool marktest2ed(triface& t);
inline int elemcounter(triface& t);
inline void setelemcounter(triface& t, int value);
inline void increaseelemcounter(triface& t);
inline void decreaseelemcounter(triface& t);
inline bool ishulltet(triface& t);
inline bool isdeadtet(triface& t);
inline void sdecode(shellface sptr, face& s);
inline shellface sencode(face& s);
inline shellface sencode2(shellface *sh, int shver);
inline void spivot(face& s1, face& s2);
inline void spivotself(face& s);
inline void sbond(face& s1, face& s2);
inline void sbond1(face& s1, face& s2);
inline void sdissolve(face& s);
inline point sorg(face& s);
inline point sdest(face& s);
inline point sapex(face& s);
inline void setsorg(face& s, point pointptr);
inline void setsdest(face& s, point pointptr);
inline void setsapex(face& s, point pointptr);
inline void sesym(face& s1, face& s2);
inline void sesymself(face& s);
inline void senext(face& s1, face& s2);
inline void senextself(face& s);
inline void senext2(face& s1, face& s2);
inline void senext2self(face& s);
inline REAL areabound(face& s);
inline void setareabound(face& s, REAL value);
inline int shellmark(face& s);
inline void setshellmark(face& s, int value);
inline void sinfect(face& s);
inline void suninfect(face& s);
inline bool sinfected(face& s);
inline void smarktest(face& s);
inline void sunmarktest(face& s);
inline bool smarktested(face& s);
inline void smarktest2(face& s);
inline void sunmarktest2(face& s);
inline bool smarktest2ed(face& s);
inline void smarktest3(face& s);
inline void sunmarktest3(face& s);
inline bool smarktest3ed(face& s);
inline void setfacetindex(face& f, int value);
inline int getfacetindex(face& f);
inline void tsbond(triface& t, face& s);
inline void tsdissolve(triface& t);
inline void stdissolve(face& s);
inline void tspivot(triface& t, face& s);
inline void stpivot(face& s, triface& t);
inline void tssbond1(triface& t, face& seg);
inline void sstbond1(face& s, triface& t);
inline void tssdissolve1(triface& t);
inline void sstdissolve1(face& s);
inline void tsspivot1(triface& t, face& s);
inline void sstpivot1(face& s, triface& t);
inline void ssbond(face& s, face& edge);
inline void ssbond1(face& s, face& edge);
inline void ssdissolve(face& s);
inline void sspivot(face& s, face& edge);
inline int pointmark(point pt);
inline void setpointmark(point pt, int value);
inline enum verttype pointtype(point pt);
inline void setpointtype(point pt, enum verttype value);
inline int pointgeomtag(point pt);
inline void setpointgeomtag(point pt, int value);
inline REAL pointgeomuv(point pt, int i);
inline void setpointgeomuv(point pt, int i, REAL value);
inline void pinfect(point pt);
inline void puninfect(point pt);
inline bool pinfected(point pt);
inline void pmarktest(point pt);
inline void punmarktest(point pt);
inline bool pmarktested(point pt);
inline void pmarktest2(point pt);
inline void punmarktest2(point pt);
inline bool pmarktest2ed(point pt);
inline void pmarktest3(point pt);
inline void punmarktest3(point pt);
inline bool pmarktest3ed(point pt);
inline tetrahedron point2tet(point pt);
inline void setpoint2tet(point pt, tetrahedron value);
inline shellface point2sh(point pt);
inline void setpoint2sh(point pt, shellface value);
inline point point2ppt(point pt);
inline void setpoint2ppt(point pt, point value);
inline tetrahedron point2bgmtet(point pt);
inline void setpoint2bgmtet(point pt, tetrahedron value);
inline void setpointinsradius(point pt, REAL value);
inline REAL getpointinsradius(point pt);
inline void point2tetorg(point pt, triface& t);
inline void point2shorg(point pa, face& s);
inline point farsorg(face& seg);
inline point farsdest(face& seg);
void tetrahedrondealloc(tetrahedron*);
tetrahedron *tetrahedrontraverse();
tetrahedron *alltetrahedrontraverse();
void shellfacedealloc(memorypool*, shellface*);
shellface *shellfacetraverse(memorypool*);
void pointdealloc(point);
point pointtraverse();
void makeindex2pointmap(point*&);
void makepoint2submap(memorypool*, int*&, face*&);
void maketetrahedron(triface*);
void makeshellface(memorypool*, face*);
void makepoint(point*, enum verttype);
void initializepools();
REAL insphere_s(REAL*, REAL*, REAL*, REAL*, REAL*);
REAL orient4d_s(REAL*, REAL*, REAL*, REAL*, REAL*,
REAL, REAL, REAL, REAL, REAL);
int tri_edge_2d(point, point, point, point, point, point, int, int*, int*);
int tri_edge_tail(point, point, point, point, point, point, REAL, REAL, int,
int*, int*);
int tri_edge_test(point, point, point, point, point, point, int, int*, int*);
int tri_edge_inter_tail(point, point, point, point, point, REAL, REAL);
int tri_tri_inter(point, point, point, point, point, point);
inline REAL dot(REAL* v1, REAL* v2);
inline void cross(REAL* v1, REAL* v2, REAL* n);
bool lu_decmp(REAL lu[4][4], int n, int* ps, REAL* d, int N);
void lu_solve(REAL lu[4][4], int n, int* ps, REAL* b, int N);
REAL incircle3d(point pa, point pb, point pc, point pd);
REAL orient3dfast(REAL *pa, REAL *pb, REAL *pc, REAL *pd);
inline REAL norm2(REAL x, REAL y, REAL z);
inline REAL distance(REAL* p1, REAL* p2);
void facenormal(point pa, point pb, point pc, REAL *n, int pivot, REAL *lav);
REAL shortdistance(REAL* p, REAL* e1, REAL* e2);
REAL triarea(REAL* pa, REAL* pb, REAL* pc);
REAL interiorangle(REAL* o, REAL* p1, REAL* p2, REAL* n);
void projpt2edge(REAL* p, REAL* e1, REAL* e2, REAL* prj);
void projpt2face(REAL* p, REAL* f1, REAL* f2, REAL* f3, REAL* prj);
REAL facedihedral(REAL* pa, REAL* pb, REAL* pc1, REAL* pc2);
bool tetalldihedral(point, point, point, point, REAL*, REAL*, REAL*);
void tetallnormal(point, point, point, point, REAL N[4][3], REAL* volume);
REAL tetaspectratio(point, point, point, point);
bool circumsphere(REAL*, REAL*, REAL*, REAL*, REAL* cent, REAL* radius);
bool orthosphere(REAL*,REAL*,REAL*,REAL*,REAL,REAL,REAL,REAL,REAL*,REAL*);
void planelineint(REAL*, REAL*, REAL*, REAL*, REAL*, REAL*, REAL*);
int linelineint(REAL*, REAL*, REAL*, REAL*, REAL*, REAL*, REAL*, REAL*);
REAL tetprismvol(REAL* pa, REAL* pb, REAL* pc, REAL* pd);
bool calculateabovepoint(arraypool*, point*, point*, point*);
void calculateabovepoint4(point, point, point, point);
void flip23(triface*, int, flipconstraints* fc);
void flip32(triface*, int, flipconstraints* fc);
void flip41(triface*, int, flipconstraints* fc);
int flipnm(triface*, int n, int level, int, flipconstraints* fc);
int flipnm_post(triface*, int n, int nn, int, flipconstraints* fc);
int insertpoint(point, triface*, face*, face*, insertvertexflags*);
void insertpoint_abort(face*, insertvertexflags*);
void transfernodes();
int transgc[8][3][8], tsb1mod3[8];
void hilbert_init(int n);
int hilbert_split(point* vertexarray, int arraysize, int gc0, int gc1,
REAL, REAL, REAL, REAL, REAL, REAL);
void hilbert_sort3(point* vertexarray, int arraysize, int e, int d,
REAL, REAL, REAL, REAL, REAL, REAL, int depth);
void brio_multiscale_sort(point*,int,int threshold,REAL ratio,int* depth);
ULONG randomnation(unsigned int choices);
void randomsample(point searchpt, triface *searchtet);
enum locateresult locate(point searchpt, triface *searchtet);
void flippush(badface*&, triface*);
int incrementalflip(point newpt, int, flipconstraints *fc);
void initialdelaunay(point pa, point pb, point pc, point pd);
void incrementaldelaunay(clock_t&);
void flipshpush(face*);
void flip22(face*, int, int);
void flip31(face*, int);
long lawsonflip();
int sinsertvertex(point newpt, face*, face*, int iloc, int bowywat, int);
int sremovevertex(point delpt, face*, face*, int lawson);
enum locateresult slocate(point, face*, int, int, int);
enum interresult sscoutsegment(face*, point);
void scarveholes(int, REAL*);
void triangulate(int, arraypool*, arraypool*, int, REAL*);
void unifysubfaces(face*, face*);
void unifysegments();
void mergefacets();
void identifypscedges(point*);
void meshsurface();
void interecursive(shellface** subfacearray, int arraysize, int axis,
REAL, REAL, REAL, REAL, REAL, REAL, int* internum);
void detectinterfaces();
void makesegmentendpointsmap();
enum interresult finddirection(triface* searchtet, point endpt);
enum interresult scoutsegment(point, point, triface*, point*, arraypool*);
int getsteinerptonsegment(face* seg, point refpt, point steinpt);
void delaunizesegments();
enum interresult scoutsubface(face* searchsh, triface* searchtet);
void formregion(face*, arraypool*, arraypool*, arraypool*);
int scoutcrossedge(triface& crosstet, arraypool*, arraypool*);
bool formcavity(triface*, arraypool*, arraypool*, arraypool*, arraypool*,
arraypool*, arraypool*);
void delaunizecavity(arraypool*, arraypool*, arraypool*, arraypool*,
arraypool*, arraypool*);
bool fillcavity(arraypool*, arraypool*, arraypool*, arraypool*,
arraypool*, arraypool*, triface* crossedge);
void carvecavity(arraypool*, arraypool*, arraypool*);
void restorecavity(arraypool*, arraypool*, arraypool*, arraypool*);
void flipcertify(triface *chkface, badface **pqueue, point, point, point);
void flipinsertfacet(arraypool*, arraypool*, arraypool*, arraypool*);
bool fillregion(arraypool* missingshs, arraypool*, arraypool* newshs);
int insertpoint_cdt(point, triface*, face*, face*, insertvertexflags*,
arraypool*, arraypool*, arraypool*, arraypool*,
arraypool*, arraypool*);
void refineregion(face&, arraypool*, arraypool*, arraypool*, arraypool*,
arraypool*, arraypool*);
void constrainedfacets();
void constraineddelaunay(clock_t&);
int checkflipeligibility(int fliptype, point, point, point, point, point,
int level, int edgepivot, flipconstraints* fc);
int removeedgebyflips(triface*, flipconstraints*);
int removefacebyflips(triface*, flipconstraints*);
int recoveredgebyflips(point, point, triface*, int fullsearch);
int add_steinerpt_in_schoenhardtpoly(triface*, int, int chkencflag);
int add_steinerpt_in_segment(face*, int searchlevel);
int addsteiner4recoversegment(face*, int);
int recoversegments(arraypool*, int fullsearch, int steinerflag);
int recoverfacebyflips(point, point, point, face*, triface*);
int recoversubfaces(arraypool*, int steinerflag);
int getvertexstar(int, point searchpt, arraypool*, arraypool*, arraypool*);
int getedge(point, point, triface*);
int reduceedgesatvertex(point startpt, arraypool* endptlist);
int removevertexbyflips(point steinerpt);
int suppressbdrysteinerpoint(point steinerpt);
int suppresssteinerpoints();
void recoverboundary(clock_t&);
void carveholes();
void reconstructmesh();
int scoutpoint(point, triface*, int randflag);
REAL getpointmeshsize(point, triface*, int iloc);
void interpolatemeshsize();
void insertconstrainedpoints(point *insertarray, int arylen, int rejflag);
void insertconstrainedpoints(tetgenio *addio);
void collectremovepoints(arraypool *remptlist);
void meshcoarsening();
void makefacetverticesmap();
int segsegadjacent(face *, face *);
int segfacetadjacent(face *checkseg, face *checksh);
int facetfacetadjacent(face *, face *);
int checkseg4encroach(point pa, point pb, point checkpt);
int checkseg4split(face *chkseg, point&, int&);
int splitsegment(face *splitseg, point encpt, REAL, point, point, int, int);
void repairencsegs(int chkencflag);
void enqueuesubface(memorypool*, face*);
int checkfac4encroach(point, point, point, point checkpt, REAL*, REAL*);
int checkfac4split(face *chkfac, point& encpt, int& qflag, REAL *ccent);
int splitsubface(face *splitfac, point, point, int qflag, REAL *ccent, int);
void repairencfacs(int chkencflag);
void enqueuetetrahedron(triface*);
int checktet4split(triface *chktet, int& qflag, REAL *ccent);
int splittetrahedron(triface* splittet,int qflag,REAL *ccent, int);
void repairbadtets(int chkencflag);
void delaunayrefinement();
long lawsonflip3d(flipconstraints *fc);
void recoverdelaunay();
int gettetrahedron(point, point, point, point, triface *);
long improvequalitybyflips();
int smoothpoint(point smtpt, arraypool*, int ccw, optparameters *opm);
long improvequalitybysmoothing(optparameters *opm);
int splitsliver(triface *, REAL, int);
long removeslivers(int);
void optimizemesh();
int checkmesh(int topoflag);
int checkshells();
int checksegments();
int checkdelaunay();
int checkregular(int);
int checkconforming(int);
void printfcomma(ULONG n);
void qualitystatistics();
void memorystatistics();
void statistics();
void jettisonnodes();
void highorder();
void numberedges();
void outnodes(tetgenio*);
void outmetrics(tetgenio*);
void outelements(tetgenio*);
void outfaces(tetgenio*);
void outhullfaces(tetgenio*);
void outsubfaces(tetgenio*);
void outedges(tetgenio*);
void outsubsegments(tetgenio*);
void outneighbors(tetgenio*);
void outvoronoi(tetgenio*);
void outsmesh(char*);
void outmesh2medit(char*);
void outmesh2vtk(char*);
tetgenmesh()
{
in = addin = NULL;
b = NULL;
bgm = NULL;
tetrahedrons = subfaces = subsegs = points = NULL;
badtetrahedrons = badsubfacs = badsubsegs = NULL;
tet2segpool = tet2subpool = NULL;
flippool = NULL;
dummypoint = NULL;
flipstack = NULL;
unflipqueue = NULL;
cavetetlist = cavebdrylist = caveoldtetlist = NULL;
cavetetshlist = cavetetseglist = cavetetvertlist = NULL;
caveencshlist = caveencseglist = NULL;
caveshlist = caveshbdlist = cavesegshlist = NULL;
subsegstack = subfacstack = subvertstack = NULL;
encseglist = encshlist = NULL;
idx2facetlist = NULL;
facetverticeslist = NULL;
segmentendpointslist = NULL;
highordertable = NULL;
numpointattrib = numelemattrib = 0;
sizeoftensor = 0;
pointmtrindex = 0;
pointparamindex = 0;
pointmarkindex = 0;
point2simindex = 0;
elemattribindex = 0;
volumeboundindex = 0;
shmarkindex = 0;
areaboundindex = 0;
checksubsegflag = 0;
checksubfaceflag = 0;
checkconstraints = 0;
nonconvex = 0;
autofliplinklevel = 1;
useinsertradius = 0;
samples = 0l;
randomseed = 1l;
minfaceang = minfacetdihed = PI;
tetprism_vol_sum = 0.0;
longest = 0.0;
xmax = xmin = ymax = ymin = zmax = zmin = 0.0;
insegments = 0l;
hullsize = 0l;
meshedges = meshhulledges = 0l;
steinerleft = -1;
dupverts = 0l;
unuverts = 0l;
nonregularcount = 0l;
st_segref_count = st_facref_count = st_volref_count = 0l;
fillregioncount = cavitycount = cavityexpcount = 0l;
flip14count = flip26count = flipn2ncount = 0l;
flip23count = flip32count = flip44count = flip41count = 0l;
flip22count = flip31count = 0l;
totalworkmemory = 0l;
}
void freememory()
{
if (bgm != NULL) {
delete bgm;
}
if (points != (memorypool *) NULL) {
delete points;
delete [] dummypoint;
}
if (tetrahedrons != (memorypool *) NULL) {
delete tetrahedrons;
}
if (subfaces != (memorypool *) NULL) {
delete subfaces;
delete subsegs;
}
if (tet2segpool != NULL) {
delete tet2segpool;
delete tet2subpool;
}
if (flippool != NULL) {
delete flippool;
delete unflipqueue;
}
if (cavetetlist != NULL) {
delete cavetetlist;
delete cavebdrylist;
delete caveoldtetlist;
delete cavetetvertlist;
}
if (caveshlist != NULL) {
delete caveshlist;
delete caveshbdlist;
delete cavesegshlist;
delete cavetetshlist;
delete cavetetseglist;
delete caveencshlist;
delete caveencseglist;
}
if (subsegstack != NULL) {
delete subsegstack;
delete subfacstack;
delete subvertstack;
}
if (idx2facetlist != NULL) {
delete [] idx2facetlist;
delete [] facetverticeslist;
}
if (segmentendpointslist != NULL) {
delete [] segmentendpointslist;
}
if (highordertable != NULL) {
delete [] highordertable;
}
}
~tetgenmesh()
{
freememory();
}
};
int tetrahedralize(tetgenbehavior *b, tetgenio *in, tetgenio *out,
tetgenio *addin = NULL, tetgenio *bgmin = NULL);
#ifdef TETLIBRARY
int tetrahedralize(char const *switches, tetgenio *in, tetgenio *out,
tetgenio *addin = NULL, tetgenio *bgmin = NULL,
char const *outfilename=NULL); #endif
inline void terminatetetgen(tetgenmesh *m, int x)
{
#ifdef TETLIBRARY
throw x;
#else
switch (x) {
case 1: printf("Error: Out of memory.\n");
break;
case 2: printf("Please report this bug to Hang.Si@wias-berlin.de. Include\n");
printf(" the message above, your input data set, and the exact\n");
printf(" command line you used to run this program, thank you.\n");
break;
case 3:
printf("A self-intersection was detected. Program stopped.\n");
printf("Hint: use -d option to detect all self-intersections.\n");
break;
case 4:
printf("A very small input feature size was detected. Program stopped.\n");
printf("Hint: use -T option to set a smaller tolerance.\n");
break;
case 5:
printf("Two very close input facets were detected. Program stopped.\n");
printf("Hint: use -Y option to avoid adding Steiner points in boundary.\n");
break;
case 10:
printf("An input error was detected. Program stopped.\n");
break;
} exit(x);
#endif }
inline tetgenmesh::tetrahedron tetgenmesh::encode(triface& t) {
return (tetrahedron) ((uintptr_t) (t).tet | (uintptr_t) (t).ver);
}
inline tetgenmesh::tetrahedron tetgenmesh::encode2(tetrahedron* ptr, int ver) {
return (tetrahedron) ((uintptr_t) (ptr) | (uintptr_t) (ver));
}
inline void tetgenmesh::decode(tetrahedron ptr, triface& t) {
(t).ver = (int) ((uintptr_t) (ptr) & (uintptr_t) 15);
(t).tet = (tetrahedron *) ((uintptr_t) (ptr) ^ (uintptr_t) (t).ver);
}
inline void tetgenmesh::bond(triface& t1, triface& t2) {
t1.tet[t1.ver & 3] = encode2(t2.tet, bondtbl[t1.ver][t2.ver]);
t2.tet[t2.ver & 3] = encode2(t1.tet, bondtbl[t2.ver][t1.ver]);
}
inline void tetgenmesh::dissolve(triface& t) {
t.tet[t.ver & 3] = NULL;
}
inline void tetgenmesh::enext(triface& t1, triface& t2) {
t2.tet = t1.tet;
t2.ver = enexttbl[t1.ver];
}
inline void tetgenmesh::enextself(triface& t) {
t.ver = enexttbl[t.ver];
}
inline void tetgenmesh::eprev(triface& t1, triface& t2) {
t2.tet = t1.tet;
t2.ver = eprevtbl[t1.ver];
}
inline void tetgenmesh::eprevself(triface& t) {
t.ver = eprevtbl[t.ver];
}
inline void tetgenmesh::esym(triface& t1, triface& t2) {
(t2).tet = (t1).tet;
(t2).ver = esymtbl[(t1).ver];
}
inline void tetgenmesh::esymself(triface& t) {
(t).ver = esymtbl[(t).ver];
}
inline void tetgenmesh::enextesym(triface& t1, triface& t2) {
t2.tet = t1.tet;
t2.ver = enextesymtbl[t1.ver];
}
inline void tetgenmesh::enextesymself(triface& t) {
t.ver = enextesymtbl[t.ver];
}
inline void tetgenmesh::eprevesym(triface& t1, triface& t2) {
t2.tet = t1.tet;
t2.ver = eprevesymtbl[t1.ver];
}
inline void tetgenmesh::eprevesymself(triface& t) {
t.ver = eprevesymtbl[t.ver];
}
inline void tetgenmesh::eorgoppo(triface& t1, triface& t2) {
t2.tet = t1.tet;
t2.ver = eorgoppotbl[t1.ver];
}
inline void tetgenmesh::eorgoppoself(triface& t) {
t.ver = eorgoppotbl[t.ver];
}
inline void tetgenmesh::edestoppo(triface& t1, triface& t2) {
t2.tet = t1.tet;
t2.ver = edestoppotbl[t1.ver];
}
inline void tetgenmesh::edestoppoself(triface& t) {
t.ver = edestoppotbl[t.ver];
}
inline void tetgenmesh::fsym(triface& t1, triface& t2) {
decode((t1).tet[(t1).ver & 3], t2);
t2.ver = fsymtbl[t1.ver][t2.ver];
}
#define fsymself(t) \
t1ver = (t).ver; \
decode((t).tet[(t).ver & 3], (t));\
(t).ver = fsymtbl[t1ver][(t).ver]
inline void tetgenmesh::fnext(triface& t1, triface& t2) {
decode(t1.tet[facepivot1[t1.ver]], t2);
t2.ver = facepivot2[t1.ver][t2.ver];
}
#define fnextself(t) \
t1ver = (t).ver; \
decode((t).tet[facepivot1[(t).ver]], (t)); \
(t).ver = facepivot2[t1ver][(t).ver]
inline tetgenmesh::point tetgenmesh::org(triface& t) {
return (point) (t).tet[orgpivot[(t).ver]];
}
inline tetgenmesh::point tetgenmesh:: dest(triface& t) {
return (point) (t).tet[destpivot[(t).ver]];
}
inline tetgenmesh::point tetgenmesh:: apex(triface& t) {
return (point) (t).tet[apexpivot[(t).ver]];
}
inline tetgenmesh::point tetgenmesh:: oppo(triface& t) {
return (point) (t).tet[oppopivot[(t).ver]];
}
inline void tetgenmesh:: setorg(triface& t, point p) {
(t).tet[orgpivot[(t).ver]] = (tetrahedron) (p);
}
inline void tetgenmesh:: setdest(triface& t, point p) {
(t).tet[destpivot[(t).ver]] = (tetrahedron) (p);
}
inline void tetgenmesh:: setapex(triface& t, point p) {
(t).tet[apexpivot[(t).ver]] = (tetrahedron) (p);
}
inline void tetgenmesh:: setoppo(triface& t, point p) {
(t).tet[oppopivot[(t).ver]] = (tetrahedron) (p);
}
#define setvertices(t, torg, tdest, tapex, toppo) \
(t).tet[orgpivot[(t).ver]] = (tetrahedron) (torg);\
(t).tet[destpivot[(t).ver]] = (tetrahedron) (tdest); \
(t).tet[apexpivot[(t).ver]] = (tetrahedron) (tapex); \
(t).tet[oppopivot[(t).ver]] = (tetrahedron) (toppo)
inline REAL tetgenmesh::elemattribute(tetrahedron* ptr, int attnum) {
return ((REAL *) (ptr))[elemattribindex + attnum];
}
inline void tetgenmesh::setelemattribute(tetrahedron* ptr, int attnum,
REAL value) {
((REAL *) (ptr))[elemattribindex + attnum] = value;
}
inline REAL tetgenmesh::volumebound(tetrahedron* ptr) {
return ((REAL *) (ptr))[volumeboundindex];
}
inline void tetgenmesh::setvolumebound(tetrahedron* ptr, REAL value) {
((REAL *) (ptr))[volumeboundindex] = value;
}
inline int tetgenmesh::elemindex(tetrahedron* ptr) {
int *iptr = (int *) &(ptr[10]);
return iptr[0];
}
inline void tetgenmesh::setelemindex(tetrahedron* ptr, int value) {
int *iptr = (int *) &(ptr[10]);
iptr[0] = value;
}
inline int tetgenmesh::elemmarker(tetrahedron* ptr) {
return ((int *) (ptr))[elemmarkerindex];
}
inline void tetgenmesh::setelemmarker(tetrahedron* ptr, int value) {
((int *) (ptr))[elemmarkerindex] = value;
}
inline void tetgenmesh::infect(triface& t) {
((int *) (t.tet))[elemmarkerindex] |= 1;
}
inline void tetgenmesh::uninfect(triface& t) {
((int *) (t.tet))[elemmarkerindex] &= ~1;
}
inline bool tetgenmesh::infected(triface& t) {
return (((int *) (t.tet))[elemmarkerindex] & 1) != 0;
}
inline void tetgenmesh::marktest(triface& t) {
((int *) (t.tet))[elemmarkerindex] |= 2;
}
inline void tetgenmesh::unmarktest(triface& t) {
((int *) (t.tet))[elemmarkerindex] &= ~2;
}
inline bool tetgenmesh::marktested(triface& t) {
return (((int *) (t.tet))[elemmarkerindex] & 2) != 0;
}
inline void tetgenmesh::markface(triface& t) {
((int *) (t.tet))[elemmarkerindex] |= (4 << (t.ver & 3));
}
inline void tetgenmesh::unmarkface(triface& t) {
((int *) (t.tet))[elemmarkerindex] &= ~(4 << (t.ver & 3));
}
inline bool tetgenmesh::facemarked(triface& t) {
return (((int *) (t.tet))[elemmarkerindex] & (4 << (t.ver & 3))) != 0;
}
inline void tetgenmesh::markedge(triface& t) {
((int *) (t.tet))[elemmarkerindex] |= (int) (64 << ver2edge[(t).ver]);
}
inline void tetgenmesh::unmarkedge(triface& t) {
((int *) (t.tet))[elemmarkerindex] &= ~(int) (64 << ver2edge[(t).ver]);
}
inline bool tetgenmesh::edgemarked(triface& t) {
return (((int *) (t.tet))[elemmarkerindex] &
(int) (64 << ver2edge[(t).ver])) != 0;
}
inline void tetgenmesh::marktest2(triface& t) {
((int *) (t.tet))[elemmarkerindex] |= (int) (4096);
}
inline void tetgenmesh::unmarktest2(triface& t) {
((int *) (t.tet))[elemmarkerindex] &= ~(int) (4096);
}
inline bool tetgenmesh::marktest2ed(triface& t) {
return (((int *) (t.tet))[elemmarkerindex] & (int) (4096)) != 0;
}
inline int tetgenmesh::elemcounter(triface& t) {
return (((int *) (t.tet))[elemmarkerindex]) >> 16;
}
inline void tetgenmesh::setelemcounter(triface& t, int value) {
int c = ((int *) (t.tet))[elemmarkerindex];
c &= 65535; c |= (value << 16);
((int *) (t.tet))[elemmarkerindex] = c;
}
inline void tetgenmesh::increaseelemcounter(triface& t) {
int c = elemcounter(t);
setelemcounter(t, c + 1);
}
inline void tetgenmesh::decreaseelemcounter(triface& t) {
int c = elemcounter(t);
setelemcounter(t, c - 1);
}
inline bool tetgenmesh::ishulltet(triface& t) {
return (point) (t).tet[7] == dummypoint;
}
inline bool tetgenmesh::isdeadtet(triface& t) {
return ((t.tet == NULL) || (t.tet[4] == NULL));
}
inline void tetgenmesh::sdecode(shellface sptr, face& s) {
s.shver = (int) ((uintptr_t) (sptr) & (uintptr_t) 7);
s.sh = (shellface *) ((uintptr_t) (sptr) ^ (uintptr_t) (s.shver));
}
inline tetgenmesh::shellface tetgenmesh::sencode(face& s) {
return (shellface) ((uintptr_t) s.sh | (uintptr_t) s.shver);
}
inline tetgenmesh::shellface tetgenmesh::sencode2(shellface *sh, int shver) {
return (shellface) ((uintptr_t) sh | (uintptr_t) shver);
}
inline void tetgenmesh::sbond(face& s1, face& s2)
{
s1.sh[s1.shver >> 1] = sencode(s2);
s2.sh[s2.shver >> 1] = sencode(s1);
}
inline void tetgenmesh::sbond1(face& s1, face& s2)
{
s1.sh[s1.shver >> 1] = sencode(s2);
}
inline void tetgenmesh::sdissolve(face& s)
{
s.sh[s.shver >> 1] = NULL;
}
inline void tetgenmesh::spivot(face& s1, face& s2)
{
shellface sptr = s1.sh[s1.shver >> 1];
sdecode(sptr, s2);
}
inline void tetgenmesh::spivotself(face& s)
{
shellface sptr = s.sh[s.shver >> 1];
sdecode(sptr, s);
}
inline tetgenmesh::point tetgenmesh::sorg(face& s)
{
return (point) s.sh[sorgpivot[s.shver]];
}
inline tetgenmesh::point tetgenmesh::sdest(face& s)
{
return (point) s.sh[sdestpivot[s.shver]];
}
inline tetgenmesh::point tetgenmesh::sapex(face& s)
{
return (point) s.sh[sapexpivot[s.shver]];
}
inline void tetgenmesh::setsorg(face& s, point pointptr)
{
s.sh[sorgpivot[s.shver]] = (shellface) pointptr;
}
inline void tetgenmesh::setsdest(face& s, point pointptr)
{
s.sh[sdestpivot[s.shver]] = (shellface) pointptr;
}
inline void tetgenmesh::setsapex(face& s, point pointptr)
{
s.sh[sapexpivot[s.shver]] = (shellface) pointptr;
}
#define setshvertices(s, pa, pb, pc)\
setsorg(s, pa);\
setsdest(s, pb);\
setsapex(s, pc)
inline void tetgenmesh::sesym(face& s1, face& s2)
{
s2.sh = s1.sh;
s2.shver = (s1.shver ^ 1); }
inline void tetgenmesh::sesymself(face& s)
{
s.shver ^= 1;
}
inline void tetgenmesh::senext(face& s1, face& s2)
{
s2.sh = s1.sh;
s2.shver = snextpivot[s1.shver];
}
inline void tetgenmesh::senextself(face& s)
{
s.shver = snextpivot[s.shver];
}
inline void tetgenmesh::senext2(face& s1, face& s2)
{
s2.sh = s1.sh;
s2.shver = snextpivot[snextpivot[s1.shver]];
}
inline void tetgenmesh::senext2self(face& s)
{
s.shver = snextpivot[snextpivot[s.shver]];
}
inline REAL tetgenmesh::areabound(face& s)
{
return ((REAL *) (s.sh))[areaboundindex];
}
inline void tetgenmesh::setareabound(face& s, REAL value)
{
((REAL *) (s.sh))[areaboundindex] = value;
}
inline int tetgenmesh::shellmark(face& s)
{
return ((int *) (s.sh))[shmarkindex];
}
inline void tetgenmesh::setshellmark(face& s, int value)
{
((int *) (s.sh))[shmarkindex] = value;
}
inline void tetgenmesh::sinfect(face& s)
{
((int *) ((s).sh))[shmarkindex+1] =
(((int *) ((s).sh))[shmarkindex+1] | (int) 1);
}
inline void tetgenmesh::suninfect(face& s)
{
((int *) ((s).sh))[shmarkindex+1] =
(((int *) ((s).sh))[shmarkindex+1] & ~(int) 1);
}
inline bool tetgenmesh::sinfected(face& s)
{
return (((int *) ((s).sh))[shmarkindex+1] & (int) 1) != 0;
}
inline void tetgenmesh::smarktest(face& s)
{
((int *) ((s).sh))[shmarkindex+1] =
(((int *)((s).sh))[shmarkindex+1] | (int) 2);
}
inline void tetgenmesh::sunmarktest(face& s)
{
((int *) ((s).sh))[shmarkindex+1] =
(((int *)((s).sh))[shmarkindex+1] & ~(int)2);
}
inline bool tetgenmesh::smarktested(face& s)
{
return ((((int *) ((s).sh))[shmarkindex+1] & (int) 2) != 0);
}
inline void tetgenmesh::smarktest2(face& s)
{
((int *) ((s).sh))[shmarkindex+1] =
(((int *)((s).sh))[shmarkindex+1] | (int) 4);
}
inline void tetgenmesh::sunmarktest2(face& s)
{
((int *) ((s).sh))[shmarkindex+1] =
(((int *)((s).sh))[shmarkindex+1] & ~(int)4);
}
inline bool tetgenmesh::smarktest2ed(face& s)
{
return ((((int *) ((s).sh))[shmarkindex+1] & (int) 4) != 0);
}
inline void tetgenmesh::smarktest3(face& s)
{
((int *) ((s).sh))[shmarkindex+1] =
(((int *)((s).sh))[shmarkindex+1] | (int) 8);
}
inline void tetgenmesh::sunmarktest3(face& s)
{
((int *) ((s).sh))[shmarkindex+1] =
(((int *)((s).sh))[shmarkindex+1] & ~(int)8);
}
inline bool tetgenmesh::smarktest3ed(face& s)
{
return ((((int *) ((s).sh))[shmarkindex+1] & (int) 8) != 0);
}
inline void tetgenmesh::setfacetindex(face& s, int value)
{
((int *) (s.sh))[shmarkindex + 2] = value;
}
inline int tetgenmesh::getfacetindex(face& s)
{
return ((int *) (s.sh))[shmarkindex + 2];
}
inline void tetgenmesh::tsbond(triface& t, face& s)
{
if ((t).tet[9] == NULL) {
(t).tet[9] = (tetrahedron) tet2subpool->alloc();
for (int i = 0; i < 4; i++) {
((shellface *) (t).tet[9])[i] = NULL;
}
}
((shellface *) (t).tet[9])[(t).ver & 3] =
sencode2((s).sh, tsbondtbl[t.ver][s.shver]);
s.sh[9 + ((s).shver & 1)] =
(shellface) encode2((t).tet, stbondtbl[t.ver][s.shver]);
}
inline void tetgenmesh::tspivot(triface& t, face& s)
{
if ((t).tet[9] == NULL) {
(s).sh = NULL;
return;
}
sdecode(((shellface *) (t).tet[9])[(t).ver & 3], (s));
(s).shver = tspivottbl[t.ver][s.shver];
}
#define issubface(t) \
((t).tet[9] && ((t).tet[9])[(t).ver & 3])
inline void tetgenmesh::stpivot(face& s, triface& t)
{
decode((tetrahedron) s.sh[9 + (s.shver & 1)], t);
if ((t).tet == NULL) {
return;
}
(t).ver = stpivottbl[t.ver][s.shver];
}
#define isshtet(s) \
((s).sh[9 + ((s).shver & 1)])
inline void tetgenmesh::tsdissolve(triface& t)
{
if ((t).tet[9] != NULL) {
((shellface *) (t).tet[9])[(t).ver & 3] = NULL;
}
}
inline void tetgenmesh::stdissolve(face& s)
{
(s).sh[9] = NULL;
(s).sh[10] = NULL;
}
inline void tetgenmesh::ssbond(face& s, face& edge)
{
s.sh[6 + (s.shver >> 1)] = sencode(edge);
edge.sh[0] = sencode(s);
}
inline void tetgenmesh::ssbond1(face& s, face& edge)
{
s.sh[6 + (s.shver >> 1)] = sencode(edge);
}
inline void tetgenmesh::ssdissolve(face& s)
{
s.sh[6 + (s.shver >> 1)] = NULL;
}
inline void tetgenmesh::sspivot(face& s, face& edge)
{
sdecode((shellface) s.sh[6 + (s.shver >> 1)], edge);
}
#define isshsubseg(s) \
((s).sh[6 + ((s).shver >> 1)])
inline void tetgenmesh::tssbond1(triface& t, face& s)
{
if ((t).tet[8] == NULL) {
(t).tet[8] = (tetrahedron) tet2segpool->alloc();
for (int i = 0; i < 6; i++) {
((shellface *) (t).tet[8])[i] = NULL;
}
}
((shellface *) (t).tet[8])[ver2edge[(t).ver]] = sencode((s));
}
inline void tetgenmesh::sstbond1(face& s, triface& t)
{
((tetrahedron *) (s).sh)[9] = encode(t);
}
inline void tetgenmesh::tssdissolve1(triface& t)
{
if ((t).tet[8] != NULL) {
((shellface *) (t).tet[8])[ver2edge[(t).ver]] = NULL;
}
}
inline void tetgenmesh::sstdissolve1(face& s)
{
((tetrahedron *) (s).sh)[9] = NULL;
}
inline void tetgenmesh::tsspivot1(triface& t, face& s)
{
if ((t).tet[8] != NULL) {
sdecode(((shellface *) (t).tet[8])[ver2edge[(t).ver]], s);
} else {
(s).sh = NULL;
}
}
#define issubseg(t) \
((t).tet[8] && ((t).tet[8])[ver2edge[(t).ver]])
inline void tetgenmesh::sstpivot1(face& s, triface& t)
{
decode((tetrahedron) s.sh[9], t);
}
inline int tetgenmesh::pointmark(point pt) {
return ((int *) (pt))[pointmarkindex];
}
inline void tetgenmesh::setpointmark(point pt, int value) {
((int *) (pt))[pointmarkindex] = value;
}
inline enum tetgenmesh::verttype tetgenmesh::pointtype(point pt) {
return (enum verttype) (((int *) (pt))[pointmarkindex + 1] >> (int) 8);
}
inline void tetgenmesh::setpointtype(point pt, enum verttype value) {
((int *) (pt))[pointmarkindex + 1] =
((int) value << 8) + (((int *) (pt))[pointmarkindex + 1] & (int) 255);
}
inline int tetgenmesh::pointgeomtag(point pt) {
return ((int *) (pt))[pointmarkindex + 2];
}
inline void tetgenmesh::setpointgeomtag(point pt, int value) {
((int *) (pt))[pointmarkindex + 2] = value;
}
inline REAL tetgenmesh::pointgeomuv(point pt, int i) {
return pt[pointparamindex + i];
}
inline void tetgenmesh::setpointgeomuv(point pt, int i, REAL value) {
pt[pointparamindex + i] = value;
}
inline void tetgenmesh::pinfect(point pt) {
((int *) (pt))[pointmarkindex + 1] |= (int) 1;
}
inline void tetgenmesh::puninfect(point pt) {
((int *) (pt))[pointmarkindex + 1] &= ~(int) 1;
}
inline bool tetgenmesh::pinfected(point pt) {
return (((int *) (pt))[pointmarkindex + 1] & (int) 1) != 0;
}
inline void tetgenmesh::pmarktest(point pt) {
((int *) (pt))[pointmarkindex + 1] |= (int) 2;
}
inline void tetgenmesh::punmarktest(point pt) {
((int *) (pt))[pointmarkindex + 1] &= ~(int) 2;
}
inline bool tetgenmesh::pmarktested(point pt) {
return (((int *) (pt))[pointmarkindex + 1] & (int) 2) != 0;
}
inline void tetgenmesh::pmarktest2(point pt) {
((int *) (pt))[pointmarkindex + 1] |= (int) 4;
}
inline void tetgenmesh::punmarktest2(point pt) {
((int *) (pt))[pointmarkindex + 1] &= ~(int) 4;
}
inline bool tetgenmesh::pmarktest2ed(point pt) {
return (((int *) (pt))[pointmarkindex + 1] & (int) 4) != 0;
}
inline void tetgenmesh::pmarktest3(point pt) {
((int *) (pt))[pointmarkindex + 1] |= (int) 8;
}
inline void tetgenmesh::punmarktest3(point pt) {
((int *) (pt))[pointmarkindex + 1] &= ~(int) 8;
}
inline bool tetgenmesh::pmarktest3ed(point pt) {
return (((int *) (pt))[pointmarkindex + 1] & (int) 8) != 0;
}
inline tetgenmesh::tetrahedron tetgenmesh::point2tet(point pt) {
return ((tetrahedron *) (pt))[point2simindex];
}
inline void tetgenmesh::setpoint2tet(point pt, tetrahedron value) {
((tetrahedron *) (pt))[point2simindex] = value;
}
inline tetgenmesh::point tetgenmesh::point2ppt(point pt) {
return (point) ((tetrahedron *) (pt))[point2simindex + 1];
}
inline void tetgenmesh::setpoint2ppt(point pt, point value) {
((tetrahedron *) (pt))[point2simindex + 1] = (tetrahedron) value;
}
inline tetgenmesh::shellface tetgenmesh::point2sh(point pt) {
return (shellface) ((tetrahedron *) (pt))[point2simindex + 2];
}
inline void tetgenmesh::setpoint2sh(point pt, shellface value) {
((tetrahedron *) (pt))[point2simindex + 2] = (tetrahedron) value;
}
inline tetgenmesh::tetrahedron tetgenmesh::point2bgmtet(point pt) {
return ((tetrahedron *) (pt))[point2simindex + 3];
}
inline void tetgenmesh::setpoint2bgmtet(point pt, tetrahedron value) {
((tetrahedron *) (pt))[point2simindex + 3] = value;
}
inline void tetgenmesh::setpointinsradius(point pt, REAL value)
{
pt[pointmtrindex + sizeoftensor - 1] = value;
}
inline REAL tetgenmesh::getpointinsradius(point pt)
{
return pt[pointmtrindex + sizeoftensor - 1];
}
inline void tetgenmesh::point2tetorg(point pa, triface& searchtet)
{
decode(point2tet(pa), searchtet);
if ((point) searchtet.tet[4] == pa) {
searchtet.ver = 11;
} else if ((point) searchtet.tet[5] == pa) {
searchtet.ver = 3;
} else if ((point) searchtet.tet[6] == pa) {
searchtet.ver = 7;
} else {
assert((point) searchtet.tet[7] == pa); searchtet.ver = 0;
}
}
inline void tetgenmesh::point2shorg(point pa, face& searchsh)
{
sdecode(point2sh(pa), searchsh);
if ((point) searchsh.sh[3] == pa) {
searchsh.shver = 0;
} else if ((point) searchsh.sh[4] == pa) {
searchsh.shver = (searchsh.sh[5] != NULL ? 2 : 1);
} else {
assert((point) searchsh.sh[5] == pa); searchsh.shver = 4;
}
}
inline tetgenmesh::point tetgenmesh::farsorg(face& s)
{
face travesh, neighsh;
travesh = s;
while (1) {
senext2(travesh, neighsh);
spivotself(neighsh);
if (neighsh.sh == NULL) break;
if (sorg(neighsh) != sorg(travesh)) sesymself(neighsh);
senext2(neighsh, travesh);
}
return sorg(travesh);
}
inline tetgenmesh::point tetgenmesh::farsdest(face& s)
{
face travesh, neighsh;
travesh = s;
while (1) {
senext(travesh, neighsh);
spivotself(neighsh);
if (neighsh.sh == NULL) break;
if (sdest(neighsh) != sdest(travesh)) sesymself(neighsh);
senext(neighsh, travesh);
}
return sdest(travesh);
}
inline REAL tetgenmesh::dot(REAL* v1, REAL* v2)
{
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}
inline void tetgenmesh::cross(REAL* v1, REAL* v2, REAL* n)
{
n[0] = v1[1] * v2[2] - v2[1] * v1[2];
n[1] = -(v1[0] * v2[2] - v2[0] * v1[2]);
n[2] = v1[0] * v2[1] - v2[0] * v1[1];
}
inline REAL tetgenmesh::distance(REAL* p1, REAL* p2)
{
return sqrt((p2[0] - p1[0]) * (p2[0] - p1[0]) +
(p2[1] - p1[1]) * (p2[1] - p1[1]) +
(p2[2] - p1[2]) * (p2[2] - p1[2]));
}
inline REAL tetgenmesh::norm2(REAL x, REAL y, REAL z)
{
return (x) * (x) + (y) * (y) + (z) * (z);
}
#undef REAL
#endif