Skip to content

Commit

Permalink
CSGCompiler: import() (for all mesh formats supported by geogram)
Browse files Browse the repository at this point in the history
             render() (calls group())
  • Loading branch information
BrunoLevy committed Nov 8, 2023
1 parent 8abdaea commit 7d49066
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/examples/geogram/compute_CSG/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ int main(int argc, char** argv) {
CmdLine::import_arg_group("algo");

std::vector<std::string> filenames;

CmdLine::declare_arg(
"verbose",false,"makes intersection algorithm more chatty"
);

if(
!CmdLine::parse(
Expand All @@ -159,6 +163,7 @@ int main(int argc, char** argv) {
result = example004();
} else {
CSGCompiler CSG;
CSG.set_verbose(CmdLine::get_arg_bool("verbose"));
result = CSG.compile_file(csg_filename);
}
if(result.is_null()) {
Expand Down
65 changes: 64 additions & 1 deletion src/lib/geogram/mesh/mesh_CSG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <geogram/mesh/mesh_surface_intersection.h>
#include <geogram/mesh/mesh_fill_holes.h>
#include <geogram/mesh/mesh_repair.h>
#include <geogram/mesh/mesh_io.h>
#include <geogram/delaunay/delaunay.h>
#include <geogram/basic/command_line.h>

Expand Down Expand Up @@ -204,6 +205,8 @@ namespace GEO {

CSGBuilder::CSGBuilder() : create_center_vertex_(true) {
reset_defaults();
STL_epsilon_ = 1e-6;
verbose_ = false;
}

void CSGBuilder::reset_defaults() {
Expand Down Expand Up @@ -458,6 +461,22 @@ namespace GEO {
return M;
}

CSGMesh_var CSGBuilder::import(const std::string& filename) {
CSGMesh_var result = new CSGMesh;
if(!mesh_load(filename, *result)) {
result.reset();
return result;
}
std::string ext = FileSystem::extension(filename);
String::to_lowercase(ext);
if( ext == "stl") {
mesh_repair(*result, MESH_REPAIR_DEFAULT, STL_epsilon_);
}
result->update_bbox();
return result;
}


/****** Instructions ****/

CSGMesh_var CSGBuilder::multmatrix(const mat4& M, const CSGScope& scope) {
Expand Down Expand Up @@ -739,6 +758,7 @@ namespace GEO {
DECLARE_OBJECT(sphere);
DECLARE_OBJECT(cylinder);
DECLARE_OBJECT(polyhedron);
DECLARE_OBJECT(import);

#define DECLARE_INSTRUCTION(instr) \
instruction_funcs_[#instr] = &CSGCompiler::instr;
Expand All @@ -749,7 +769,8 @@ namespace GEO {
DECLARE_INSTRUCTION(color);
DECLARE_INSTRUCTION(hull);
DECLARE_INSTRUCTION(linear_extrude);
instruction_funcs_["union"] = &CSGCompiler::union_instr;
instruction_funcs_["union"] = &CSGCompiler::union_instr;
instruction_funcs_["render"] = &CSGCompiler::group;
}

CSGMesh_var CSGCompiler::compile_file(const std::string& input_filename) {
Expand Down Expand Up @@ -913,6 +934,16 @@ namespace GEO {
return M;
}

CSGMesh_var CSGCompiler::import(const ArgList& args) {
std::string filename = "";
filename = args.get_arg("file", filename);
CSGMesh_var M = builder_.import(filename);
if(M.is_null()) {
syntax_error((filename + ": could not load").c_str());
}
return M;
}

/********* Instructions **************************************************/

CSGMesh_var CSGCompiler::multmatrix(
Expand Down Expand Up @@ -1117,6 +1148,10 @@ namespace GEO {
return Value(tok.boolean_val);
}

if(tok.type == CLEX_dqstring) {
return Value(tok.str_val);
}

syntax_error("Expected value", tok);
}

Expand Down Expand Up @@ -1212,6 +1247,9 @@ namespace GEO {
result.boolean_val = false;
}
}
if(getlex(lex_).token == CLEX_dqstring) {
result.str_val = getlex(lex_).string;
}
result.int_val = int(getlex(lex_).int_number);
result.double_val = getlex(lex_).real_number;
} else {
Expand Down Expand Up @@ -1266,6 +1304,11 @@ namespace GEO {

CSGCompiler::Value::Value() : type(NONE) {
}

CSGCompiler::Value::Value(const std::string& x) :
type(STRING),
string_val(x) {
}

CSGCompiler::Value::Value(double x) :
type(NUMBER),
Expand Down Expand Up @@ -1314,6 +1357,9 @@ namespace GEO {
result += "]";
return result;
}
case STRING: {
return "\"" + string_val + "\"";
}
}
return "<unknown>";
}
Expand Down Expand Up @@ -1523,6 +1569,23 @@ namespace GEO {
}
return default_value;
}

std::string CSGCompiler::ArgList::get_arg(
const std::string& name, const std::string& default_value
) const {
for(const Arg& arg : args_) {
if(arg.first == name) {
if(arg.second.type != Value::STRING) {
throw(std::logic_error(
"Arg " + name + " has wrong type"
));
}
return arg.second.string_val;
}
}
return default_value;
}


/***** Token **********************************************************/

Expand Down
31 changes: 29 additions & 2 deletions src/lib/geogram/mesh/mesh_CSG.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ namespace GEO {
CSGMesh_var cylinder(
double h=1.0, double r1=1.0, double r2=1.0, bool center=true
);

CSGMesh_var import(const std::string& filename);

/****** Instructions ****/

/**
Expand Down Expand Up @@ -256,6 +257,15 @@ namespace GEO {
fa_ = std::max(fa,0.01);
}

/**
* \brief Displays (lots of) additional information
* \param[in] x whether additional information should be displayed.
* Default is off
*/
void set_verbose(bool x) {
verbose_ = x;
}

protected:

/**
Expand All @@ -281,6 +291,8 @@ namespace GEO {
double fn_;
double fs_;
double fa_;
double STL_epsilon_;
bool verbose_;
};

/**************************************************************/
Expand All @@ -296,6 +308,15 @@ namespace GEO {
CSGMesh_var compile_file(const std::string& input_filename);
CSGMesh_var compile_string(const std::string& source);

/**
* \brief Displays (lots of) additional information
* \param[in] x whether additional information should be displayed.
* Default is off
*/
void set_verbose(bool x) {
builder_.set_verbose(x);
}

protected:

/****** Value, Arglist **********************************/
Expand All @@ -305,18 +326,20 @@ namespace GEO {
* \details Can be a number, a boolean, a 1d array or a 2d array
*/
struct Value {
enum Type {NONE, NUMBER, BOOLEAN, ARRAY1D, ARRAY2D};
enum Type {NONE, NUMBER, BOOLEAN, ARRAY1D, ARRAY2D, STRING};

Value();
Value(double x);
Value(int x);
Value(bool x);
Value(const std::string& x);
std::string to_string() const;

Type type;
bool boolean_val;
double number_val;
vector<vector<double> > array_val;
std::string string_val;
};

/**
Expand Down Expand Up @@ -353,6 +376,9 @@ namespace GEO {
mat4 get_arg(
const std::string& name, const mat4& default_value
) const;
std::string get_arg(
const std::string& name, const std::string& default_value
) const;

private:
vector<Arg> args_;
Expand All @@ -367,6 +393,7 @@ namespace GEO {
CSGMesh_var sphere(const ArgList& args);
CSGMesh_var cylinder(const ArgList& args);
CSGMesh_var polyhedron(const ArgList& args);
CSGMesh_var import(const ArgList& args);

/****** Instructions ************************************/

Expand Down
4 changes: 4 additions & 0 deletions src/lib/geogram/mesh/mesh_surface_intersection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,10 @@ namespace GEO {
MeshSurfaceIntersection I(result);
I.set_radial_sort(false); // For now classification does not use it
I.intersect();

// TODO: do we really need these two calls to mesh_repair() ?
// If removed, example006.csg takes more time...
// We need to better understand what's going on here.
mesh_repair(result); // Merge duplicated facets, reorient, get charts
mesh_classify_intersections(result, operation, "", false);
mesh_repair(result); // Final gluing
Expand Down

0 comments on commit 7d49066

Please sign in to comment.