implemented isSolid() test; simplified cork.h; trimmed number of headers

This commit closes issue #2 and issue #8
This commit is contained in:
Gilbert Bernstein
2013-02-13 16:14:32 -08:00
parent b5add9c565
commit f7485c2141
7 changed files with 261 additions and 307 deletions
+10 -10
View File
@@ -12,12 +12,12 @@ SUBDIRECTORIES := util file_formats math isct mesh rawmesh accel
# make sure the subdirectories are mirrored in
# the obj/ debug/ and depend/ directories
# (HACK: use this dummy variable to get access to shell commands)
SHELL_HACK := $(shell mkdir -p bin lib)
SHELL_HACK := $(shell mkdir -p bin lib include)
SHELL_HACK := $(shell mkdir -p $(addprefix obj/,$(SUBDIRECTORIES)))
SHELL_HACK := $(shell mkdir -p $(addprefix debug/,$(SUBDIRECTORIES)))
SHELL_HACK := $(shell mkdir -p $(addprefix depend/,$(SUBDIRECTORIES)))
# also make a directory to expose headers in
SHELL_HACK := $(shell mkdir -p $(addprefix include/,$(SUBDIRECTORIES)))
#SHELL_HACK := $(shell mkdir -p $(addprefix include/,$(SUBDIRECTORIES)))
# +----------+
# | Platform |
@@ -121,14 +121,14 @@ MESH_HEADERS := mesh.h mesh.decl.h \
ACCEL_HEADERS := aabvh.h
FILE_HEADERS := files.h
HEADERS := \
cork.h \
$(addprefix math/,$(MATH_HEADERS))\
$(addprefix util/,$(UTIL_HEADERS))\
$(addprefix isct/,$(ISCT_HEADERS))\
$(addprefix mesh/,$(MESH_HEADERS))\
$(addprefix rawmesh/,$(RAWMESH_HEADERS))\
$(addprefix accel/,$(ACCEL_HEADERS))\
$(addprefix file_formats/,$(FILE_HEADERS))
cork.h
# $(addprefix math/,$(MATH_HEADERS))\
# $(addprefix util/,$(UTIL_HEADERS))\
# $(addprefix isct/,$(ISCT_HEADERS))\
# $(addprefix mesh/,$(MESH_HEADERS))\
# $(addprefix rawmesh/,$(RAWMESH_HEADERS))\
# $(addprefix accel/,$(ACCEL_HEADERS))\
# $(addprefix file_formats/,$(FILE_HEADERS))
HEADER_COPIES := $(addprefix include/,$(HEADERS))
# +-----------------------------+
+94 -155
View File
@@ -27,6 +27,16 @@
#include "mesh.h"
void freeCorkTriMesh(CorkTriMesh *mesh)
{
delete[] mesh->triangles;
delete[] mesh->vertices;
mesh->n_triangles = 0;
mesh->n_vertices = 0;
}
struct CorkTriangle;
struct CorkVertex :
@@ -97,223 +107,152 @@ struct CorkTriangle :
using RawCorkMesh = RawMesh<CorkVertex, CorkTriangle>;
using CorkMesh = Mesh<CorkVertex, CorkTriangle>;
void cMesh2CorkMesh(
uint n_triangles_in, uint *triangles_in,
uint n_vertices_in, float *vertices_in,
void corkTriMesh2CorkMesh(
CorkTriMesh in,
CorkMesh *mesh_out
) {
RawCorkMesh raw;
raw.vertices.resize(n_vertices_in);
raw.triangles.resize(n_triangles_in);
if(n_vertices_in == 0 || n_triangles_in == 0) {
raw.vertices.resize(in.n_vertices);
raw.triangles.resize(in.n_triangles);
if(in.n_vertices == 0 || in.n_triangles == 0) {
ERROR("empty mesh input to Cork routine.");
*mesh_out = CorkMesh(raw);
return;
}
uint max_ref_idx = 0;
for(uint i=0; i<n_triangles_in; i++) {
raw.triangles[i].a = triangles_in[3*i+0];
raw.triangles[i].b = triangles_in[3*i+1];
raw.triangles[i].c = triangles_in[3*i+2];
for(uint i=0; i<in.n_triangles; i++) {
raw.triangles[i].a = in.triangles[3*i+0];
raw.triangles[i].b = in.triangles[3*i+1];
raw.triangles[i].c = in.triangles[3*i+2];
max_ref_idx = std::max(
std::max(max_ref_idx,
triangles_in[3*i+0]),
std::max(triangles_in[3*i+1],
triangles_in[3*i+2])
in.triangles[3*i+0]),
std::max(in.triangles[3*i+1],
in.triangles[3*i+2])
);
}
if(max_ref_idx > n_vertices_in) {
ERROR("mesh input to Cork routine has an out of range vertex index.");
if(max_ref_idx > in.n_vertices) {
ERROR("mesh input to Cork routine has an out of range reference "
"to a vertex.");
raw.vertices.clear();
raw.triangles.clear();
*mesh_out = CorkMesh(raw);
return;
}
for(uint i=0; i<n_vertices_in; i++) {
raw.vertices[i].pos.x = vertices_in[3*i+0];
raw.vertices[i].pos.y = vertices_in[3*i+1];
raw.vertices[i].pos.z = vertices_in[3*i+2];
for(uint i=0; i<in.n_vertices; i++) {
raw.vertices[i].pos.x = in.vertices[3*i+0];
raw.vertices[i].pos.y = in.vertices[3*i+1];
raw.vertices[i].pos.z = in.vertices[3*i+2];
}
*mesh_out = CorkMesh(raw);
}
void corkMesh2CMesh(
void corkMesh2CorkTriMesh(
CorkMesh *mesh_in,
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
CorkTriMesh *out
) {
RawCorkMesh raw = mesh_in->raw();
*n_triangles_out = raw.triangles.size();
*n_vertices_out = raw.vertices.size();
out->n_triangles = raw.triangles.size();
out->n_vertices = raw.vertices.size();
*triangles_out = new uint[(*n_triangles_out) * 3];
*vertices_out = new float[(*n_vertices_out) * 3];
out->triangles = new uint[(out->n_triangles) * 3];
out->vertices = new float[(out->n_vertices) * 3];
for(uint i=0; i<*n_triangles_out; i++) {
(*triangles_out)[3*i+0] = raw.triangles[i].a;
(*triangles_out)[3*i+1] = raw.triangles[i].b;
(*triangles_out)[3*i+2] = raw.triangles[i].c;
for(uint i=0; i<out->n_triangles; i++) {
(out->triangles)[3*i+0] = raw.triangles[i].a;
(out->triangles)[3*i+1] = raw.triangles[i].b;
(out->triangles)[3*i+2] = raw.triangles[i].c;
}
for(uint i=0; i<*n_vertices_out; i++) {
(*vertices_out)[3*i+0] = raw.vertices[i].pos.x;
(*vertices_out)[3*i+1] = raw.vertices[i].pos.y;
(*vertices_out)[3*i+2] = raw.vertices[i].pos.z;
for(uint i=0; i<out->n_vertices; i++) {
(out->vertices)[3*i+0] = raw.vertices[i].pos.x;
(out->vertices)[3*i+1] = raw.vertices[i].pos.y;
(out->vertices)[3*i+2] = raw.vertices[i].pos.z;
}
}
bool isSolid(CorkTriMesh cmesh)
{
CorkMesh mesh;
corkTriMesh2CorkMesh(cmesh, &mesh);
bool solid = true;
if(mesh.isSelfIntersecting()) {
ERROR("isSolid() was given a self-intersecting mesh");
solid = false;
}
if(!mesh.isClosed()) {
ERROR("isSolid() was given a non-closed mesh");
solid = false;
}
return solid;
}
void computeUnion(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out
) {
// convert input
CorkMesh in0, in1;
cMesh2CorkMesh(
n_triangles_in0, triangles_in0,
n_vertices_in0, vertices_in0,
&in0);
cMesh2CorkMesh(
n_triangles_in1, triangles_in1,
n_vertices_in1, vertices_in1,
&in1);
CorkMesh cmIn0, cmIn1;
corkTriMesh2CorkMesh(in0, &cmIn0);
corkTriMesh2CorkMesh(in1, &cmIn1);
in0.boolUnion(in1);
cmIn0.boolUnion(cmIn1);
// convert output
corkMesh2CMesh(&in0,
n_triangles_out, triangles_out,
n_vertices_out, vertices_out);
corkMesh2CorkTriMesh(&cmIn0, out);
}
void computeDifference(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out
) {
// convert input
CorkMesh in0, in1;
cMesh2CorkMesh(
n_triangles_in0, triangles_in0,
n_vertices_in0, vertices_in0,
&in0);
cMesh2CorkMesh(
n_triangles_in1, triangles_in1,
n_vertices_in1, vertices_in1,
&in1);
CorkMesh cmIn0, cmIn1;
corkTriMesh2CorkMesh(in0, &cmIn0);
corkTriMesh2CorkMesh(in1, &cmIn1);
in0.boolDiff(in1);
cmIn0.boolDiff(cmIn1);
// convert output
corkMesh2CMesh(&in0,
n_triangles_out, triangles_out,
n_vertices_out, vertices_out);
corkMesh2CorkTriMesh(&cmIn0, out);
}
void computeIntersection(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out
) {
// convert input
CorkMesh in0, in1;
cMesh2CorkMesh(
n_triangles_in0, triangles_in0,
n_vertices_in0, vertices_in0,
&in0);
cMesh2CorkMesh(
n_triangles_in1, triangles_in1,
n_vertices_in1, vertices_in1,
&in1);
CorkMesh cmIn0, cmIn1;
corkTriMesh2CorkMesh(in0, &cmIn0);
corkTriMesh2CorkMesh(in1, &cmIn1);
in0.boolIsct(in1);
cmIn0.boolIsct(cmIn1);
// convert output
corkMesh2CMesh(&in0,
n_triangles_out, triangles_out,
n_vertices_out, vertices_out);
corkMesh2CorkTriMesh(&cmIn0, out);
}
void computeSymmetricDifference(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out
) {
// convert input
CorkMesh in0, in1;
cMesh2CorkMesh(
n_triangles_in0, triangles_in0,
n_vertices_in0, vertices_in0,
&in0);
cMesh2CorkMesh(
n_triangles_in1, triangles_in1,
n_vertices_in1, vertices_in1,
&in1);
CorkMesh cmIn0, cmIn1;
corkTriMesh2CorkMesh(in0, &cmIn0);
corkTriMesh2CorkMesh(in1, &cmIn1);
in0.boolXor(in1);
cmIn0.boolXor(cmIn1);
// convert output
corkMesh2CMesh(&in0,
n_triangles_out, triangles_out,
n_vertices_out, vertices_out);
corkMesh2CorkTriMesh(&cmIn0, out);
}
void resolveIntersections(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out
) {
// convert input
CorkMesh in0, in1;
cMesh2CorkMesh(
n_triangles_in0, triangles_in0,
n_vertices_in0, vertices_in0,
&in0);
cMesh2CorkMesh(
n_triangles_in1, triangles_in1,
n_vertices_in1, vertices_in1,
&in1);
CorkMesh cmIn0, cmIn1;
corkTriMesh2CorkMesh(in0, &cmIn0);
corkTriMesh2CorkMesh(in1, &cmIn1);
in0.disjointUnion(in1);
in0.resolveIntersections();
cmIn0.disjointUnion(cmIn1);
cmIn0.resolveIntersections();
// convert output
corkMesh2CMesh(&in0,
n_triangles_out, triangles_out,
n_vertices_out, vertices_out);
corkMesh2CorkTriMesh(&cmIn0, out);
}
+26 -65
View File
@@ -29,85 +29,46 @@
typedef unsigned int uint;
#endif
// TODO: describe input format here.
// if a mesh is taken as input, the client must manage the memory
// if a mesh is given as output, please use the provided
// function to free the allocated memory.
struct CorkTriMesh
{
uint n_triangles;
uint n_vertices;
uint *triangles;
float *vertices;
};
// the inputs to a Boolean operation must be "solid":
// - closed (aka. watertight;
// every edge has an even number of incident triangles)
void freeCorkTriMesh(CorkTriMesh *mesh);
// the inputs to Boolean operations must be "solid":
// - closed (aka. watertight; see comment at bottom)
// - non-self-intersecting
// - have consistent CCW triangle orientation
// This function will test whether or not a given mesh is solid
bool isSolid(
uint n_triangles, uint *triangles,
uint n_vertices, float *vertices
);
// additionally, inputs should use a counter-clockwise convention
// for triangle facing. If the triangles are presented in clockwise
// orientation, the object is interpreted as its unbounded complement
// This function will test whether or not a mesh is solid
bool isSolid(CorkTriMesh mesh);
// Boolean operations follow
// result = A U B
void computeUnion(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
);
void computeUnion(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out);
// result = A - B
void computeDifference(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
);
void computeDifference(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out);
// result = A ^ B
void computeIntersection(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
);
void computeIntersection(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out);
// result = A XOR B
void computeSymmetricDifference(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
);
CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out);
// An operation which is not a Boolean operation, but is related:
// Not a Boolean operation, but related:
// No portion of either surface is deleted. However, the
// curve of intersection between the two surfaces is made explicit,
// such that the two surfaces are now connected.
void resolveIntersections(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
);
void resolveIntersections(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out);
+67 -77
View File
@@ -43,55 +43,49 @@ using std::ostream;
#include "cork.h"
void file2cmesh(
const Files::FileMesh &in,
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
void file2corktrimesh(
const Files::FileMesh &in, CorkTriMesh *out
) {
*n_vertices_out = in.vertices.size();
*n_triangles_out = in.triangles.size();
out->n_vertices = in.vertices.size();
out->n_triangles = in.triangles.size();
*triangles_out = new uint[(*n_triangles_out) * 3];
*vertices_out = new float[(*n_vertices_out) * 3];
out->triangles = new uint[(out->n_triangles) * 3];
out->vertices = new float[(out->n_vertices) * 3];
for(uint i=0; i<*n_triangles_out; i++) {
(*triangles_out)[3*i+0] = in.triangles[i].a;
(*triangles_out)[3*i+1] = in.triangles[i].b;
(*triangles_out)[3*i+2] = in.triangles[i].c;
for(uint i=0; i<out->n_triangles; i++) {
(out->triangles)[3*i+0] = in.triangles[i].a;
(out->triangles)[3*i+1] = in.triangles[i].b;
(out->triangles)[3*i+2] = in.triangles[i].c;
}
for(uint i=0; i<*n_vertices_out; i++) {
(*vertices_out)[3*i+0] = in.vertices[i].pos.x;
(*vertices_out)[3*i+1] = in.vertices[i].pos.y;
(*vertices_out)[3*i+2] = in.vertices[i].pos.z;
for(uint i=0; i<out->n_vertices; i++) {
(out->vertices)[3*i+0] = in.vertices[i].pos.x;
(out->vertices)[3*i+1] = in.vertices[i].pos.y;
(out->vertices)[3*i+2] = in.vertices[i].pos.z;
}
}
void cmesh2file(
uint n_triangles_in, uint *triangles_in,
uint n_vertices_in, float *vertices_in,
Files::FileMesh &out
void corktrimesh2file(
CorkTriMesh in, Files::FileMesh &out
) {
out.vertices.resize(n_vertices_in);
out.triangles.resize(n_triangles_in);
out.vertices.resize(in.n_vertices);
out.triangles.resize(in.n_triangles);
for(uint i=0; i<n_triangles_in; i++) {
out.triangles[i].a = triangles_in[3*i+0];
out.triangles[i].b = triangles_in[3*i+1];
out.triangles[i].c = triangles_in[3*i+2];
for(uint i=0; i<in.n_triangles; i++) {
out.triangles[i].a = in.triangles[3*i+0];
out.triangles[i].b = in.triangles[3*i+1];
out.triangles[i].c = in.triangles[3*i+2];
}
for(uint i=0; i<n_vertices_in; i++) {
out.vertices[i].pos.x = vertices_in[3*i+0];
out.vertices[i].pos.y = vertices_in[3*i+1];
out.vertices[i].pos.z = vertices_in[3*i+2];
for(uint i=0; i<in.n_vertices; i++) {
out.vertices[i].pos.x = in.vertices[3*i+0];
out.vertices[i].pos.y = in.vertices[3*i+1];
out.vertices[i].pos.z = in.vertices[3*i+2];
}
}
void loadMesh(string filename,
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
) {
void loadMesh(string filename, CorkTriMesh *out)
{
Files::FileMesh filemesh;
if(Files::readTriMesh(filename, &filemesh) > 0) {
@@ -99,22 +93,13 @@ void loadMesh(string filename,
exit(1);
}
file2cmesh(filemesh,
n_triangles_out, triangles_out,
n_vertices_out, vertices_out
);
file2corktrimesh(filemesh, out);
}
void saveMesh(string filename,
uint n_triangles_in, uint *triangles_in,
uint n_vertices_in, float *vertices_in
) {
void saveMesh(string filename, CorkTriMesh in)
{
Files::FileMesh filemesh;
cmesh2file(
n_triangles_in, triangles_in,
n_vertices_in, vertices_in,
filemesh
);
corktrimesh2file(in, filemesh);
if(Files::writeTriMesh(filename, &filemesh) > 0) {
cerr << "Unable to write to " << filename << endl;
@@ -222,51 +207,37 @@ std::function< void(
const std::vector<string>::iterator &
) >
genericBinaryOp(
std::function< void(
// input mesh 0
uint n_triangles_in0, uint *triangles_in0,
uint n_vertices_in0, float *vertices_in0,
// input mesh 1
uint n_triangles_in1, uint *triangles_in1,
uint n_vertices_in1, float *vertices_in1,
// output mesh
uint *n_triangles_out, uint **triangles_out,
uint *n_vertices_out, float **vertices_out
) > binop
std::function< void(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out) >
binop
) {
return [binop]
(std::vector<string>::iterator &args,
const std::vector<string>::iterator &end) {
// data...
uint nTri0, nTri1, nTriOut;
uint nVert0, nVert1, nVertOut;
uint *tri0, *tri1, *triOut;
float *vert0, *vert1, *vertOut;
CorkTriMesh in0;
CorkTriMesh in1;
CorkTriMesh out;
if(args == end) { cerr << "too few args" << endl; exit(1); }
loadMesh(*args, &nTri0, &tri0, &nVert0, &vert0);
loadMesh(*args, &in0);
args++;
if(args == end) { cerr << "too few args" << endl; exit(1); }
loadMesh(*args, &nTri1, &tri1, &nVert1, &vert1);
loadMesh(*args, &in1);
args++;
binop(
nTri0, tri0, nVert0, vert0,
nTri1, tri1, nVert1, vert1,
&nTriOut, &triOut, &nVertOut, &vertOut
);
binop(in0, in1, &out);
if(args == end) { cerr << "too few args" << endl; exit(1); }
saveMesh(*args, nTriOut, triOut, nVertOut, vertOut);
saveMesh(*args, out);
args++;
delete [] tri0;
delete [] tri1;
delete [] triOut;
delete [] vert0;
delete [] vert1;
delete [] vertOut;
freeCorkTriMesh(&out);
delete[] in0.vertices;
delete[] in0.triangles;
delete[] in1.vertices;
delete[] in1.triangles;
};
}
@@ -293,6 +264,25 @@ int main(int argc, char *argv[])
CmdList cmds;
// add cmds
cmds.regCmd("solid",
"-solid in Determine whether the input mesh represents\n"
" a solid object. (aka. watertight) (technically\n"
" solid == closed and non-self-intersecting)",
[](std::vector<string>::iterator &args,
const std::vector<string>::iterator &end) {
CorkTriMesh in;
if(args == end) { cerr << "too few args" << endl; exit(1); }
string filename = *args;
loadMesh(*args, &in);
args++;
bool solid = isSolid(in);
cout << "The mesh " << filename << " is: " << endl;
cout << " " << ((solid)? "SOLID" : "NOT SOLID") << endl;
delete[] in.vertices;
delete[] in.triangles;
});
cmds.regCmd("union",
"-union in0 in1 out Compute the Boolean union of in0 and in1,\n"
" and output the result",
@@ -308,7 +298,7 @@ int main(int argc, char *argv[])
cmds.regCmd("xor",
"-xor in0 in1 out Compute the Boolean XOR of in0 and in1,\n"
" and output the result\n"
" (aka. the symmetric difference)\n",
" (aka. the symmetric difference)",
genericBinaryOp(computeSymmetricDifference));
cmds.regCmd("resolve",
"-resolve in0 in1 out Intersect the two meshes in0 and in1,\n"
+3
View File
@@ -184,6 +184,8 @@ public:
std::function<void(TriData &,
VertData &, VertData &, VertData &)> func);
// checks if the mesh is closed
bool isClosed();
public: // REMESHING module
// REQUIRES:
@@ -194,6 +196,7 @@ public: // REMESHING module
public: // ISCT (intersections) module
void resolveIntersections(); // makes all intersections explicit
bool isSelfIntersecting(); // is the mesh self-intersecting?
// TESTING
void testingComputeStaticIsctPoints(std::vector<Vec3d> *points);
void testingComputeStaticIsct(std::vector<Vec3d> *points,
+33
View File
@@ -789,6 +789,8 @@ public:
// create edges as necessary...
}*/
bool hasIntersections(); // test for iscts, exit if one is found
void findIntersections();
void resolveAllIntersections();
private:
@@ -1056,6 +1058,29 @@ void Mesh<VertData,TriData>::IsctProblem::findIntersections()
});
}
template<class VertData, class TriData>
bool Mesh<VertData,TriData>::IsctProblem::hasIntersections()
{
bool foundIsct = false;
Empty3d::degeneracy_count = 0;
// Find some edge-triangle intersection point...
bvh_edge_tri([&](Eptr eisct, Tptr tisct)->bool{
if(checkIsct(eisct,tisct)) {
foundIsct = true;
return false; // break;
}
if(Empty3d::degeneracy_count > 0) {
return false; // break;
}
return true; // continue
});
if(Empty3d::degeneracy_count > 0 || foundIsct) {
return true;
} else {
return false;
}
}
template<class VertData, class TriData> inline
@@ -1471,5 +1496,13 @@ void Mesh<VertData,TriData>::resolveIntersections()
//iproblem.print();
}
template<class VertData, class TriData>
bool Mesh<VertData,TriData>::isSelfIntersecting()
{
IsctProblem iproblem(this);
return iproblem.hasIntersections();
}
+28
View File
@@ -186,6 +186,34 @@ typename Mesh<VertData,TriData>::Isct
template<class VertData, class TriData>
bool Mesh<VertData,TriData>::isClosed()
{
EGraphCache<int> chains = createEGraphCache<int>();
// count up how many times each edge is encountered in one
// orientation vs. the other
for(Tri &tri : tris) {
chains(tri.a, tri.b).data ++;
chains(tri.b, tri.a).data --;
chains(tri.b, tri.c).data ++;
chains(tri.c, tri.b).data --;
chains(tri.c, tri.a).data ++;
chains(tri.a, tri.c).data --;
}
// now go through and see if any of these are non-zero
bool closed = true;
chains.for_each([&](uint i, uint j, EGraphEntry<int> &entry) {
if(entry.data != 0)
closed = false;
});
return closed;
}
static inline
bool contains(const ShortVec<uint, 8> &list, uint item)
{