// +-------------------------------------------------------------------------
// | main.cpp
// |
// | Author: Gilbert Bernstein
// +-------------------------------------------------------------------------
// | COPYRIGHT:
// | Copyright Gilbert Bernstein 2013
// | See the included COPYRIGHT file for further details.
// |
// | This file is part of the Cork library.
// |
// | Cork is free software: you can redistribute it and/or modify
// | it under the terms of the GNU Lesser General Public License as
// | published by the Free Software Foundation, either version 3 of
// | the License, or (at your option) any later version.
// |
// | Cork is distributed in the hope that it will be useful,
// | but WITHOUT ANY WARRANTY; without even the implied warranty of
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// | GNU Lesser General Public License for more details.
// |
// | You should have received a copy
// | of the GNU Lesser General Public License
// | along with Cork. If not, see .
// +-------------------------------------------------------------------------
// This file contains a command line program that can be used
// to exercise Cork's functionality without having to write
// any code.
#include "files.h"
#include
using std::cout;
using std::cerr;
using std::endl;
#include
using std::stringstream;
using std::string;
using std::ostream;
#include "cork.h"
void file2corktrimesh(
const Files::FileMesh &in, CorkTriMesh *out
) {
out->n_vertices = in.vertices.size();
out->n_triangles = in.triangles.size();
out->triangles = new uint[(out->n_triangles) * 3];
out->vertices = new float[(out->n_vertices) * 3];
for(uint i=0; in_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; in_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 corktrimesh2file(
CorkTriMesh in, Files::FileMesh &out
) {
out.vertices.resize(in.n_vertices);
out.triangles.resize(in.n_triangles);
for(uint i=0; i 0) {
cerr << "Unable to load in " << filename << endl;
exit(1);
}
file2corktrimesh(filemesh, out);
}
void saveMesh(string filename, CorkTriMesh in)
{
Files::FileMesh filemesh;
corktrimesh2file(in, filemesh);
if(Files::writeTriMesh(filename, &filemesh) > 0) {
cerr << "Unable to write to " << filename << endl;
exit(1);
}
}
class CmdList {
public:
CmdList();
~CmdList() {}
void regCmd(
string name,
string helptxt,
std::function< void(std::vector::iterator &,
const std::vector::iterator &) > body
);
void printHelp(ostream &out);
void runCommands(std::vector::iterator &arg_it,
const std::vector::iterator &end_it);
private:
struct Command {
string name; // e.g. "show" will be invoked with option "-show"
string helptxt; // lines to be displayed
std::function< void(std::vector::iterator &,
const std::vector::iterator &) > body;
};
std::vector commands;
};
CmdList::CmdList()
{
regCmd("help",
"-help show this help message",
[this](std::vector::iterator &,
const std::vector::iterator &) {
printHelp(cout);
exit(0);
});
}
void CmdList::regCmd(
string name,
string helptxt,
std::function< void(std::vector::iterator &,
const std::vector::iterator &) > body
) {
Command cmd = {
name,
helptxt,
body
};
commands.push_back(cmd);
}
void CmdList::printHelp(ostream &out)
{
out <<
"Welcome to Cork. Usage:" << endl <<
" > cork [-command arg0 arg1 ... argn]*" << endl <<
"for example," << endl <<
" > cork -union box0.off box1.off result.off" << endl <<
"Options:" << endl;
for(auto &cmd : commands)
out << cmd.helptxt << endl;
out << endl;
}
void CmdList::runCommands(std::vector::iterator &arg_it,
const std::vector::iterator &end_it)
{
while(arg_it != end_it) {
string arg_cmd = *arg_it;
if(arg_cmd[0] != '-') {
cerr << arg_cmd << endl;
cerr << "All commands must begin with '-'" << endl;
exit(1);
}
arg_cmd = arg_cmd.substr(1);
arg_it++;
bool found = true;
for(auto &cmd : commands) {
if(arg_cmd == cmd.name) {
cmd.body(arg_it, end_it);
found = true;
break;
}
}
if(!found) {
cerr << "Command -" + arg_cmd + " is not recognized" << endl;
exit(1);
}
}
}
std::function< void(
std::vector::iterator &,
const std::vector::iterator &
) >
genericBinaryOp(
std::function< void(CorkTriMesh in0, CorkTriMesh in1, CorkTriMesh *out) >
binop
) {
return [binop]
(std::vector::iterator &args,
const std::vector::iterator &end) {
// data...
CorkTriMesh in0;
CorkTriMesh in1;
CorkTriMesh out;
if(args == end) { cerr << "too few args" << endl; exit(1); }
loadMesh(*args, &in0);
args++;
if(args == end) { cerr << "too few args" << endl; exit(1); }
loadMesh(*args, &in1);
args++;
binop(in0, in1, &out);
if(args == end) { cerr << "too few args" << endl; exit(1); }
saveMesh(*args, out);
args++;
freeCorkTriMesh(&out);
delete[] in0.vertices;
delete[] in0.triangles;
delete[] in1.vertices;
delete[] in1.triangles;
};
}
int main(int argc, char *argv[])
{
initRand(); // that's useful
if(argc < 2) {
cout << "Please type 'cork -help' for instructions" << endl;
exit(0);
}
// store arguments in a standard container
std::vector args(argc);
for(int k=0; k::iterator &args,
const std::vector::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",
genericBinaryOp(computeUnion));
cmds.regCmd("diff",
"-diff in0 in1 out Compute the Boolean difference of in0 and in1,\n"
" and output the result",
genericBinaryOp(computeDifference));
cmds.regCmd("isct",
"-isct in0 in1 out Compute the Boolean intersection of in0 and in1,\n"
" and output the result",
genericBinaryOp(computeIntersection));
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)",
genericBinaryOp(computeSymmetricDifference));
cmds.regCmd("resolve",
"-resolve in0 in1 out Intersect the two meshes in0 and in1,\n"
" and output the connected mesh with those\n"
" intersections made explicit and connected",
genericBinaryOp(resolveIntersections));
cmds.runCommands(arg_it, args.end());
return 0;
}