diff --git a/Makefile b/Makefile index a9fbb62c..4bf2de49 100644 --- a/Makefile +++ b/Makefile @@ -35,8 +35,8 @@ PLATFORM := $(shell uname) # | Programs | # +----------+ CPP11_FLAGS := -std=c++11 -CC := clang -CXX := clang++ +CC := gcc +CXX := g++ ifeq ($(PLATFORM),Darwin) # on mac CPP11_FLAGS := $(CPP11_FLAGS) -stdlib=libc++ -Wno-c++11-extensions endif @@ -79,6 +79,12 @@ ifeq ($(PLATFORM),Darwin) LINKD := $(LINK) -Wl,-no_pie endif +ARCH = $(shell uname -m) + +ifeq ($(findstring x86_64,$(ARCH)), x86_64) + CCFLAGS += -m64 + CXXFLAGS+= -m64 +endif # *********************** # * SOURCE DECLARATIONS * diff --git a/src/cork.cpp b/src/cork.cpp index 75302b32..2438e750 100644 --- a/src/cork.cpp +++ b/src/cork.cpp @@ -206,6 +206,9 @@ void computeUnion( cmIn0.boolUnion(cmIn1); + if(out->remesh) + cmIn0.remesh(); + corkMesh2CorkTriMesh(&cmIn0, out); } @@ -218,6 +221,9 @@ void computeDifference( cmIn0.boolDiff(cmIn1); + if(out->remesh) + cmIn0.remesh(); + corkMesh2CorkTriMesh(&cmIn0, out); } @@ -230,6 +236,9 @@ void computeIntersection( cmIn0.boolIsct(cmIn1); + if(out->remesh) + cmIn0.remesh(); + corkMesh2CorkTriMesh(&cmIn0, out); } @@ -242,6 +251,9 @@ void computeSymmetricDifference( cmIn0.boolXor(cmIn1); + if(out->remesh) + cmIn0.remesh(); + corkMesh2CorkTriMesh(&cmIn0, out); } @@ -255,6 +267,50 @@ void resolveIntersections( cmIn0.disjointUnion(cmIn1); cmIn0.resolveIntersections(); + if(out->remesh){ + cmIn0.remesh(); + } + corkMesh2CorkTriMesh(&cmIn0, out); +} + +void computeFirst( + CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out +) { + CorkMesh cmIn0, cmIn1; + corkTriMesh2CorkMesh(in0, &cmIn0); + corkTriMesh2CorkMesh(in1, &cmIn1); + + cmIn0.boolFirst(cmIn1); + + if(out->remesh) + cmIn0.remesh(); + corkMesh2CorkTriMesh(&cmIn0, out); } +void computeSecond( + CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out +) { + CorkMesh cmIn0, cmIn1; + corkTriMesh2CorkMesh(in0, &cmIn0); + corkTriMesh2CorkMesh(in1, &cmIn1); + + cmIn1.boolFirst(cmIn0); + + if(out->remesh) + cmIn1.remesh(); + + corkMesh2CorkTriMesh(&cmIn1, out); +} + + +void remeshTriangles( + CorkTriMesh in, CorkTriMesh *out +) { + CorkMesh cmIn; + corkTriMesh2CorkMesh(in, &cmIn); + + cmIn.remesh(); + + corkMesh2CorkTriMesh(&cmIn, out); +} diff --git a/src/cork.h b/src/cork.h index 78bcb8a8..bbb6e65a 100644 --- a/src/cork.h +++ b/src/cork.h @@ -38,6 +38,7 @@ struct CorkTriMesh uint n_vertices; uint *triangles; float *vertices; + uint remesh; }; void freeCorkTriMesh(CorkTriMesh *mesh); @@ -72,3 +73,9 @@ void computeSymmetricDifference( // such that the two surfaces are now connected. void resolveIntersections(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out); +// result = A cut by B +void computeFirst(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out); +// result = B cut by A +void computeSecond(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out); +// result = remesh(A) +void remeshTriangles(CorkTriMesh in, CorkTriMesh *out); diff --git a/src/file_formats/off.cpp b/src/file_formats/off.cpp index 3b125716..f5e032d6 100644 --- a/src/file_formats/off.cpp +++ b/src/file_formats/off.cpp @@ -93,6 +93,7 @@ int writeOFF(string filename, FileMesh *data) int numfaces = data->triangles.size(); out << numvertices << ' ' << numfaces << ' ' << 0 << endl; + out.precision(18); // vertex data for(const auto &v : data->vertices) { const Vec3d &p = v.pos; diff --git a/src/isct/triangle.c b/src/isct/triangle.c index 08dcc87e..9102f1b6 100644 --- a/src/isct/triangle.c +++ b/src/isct/triangle.c @@ -3295,8 +3295,11 @@ struct behavior *b; int increment; int meshnumber; #endif /* not TRILIBRARY */ - int i, j, k; + int i, j; +#ifndef CDT_ONLY + int k; char workstring[FILENAMESIZE]; +#endif b->poly = b->refine = b->quality = 0; b->vararea = b->fixedarea = b->usertest = 0; diff --git a/src/main.cpp b/src/main.cpp index 93d89c43..a2ccb2f6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,6 +42,7 @@ using std::ostream; #include "cork.h" +int doremesh=0; void file2corktrimesh( const Files::FileMesh &in, CorkTriMesh *out @@ -165,6 +166,7 @@ void CmdList::printHelp(ostream &out) out << "Welcome to Cork. Usage:" << endl << " > cork [-command arg0 arg1 ... argn]*" << endl << + " if --command is used, a remesh is applied to the output" << endl << "for example," << endl << " > cork -union box0.off box1.off result.off" << endl << "Options:" << endl; @@ -184,6 +186,10 @@ void CmdList::runCommands(std::vector::iterator &arg_it, exit(1); } arg_cmd = arg_cmd.substr(1); + if(arg_cmd[0] == '-') { + doremesh=1; + arg_cmd = arg_cmd.substr(1); + } arg_it++; bool found = true; @@ -217,6 +223,8 @@ genericBinaryOp( CorkTriMesh in0; CorkTriMesh in1; CorkTriMesh out; + + out.remesh=doremesh; if(args == end) { cerr << "too few args" << endl; exit(1); } loadMesh(*args, &in0); @@ -244,7 +252,10 @@ genericBinaryOp( int main(int argc, char *argv[]) { - initRand(); // that's useful + if(argc>=6){ + initRand(atoi(argv[5])); //use the 4th argument to set the seed + }else + initRand(); if(argc < 2) { cout << "Please type 'cork -help' for instructions" << endl; @@ -305,8 +316,39 @@ int main(int argc, char *argv[]) " and output the connected mesh with those\n" " intersections made explicit and connected", genericBinaryOp(resolveIntersections)); - - + cmds.regCmd("first", + "-first in0 in1 out Compute the first mesh in0 cut by the second mesh in1,\n" + " and output the result", + genericBinaryOp(computeFirst)); + cmds.regCmd("second", + "-second in0 in1 out Compute the second mesh in1 cut by the first mesh in0,\n" + " and output the result", + genericBinaryOp(computeSecond)); + + // add cmds + cmds.regCmd("remesh", + "-remesh in out Remesh the input mesh to remove poorly shaped triangles", + [](std::vector::iterator &args, + const std::vector::iterator &end) { + CorkTriMesh in; + CorkTriMesh out; + + if(args == end) { cerr << "too few args" << endl; exit(1); } + loadMesh(*args, &in); + args++; + + remeshTriangles(in, &out); + + if(args == end) { cerr << "too few args" << endl; exit(1); } + saveMesh(*args, out); + args++; + + freeCorkTriMesh(&out); + + delete[] in.vertices; + delete[] in.triangles; + }); + cmds.runCommands(arg_it, args.end()); return 0; diff --git a/src/mesh/mesh.bool.tpp b/src/mesh/mesh.bool.tpp index 6b76c551..0c6e747d 100644 --- a/src/mesh/mesh.bool.tpp +++ b/src/mesh/mesh.bool.tpp @@ -356,17 +356,17 @@ void Mesh::boolXor(Mesh &rhs) }); } - - - - - - - - - - - - - - +template +void Mesh::boolFirst(Mesh &rhs) +{ + BoolProblem bprob(this); + + bprob.doSetup(rhs); + + bprob.doDeleteAndFlip([](byte data) -> typename BoolProblem::TriCode { + if(data == 1) // part of op 1 OUTSIDE op 0 + return BoolProblem::DELETE_TRI; + else // otherwise + return BoolProblem::KEEP_TRI; + }); +} diff --git a/src/mesh/mesh.decl.h b/src/mesh/mesh.decl.h index 0adac06f..d940e611 100644 --- a/src/mesh/mesh.decl.h +++ b/src/mesh/mesh.decl.h @@ -212,6 +212,7 @@ class Mesh void boolDiff(Mesh &rhs); void boolIsct(Mesh &rhs); void boolXor(Mesh &rhs); + void boolFirst(Mesh &rhs); private: // Internal Formats struct Tri { diff --git a/src/util/prelude.h b/src/util/prelude.h index 00329aad..fb92a0e3 100644 --- a/src/util/prelude.h +++ b/src/util/prelude.h @@ -25,11 +25,13 @@ // +------------------------------------------------------------------------- #pragma once +#define _USE_MATH_DEFINES #include #include #include #include #include +#include #ifndef uint typedef unsigned int uint; @@ -39,6 +41,10 @@ typedef unsigned int uint; typedef unsigned char byte; #endif +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + // *********** // * Logging @@ -150,6 +156,11 @@ inline void initRand() { srand(uint(time(0))); } +inline void initRand(uint seed) { + // currently none! Should seed using clock + srand(seed); +} + inline double drand(double min, double max) { const double invMAX = 1.0/double(RAND_MAX); double rand0to1 = double(std::rand())*invMAX;