diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index a91550a7..8ca203a2 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -59,36 +59,36 @@ bool CGALEvaluator::isCached(const AbstractNode &node) const Modifies target by applying op to target and src: target = target [op] src */ -void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, CGALEvaluator::CsgOp op) +void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, OpenSCADOperator op) { if (target.dim != 2 && target.dim != 3) { assert(false && "Dimension of Nef polyhedron must be 2 or 3"); } if (src.isEmpty()) return; // Empty polyhedron. This can happen for e.g. square([0,0]) - if (target.isEmpty() && op != CGE_UNION) return; // empty op => empty + if (target.isEmpty() && op != OPENSCAD_UNION) return; // empty op => empty if (target.dim != src.dim) return; // If someone tries to e.g. union 2d and 3d objects CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); try { switch (op) { - case CGE_UNION: + case OPENSCAD_UNION: if (target.isEmpty()) target = src.copy(); else target += src; break; - case CGE_INTERSECTION: + case OPENSCAD_INTERSECTION: target *= src; break; - case CGE_DIFFERENCE: + case OPENSCAD_DIFFERENCE: target -= src; break; - case CGE_MINKOWSKI: + case OPENSCAD_MINKOWSKI: target.minkowski(src); break; } } catch (const CGAL::Failure_exception &e) { // union && difference assert triggered by testdata/scad/bugs/rotate-diff-nonmanifold-crash.scad and testdata/scad/bugs/issue204.scad - std::string opstr = op == CGE_UNION ? "union" : op == CGE_INTERSECTION ? "intersection" : op == CGE_DIFFERENCE ? "difference" : op == CGE_MINKOWSKI ? "minkowski" : "UNKNOWN"; + std::string opstr = op == OPENSCAD_UNION ? "union" : op == OPENSCAD_INTERSECTION ? "intersection" : op == OPENSCAD_DIFFERENCE ? "difference" : op == OPENSCAD_MINKOWSKI ? "minkowski" : "UNKNOWN"; PRINTB("CGAL error in CGAL_Nef_polyhedron's %s operator: %s", opstr % e.what()); // Errors can result in corrupt polyhedrons, so put back the old one @@ -99,7 +99,7 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr /*! */ -CGAL_Nef_polyhedron CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::CsgOp op) +CGAL_Nef_polyhedron CGALEvaluator::applyToChildren(const AbstractNode &node, OpenSCADOperator op) { CGAL_Nef_polyhedron N; BOOST_FOREACH(const ChildItem &item, this->visitedchildren[node.index()]) { @@ -201,7 +201,7 @@ CGAL_Nef_polyhedron CGALEvaluator::applyResize(const CgaladvNode &node) { // Based on resize() in Giles Bathgate's RapCAD (but not exactly) CGAL_Nef_polyhedron N; - N = applyToChildren(node, CGE_UNION); + N = applyToChildren(node, OPENSCAD_UNION); if ( N.isNull() || N.isEmpty() ) return N; @@ -277,7 +277,7 @@ Response CGALEvaluator::visit(State &state, const AbstractNode &node) if (state.isPrefix() && isCached(node)) return PruneTraversal; if (state.isPostfix()) { CGAL_Nef_polyhedron N; - if (!isCached(node)) N = applyToChildren(node, CGE_UNION); + if (!isCached(node)) N = applyToChildren(node, OPENSCAD_UNION); else N = CGALCache::instance()->get(this->tree.getIdString(node)); addToParent(state, node, N); } @@ -289,7 +289,7 @@ Response CGALEvaluator::visit(State &state, const AbstractIntersectionNode &node if (state.isPrefix() && isCached(node)) return PruneTraversal; if (state.isPostfix()) { CGAL_Nef_polyhedron N; - if (!isCached(node)) N = applyToChildren(node, CGE_INTERSECTION); + if (!isCached(node)) N = applyToChildren(node, OPENSCAD_INTERSECTION); else N = CGALCache::instance()->get(this->tree.getIdString(node)); addToParent(state, node, N); } @@ -302,21 +302,7 @@ Response CGALEvaluator::visit(State &state, const CsgNode &node) if (state.isPostfix()) { CGAL_Nef_polyhedron N; if (!isCached(node)) { - CGALEvaluator::CsgOp op = CGE_UNION; - switch (node.type) { - case CSG_TYPE_UNION: - op = CGE_UNION; - break; - case CSG_TYPE_DIFFERENCE: - op = CGE_DIFFERENCE; - break; - case CSG_TYPE_INTERSECTION: - op = CGE_INTERSECTION; - break; - default: - assert(false); - } - N = applyToChildren(node, op); + N = applyToChildren(node, node.type); } else { N = CGALCache::instance()->get(this->tree.getIdString(node)); @@ -333,7 +319,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) CGAL_Nef_polyhedron N; if (!isCached(node)) { // First union all children - N = applyToChildren(node, CGE_UNION); + N = applyToChildren(node, OPENSCAD_UNION); if ( matrix_contains_infinity( node.matrix ) || matrix_contains_nan( node.matrix ) ) { // due to the way parse/eval works we can't currently distinguish between NaN and Inf PRINT("Warning: Transformation matrix contains Not-a-Number and/or Infinity - removing object."); @@ -377,10 +363,10 @@ Response CGALEvaluator::visit(State &state, const CgaladvNode &node) if (state.isPostfix()) { CGAL_Nef_polyhedron N; if (!isCached(node)) { - CGALEvaluator::CsgOp op; + OpenSCADOperator op; switch (node.type) { case MINKOWSKI: - op = CGE_MINKOWSKI; + op = OPENSCAD_MINKOWSKI; N = applyToChildren(node, op); break; case GLIDE: diff --git a/src/CGALEvaluator.h b/src/CGALEvaluator.h index 458d2a0d..d8ca50b7 100644 --- a/src/CGALEvaluator.h +++ b/src/CGALEvaluator.h @@ -2,6 +2,7 @@ #define CGALEVALUATOR_H_ #include "visitor.h" +#include "enums.h" #include "CGAL_Nef_polyhedron.h" #include @@ -30,8 +31,8 @@ public: private: void addToParent(const State &state, const AbstractNode &node, const CGAL_Nef_polyhedron &N); bool isCached(const AbstractNode &node) const; - void process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, CGALEvaluator::CsgOp op); - CGAL_Nef_polyhedron applyToChildren(const AbstractNode &node, CGALEvaluator::CsgOp op); + void process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, OpenSCADOperator op); + CGAL_Nef_polyhedron applyToChildren(const AbstractNode &node, OpenSCADOperator op); CGAL_Nef_polyhedron applyHull(const CgaladvNode &node); CGAL_Nef_polyhedron applyResize(const CgaladvNode &node); diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index e149a9ca..9bb5da0a 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -130,13 +130,13 @@ Response CSGTermEvaluator::visit(State &state, const CsgNode &node) if (state.isPostfix()) { CsgOp op = CSGT_UNION; switch (node.type) { - case CSG_TYPE_UNION: + case OPENSCAD_UNION: op = CSGT_UNION; break; - case CSG_TYPE_DIFFERENCE: + case OPENSCAD_DIFFERENCE: op = CSGT_DIFFERENCE; break; - case CSG_TYPE_INTERSECTION: + case OPENSCAD_INTERSECTION: op = CSGT_INTERSECTION; break; default: diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 5736e248..6c7f38d3 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -7,10 +7,13 @@ #include "state.h" #include "transformnode.h" #include "linearextrudenode.h" +#include "rotateextrudenode.h" +#include "csgnode.h" #include "clipper-utils.h" #include "CGALEvaluator.h" #include "CGALCache.h" #include "PolySet.h" +#include "openscad.h" // get_fragments_from_r() #include @@ -93,10 +96,26 @@ Geometry *GeometryEvaluator::applyToChildren(const AbstractNode &node, OpenSCADO chnode->progress_report(); } + ClipperLib::ClipType clipType; + switch (op) { + case OPENSCAD_UNION: + clipType = ClipperLib::ctUnion; + break; + case OPENSCAD_INTERSECTION: + clipType = ClipperLib::ctIntersection; + break; + case OPENSCAD_DIFFERENCE: + clipType = ClipperLib::ctDifference; + break; + default: + PRINTB("Error: Unknown boolean operation %d", int(op)); + return NULL; + break; + } ClipperLib::Clipper clipper; clipper.AddPolygons(ClipperUtils::fromPolygon2d(sum), ClipperLib::ptSubject); ClipperLib::Polygons result; - clipper.Execute(ClipperLib::ctUnion, result); + clipper.Execute(clipType, result); if (result.size() == 0) return NULL; @@ -168,28 +187,49 @@ Response GeometryEvaluator::visit(State &state, const LeafNode &node) return PruneTraversal; } +Response GeometryEvaluator::visit(State &state, const CsgNode &node) +{ + if (state.isPrefix() && isCached(node)) return PruneTraversal; + if (state.isPostfix()) { + shared_ptr geom; + if (!isCached(node)) { + shared_ptr geom(applyToChildren(node, node.type)); + shared_ptr polygons = dynamic_pointer_cast(geom); + assert(polygons); + addToParent(state, node, geom); + } + // FIXME: if 3d node, CGAL? + } + return ContinueTraversal; +} + Response GeometryEvaluator::visit(State &state, const TransformNode &node) { if (state.isPrefix() && isCached(node)) return PruneTraversal; if (state.isPostfix()) { shared_ptr geom; if (!isCached(node)) { - // First union all children - geom.reset(applyToChildren(node, CGE_UNION)); if (matrix_contains_infinity(node.matrix) || matrix_contains_nan(node.matrix)) { // due to the way parse/eval works we can't currently distinguish between NaN and Inf PRINT("Warning: Transformation matrix contains Not-a-Number and/or Infinity - removing object."); - geom.reset(); - } - //FIXME: Handle 2D vs. 3D - shared_ptr polygons = dynamic_pointer_cast(geom); - if (polygons) { -// FIXME: Convert from mat3 to mat2: Transform2d mat2(node.matrix); - Transform2d mat2; -// polygons->transform(mat2); } else { - // FIXME: Handle 3D transfer + // First union all children + Geometry *geometry = applyToChildren(node, OPENSCAD_UNION); + Polygon2d *polygons = dynamic_cast(geometry); + //FIXME: Handle 2D vs. 3D + if (polygons) { + Transform2d mat2; + mat2.matrix() << + node.matrix(0,0), node.matrix(0,1), node.matrix(0,3), + node.matrix(1,0), node.matrix(1,1), node.matrix(1,3), + node.matrix(3,0), node.matrix(3,1), node.matrix(3,3); + polygons->transform(mat2); + geom.reset(polygons); + } + else { + // FIXME: Handle 3D transform + } } } else { @@ -200,20 +240,11 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node) return ContinueTraversal; } -static Vector2d transform(const Vector2d &v, double rot, const Vector2d &scale) -{ - return Vector2d(scale[0] * (v[0] * cos(rot*M_PI/180) + v[1] * sin(rot*M_PI/180)), - scale[1] * (v[0] * -sin(rot*M_PI/180) + v[1] * cos(rot*M_PI/180))); -} - -static void transform_PolySet(PolySet &ps, - double height, double rot, const Vector2d &scale) +static void translate_PolySet(PolySet &ps, const Vector3d &translation) { BOOST_FOREACH(PolySet::Polygon &p, ps.polygons) { BOOST_FOREACH(Vector3d &v, p) { - v = Vector3d(scale[0] * (v[0] * cos(rot*M_PI/180) + v[1] * sin(rot*M_PI/180)), - scale[1] * (v[0] * -sin(rot*M_PI/180) + v[1] * cos(rot*M_PI/180)), - height); + v += translation; } } } @@ -224,20 +255,23 @@ static void add_slice(PolySet *ps, const Polygon2d &poly, const Vector2d &scale1, const Vector2d &scale2) { + Eigen::Affine2d trans1(Eigen::Scaling(scale1) * Eigen::Rotation2D(rot1*M_PI/180)); + Eigen::Affine2d trans2(Eigen::Scaling(scale2) * Eigen::Rotation2D(rot2*M_PI/180)); + // FIXME: If scale2 == 0 we need to handle tessellation separately bool splitfirst = sin(rot2 - rot1) >= 0.0; BOOST_FOREACH(const Outline2d &o, poly.outlines()) { - Vector2d prev1 = transform(o[0], rot1, scale1); - Vector2d prev2 = transform(o[0], rot2, scale2); + Vector2d prev1 = trans1 * o[0]; + Vector2d prev2 = trans2 * o[0]; for (size_t i=1;i<=o.size();i++) { - Vector2d curr1 = transform(o[i % o.size()], rot1, scale1); - Vector2d curr2 = transform(o[i % o.size()], rot2, scale2); + Vector2d curr1 = trans1 * o[i % o.size()]; + Vector2d curr2 = trans2 * o[i % o.size()]; ps->append_poly(); if (splitfirst) { ps->insert_vertex(prev1[0], prev1[1], h1); - ps->insert_vertex(curr1[0], curr1[1], h1); ps->insert_vertex(curr2[0], curr2[1], h2); + ps->insert_vertex(curr1[0], curr1[1], h1); if (scale2[0] > 0 || scale2[1] > 0) { ps->append_poly(); ps->insert_vertex(curr2[0], curr2[1], h2); @@ -247,16 +281,16 @@ static void add_slice(PolySet *ps, const Polygon2d &poly, } else { ps->insert_vertex(prev1[0], prev1[1], h1); - ps->insert_vertex(curr1[0], curr1[1], h1); ps->insert_vertex(prev2[0], prev2[1], h2); + ps->insert_vertex(curr1[0], curr1[1], h1); if (scale2[0] > 0 || scale2[1] > 0) { ps->append_poly(); ps->insert_vertex(prev2[0], prev2[1], h2); - ps->insert_vertex(curr1[0], curr1[1], h1); ps->insert_vertex(curr2[0], curr2[1], h2); + ps->insert_vertex(curr1[0], curr1[1], h1); } } - prev1 = curr1; + prev1 = curr1; prev2 = curr2; } } @@ -286,8 +320,12 @@ static Geometry *extrudePolygon(const LinearExtrudeNode &node, const Polygon2d & ps->append(*ps_bottom); delete ps_bottom; if (node.scale_x > 0 || node.scale_y > 0) { - PolySet *ps_top = poly.tessellate(); // top - transform_PolySet(*ps_top, h2, node.twist, Vector2d(node.scale_x, node.scale_y)); + Polygon2d top_poly(poly); + Eigen::Affine2d trans(Eigen::Scaling(node.scale_x, node.scale_y) * + Eigen::Rotation2D(node.twist*M_PI/180)); + top_poly.transform(trans); // top + PolySet *ps_top = top_poly.tessellate(); + translate_PolySet(*ps_top, Vector3d(0,0,h2)); ps->append(*ps_top); delete ps_top; } @@ -312,7 +350,7 @@ Response GeometryEvaluator::visit(State &state, const LinearExtrudeNode &node) { if (state.isPrefix() && isCached(node)) return PruneTraversal; if (state.isPostfix()) { - shared_ptr geom(applyToChildren(node, CGE_UNION)); + shared_ptr geom(applyToChildren(node, OPENSCAD_UNION)); shared_ptr polygons = dynamic_pointer_cast(geom); assert(polygons); Geometry *extruded = extrudePolygon(node, *polygons); @@ -322,6 +360,67 @@ Response GeometryEvaluator::visit(State &state, const LinearExtrudeNode &node) return ContinueTraversal; } +static void fill_ring(std::vector &ring, const Outline2d &o, double a) +{ + for (int i=0;iconvexity = node.convexity; + + BOOST_FOREACH(const Outline2d &o, poly.outlines()) { + double max_x = 0; + BOOST_FOREACH(const Vector2d &v, o) max_x = fmax(max_x, v[0]); + int fragments = get_fragments_from_r(max_x, node.fn, node.fs, node.fa); + + std::vector rings[2]; + rings[0].reserve(o.size()); + rings[1].reserve(o.size()); + + fill_ring(rings[0], o, -M_PI/2); // first ring + for (int j = 0; j <= fragments; j++) { + double a = ((j+1)*2*M_PI) / fragments - M_PI/2; // start on the X axis + fill_ring(rings[(j+1)%2], o, a); + + for (size_t i=0;iappend_poly(); + ps->insert_vertex(rings[j%2][i]); + ps->insert_vertex(rings[(j+1)%2][(i+1)%o.size()]); + ps->insert_vertex(rings[j%2][(i+1)%o.size()]); + ps->append_poly(); + ps->insert_vertex(rings[j%2][i]); + ps->insert_vertex(rings[(j+1)%2][i]); + ps->insert_vertex(rings[(j+1)%2][(i+1)%o.size()]); + } + } + } + return ps; +} + +Response GeometryEvaluator::visit(State &state, const RotateExtrudeNode &node) +{ + if (state.isPrefix() && isCached(node)) return PruneTraversal; + if (state.isPostfix()) { + shared_ptr geom(applyToChildren(node, OPENSCAD_UNION)); + shared_ptr polygons = dynamic_pointer_cast(geom); + assert(polygons); + Geometry *rotated = rotatePolygon(node, *polygons); + assert(rotated); + addToParent(state, node, shared_ptr(rotated)); + } + return ContinueTraversal; +} + /*! Handles non-leaf PolyNodes; extrusions, projection */ diff --git a/src/GeometryEvaluator.h b/src/GeometryEvaluator.h index b77ccbd1..5cedf6a6 100644 --- a/src/GeometryEvaluator.h +++ b/src/GeometryEvaluator.h @@ -21,8 +21,10 @@ public: virtual Response visit(State &state, const AbstractNode &node); virtual Response visit(State &state, const AbstractPolyNode &node); virtual Response visit(State &state, const LinearExtrudeNode &node); + virtual Response visit(State &state, const RotateExtrudeNode &node); virtual Response visit(State &state, const LeafNode &node); virtual Response visit(State &state, const TransformNode &node); + virtual Response visit(State &state, const CsgNode &node); const Tree &getTree() const { return this->tree; } diff --git a/src/Polygon2d.h b/src/Polygon2d.h index d13e1173..8ef2d3af 100644 --- a/src/Polygon2d.h +++ b/src/Polygon2d.h @@ -7,7 +7,6 @@ typedef std::vector Outline2d; - class Polygon2d : public Geometry { public: diff --git a/src/csgnode.h b/src/csgnode.h index 2e1d9fbd..06b00778 100644 --- a/src/csgnode.h +++ b/src/csgnode.h @@ -3,18 +3,13 @@ #include "node.h" #include "visitor.h" - -enum csg_type_e { - CSG_TYPE_UNION, - CSG_TYPE_DIFFERENCE, - CSG_TYPE_INTERSECTION -}; +#include "enums.h" class CsgNode : public AbstractNode { public: - csg_type_e type; - CsgNode(const ModuleInstantiation *mi, csg_type_e type) : AbstractNode(mi), type(type) { } + OpenSCADOperator type; + CsgNode(const ModuleInstantiation *mi, OpenSCADOperator type) : AbstractNode(mi), type(type) { } virtual Response accept(class State &state, Visitor &visitor) const { return visitor.visit(state, *this); } diff --git a/src/csgops.cc b/src/csgops.cc index 8ac1d4f7..28d15157 100644 --- a/src/csgops.cc +++ b/src/csgops.cc @@ -36,8 +36,8 @@ class CsgModule : public AbstractModule { public: - csg_type_e type; - CsgModule(csg_type_e type) : type(type) { } + OpenSCADOperator type; + CsgModule(OpenSCADOperator type) : type(type) { } virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const; }; @@ -57,13 +57,13 @@ std::string CsgNode::toString() const std::string CsgNode::name() const { switch (this->type) { - case CSG_TYPE_UNION: + case OPENSCAD_UNION: return "union"; break; - case CSG_TYPE_DIFFERENCE: + case OPENSCAD_DIFFERENCE: return "difference"; break; - case CSG_TYPE_INTERSECTION: + case OPENSCAD_INTERSECTION: return "intersection"; break; default: @@ -74,8 +74,8 @@ std::string CsgNode::name() const void register_builtin_csgops() { - Builtins::init("union", new CsgModule(CSG_TYPE_UNION)); - Builtins::init("difference", new CsgModule(CSG_TYPE_DIFFERENCE)); - Builtins::init("intersection", new CsgModule(CSG_TYPE_INTERSECTION)); + Builtins::init("union", new CsgModule(OPENSCAD_UNION)); + Builtins::init("difference", new CsgModule(OPENSCAD_DIFFERENCE)); + Builtins::init("intersection", new CsgModule(OPENSCAD_INTERSECTION)); } diff --git a/src/enums.h b/src/enums.h index d61079d1..339f0d05 100644 --- a/src/enums.h +++ b/src/enums.h @@ -2,10 +2,10 @@ #define ENUMS_H_ enum OpenSCADOperator { - CGE_UNION, - CGE_INTERSECTION, - CGE_DIFFERENCE, - CGE_MINKOWSKI + OPENSCAD_UNION, + OPENSCAD_INTERSECTION, + OPENSCAD_DIFFERENCE, + OPENSCAD_MINKOWSKI }; #endif diff --git a/src/polyset.cc b/src/polyset.cc index 608977f8..f2aa1f6b 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -88,14 +88,24 @@ void PolySet::append_poly() void PolySet::append_vertex(double x, double y, double z) { - grid.align(x, y, z); - polygons.back().push_back(Vector3d(x, y, z)); + append_vertex(Vector3d(x, y, z)); +} + +void PolySet::append_vertex(Vector3d v) +{ + grid.align(v[0], v[1], v[2]); + polygons.back().push_back(v); } void PolySet::insert_vertex(double x, double y, double z) { - grid.align(x, y, z); - polygons.back().insert(polygons.back().begin(), Vector3d(x, y, z)); + insert_vertex(Vector3d(x, y, z)); +} + +void PolySet::insert_vertex(Vector3d v) +{ + grid.align(v[0], v[1], v[2]); + polygons.back().insert(polygons.back().begin(), v); } static void gl_draw_triangle(GLint *shaderinfo, const Vector3d &p0, const Vector3d &p1, const Vector3d &p2, bool e0, bool e1, bool e2, double z, bool mirrored) diff --git a/src/polyset.h b/src/polyset.h index eca12270..c6f16bdc 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -32,7 +32,9 @@ public: bool empty() const { return polygons.size() == 0; } void append_poly(); void append_vertex(double x, double y, double z = 0.0); + void append_vertex(Vector3d v); void insert_vertex(double x, double y, double z = 0.0); + void insert_vertex(Vector3d v); void append(const PolySet &ps); void render_surface(Renderer::csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo = NULL) const; diff --git a/tests/cgalcachetest.cc b/tests/cgalcachetest.cc index 67d33135..1c74ba5f 100644 --- a/tests/cgalcachetest.cc +++ b/tests/cgalcachetest.cc @@ -36,6 +36,7 @@ #include "builtin.h" #include "Tree.h" #include "CGAL_Nef_polyhedron.h" +#include "GeometryEvaluator.h" #include "CGALEvaluator.h" #include "PolySetCGALEvaluator.h" #include "CGALCache.h" @@ -59,15 +60,6 @@ std::string currentdir; using std::string; -void cgalTree(Tree &tree) -{ - assert(tree.root()); - - CGALEvaluator evaluator(tree); - Traverser evaluate(evaluator, *tree.root(), Traverser::PRE_AND_POSTFIX); - evaluate.execute(); -} - po::variables_map parse_options(int argc, char *argv[]) { po::options_description desc("Allowed options"); @@ -152,15 +144,14 @@ int main(int argc, char **argv) Tree tree(root_node); - CGALEvaluator cgalevaluator(tree); - PolySetCGALEvaluator psevaluator(cgalevaluator); + GeometryEvaluator geomevaluator(tree); print_messages_push(); std::cout << "First evaluation:\n"; - CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node); + CGAL_Nef_polyhedron N = geomevaluator.cgalevaluator->evaluateCGALMesh(*root_node); std::cout << "Second evaluation:\n"; - CGAL_Nef_polyhedron N2 = cgalevaluator.evaluateCGALMesh(*root_node); + CGAL_Nef_polyhedron N2 = geomevaluator.cgalevaluator->evaluateCGALMesh(*root_node); // FIXME: // Evaluate again to make cache kick in // Record printed output and compare it