diff options
author | Marius Kintel <marius@kintel.net> | 2011-09-06 12:57:24 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2011-09-06 12:57:24 (GMT) |
commit | 1e4e18c52451d2f04050cb44441b615398882c56 (patch) | |
tree | 0fc51c818db83632e983c0720d1e497c83fedb01 | |
parent | fdd96a177c0fb3a94d317cb3e584b4881c09ea0e (diff) |
minkowski sums should now work again
-rw-r--r-- | openscad.pro | 1 | ||||
-rw-r--r-- | src/CGALEvaluator.cc | 38 | ||||
-rw-r--r-- | src/CGALEvaluator.h | 1 | ||||
-rw-r--r-- | src/CGAL_Nef_polyhedron.cc | 72 | ||||
-rw-r--r-- | src/CSGTermEvaluator.cc | 23 | ||||
-rw-r--r-- | src/CSGTermEvaluator.h | 1 | ||||
-rw-r--r-- | src/PolySetCGALEvaluator.cc | 10 | ||||
-rw-r--r-- | src/PolySetCGALEvaluator.h | 1 | ||||
-rw-r--r-- | src/PolySetEvaluator.h | 1 | ||||
-rw-r--r-- | src/cgaladv.cc | 66 |
10 files changed, 129 insertions, 85 deletions
diff --git a/openscad.pro b/openscad.pro index d3923e5..a7dd59e 100644 --- a/openscad.pro +++ b/openscad.pro @@ -142,6 +142,7 @@ HEADERS += src/renderer.h \ src/dxflinextrudenode.h \ src/dxfrotextrudenode.h \ src/projectionnode.h \ + src/cgaladvnode.h \ src/importnode.h \ src/transformnode.h \ src/colornode.h \ diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index f4765a3..0d67152 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -5,6 +5,7 @@ #include "printutils.h" #include "csgnode.h" +#include "cgaladvnode.h" #include "transformnode.h" #include "polyset.h" #include "dxfdata.h" @@ -47,7 +48,7 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr assert(false && "Dimension of Nef polyhedron must be 2 or 3"); } if (src.empty()) return; // Empty polyhedron. This can happen for e.g. square([0,0]) - assert(target.dim == src.dim); + if (target.dim != src.dim) return; // If someone tries to e.g. union 2d and 3d objects switch (op) { case CGE_UNION: @@ -203,14 +204,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) } // FIXME: EvaluateNode: Union over children + some magic -// FIXME: CgaladvNode: Iterate over children. Special operation - -// FIXME: Subtypes of AbstractPolyNode: -// ProjectionNode -// DxfLinearExtrudeNode -// DxfRotateExtrudeNode -// (SurfaceNode) -// (PrimitiveNode) + Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) { if (state.isPrefix() && isCached(node)) return PruneTraversal; @@ -242,6 +236,32 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) return ContinueTraversal; } +Response CGALEvaluator::visit(State &state, const CgaladvNode &node) +{ + if (state.isPrefix() && isCached(node)) return PruneTraversal; + if (state.isPostfix()) { + if (!isCached(node)) { + CGALEvaluator::CsgOp op; + switch (node.type) { + case MINKOWSKI: + op = CGE_MINKOWSKI; + break; + case GLIDE: + case SUBDIV: + // FIXME: Not implemented + return PruneTraversal; + break; + case HULL: + op = CGE_HULL; + break; + } + applyToChildren(node, op); + } + addToParent(state, node); + } + return ContinueTraversal; +} + /*! Adds ourself to out parent's list of traversed children. Call this for _every_ node which affects output during the postfix traversal. diff --git a/src/CGALEvaluator.h b/src/CGALEvaluator.h index 8af64e3..a985065 100644 --- a/src/CGALEvaluator.h +++ b/src/CGALEvaluator.h @@ -29,6 +29,7 @@ public: virtual Response visit(State &state, const CsgNode &node); virtual Response visit(State &state, const TransformNode &node); virtual Response visit(State &state, const AbstractPolyNode &node); + virtual Response visit(State &state, const CgaladvNode &node); CGAL_Nef_polyhedron evaluateCGALMesh(const AbstractNode &node); CGAL_Nef_polyhedron evaluateCGALMesh(const PolySet &polyset); diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index 0c8c627..afe7119 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -1,6 +1,8 @@ #include "CGAL_Nef_polyhedron.h" #include "cgal.h" #include "polyset.h" +#include "dxfdata.h" +#include "dxftess.h" #include <CGAL/minkowski_sum_3.h> CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator+=(const CGAL_Nef_polyhedron &other) @@ -48,38 +50,48 @@ int CGAL_Nef_polyhedron::weight() const */ PolySet *CGAL_Nef_polyhedron::convertToPolyset() { + assert(!this->empty()); PolySet *ps = new PolySet(); - CGAL_Polyhedron P; - this->p3->convert_to_Polyhedron(P); - - typedef CGAL_Polyhedron::Vertex Vertex; - typedef CGAL_Polyhedron::Vertex_const_iterator VCI; - typedef CGAL_Polyhedron::Facet_const_iterator FCI; - typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; - - for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { - HFCC hc = fi->facet_begin(); - HFCC hc_end = hc; - Vertex v1, v2, v3; - v1 = *VCI((hc++)->vertex()); - v3 = *VCI((hc++)->vertex()); - do { - v2 = v3; + if (this->dim == 2) { + DxfData *dd = this->convertToDxfData(); + ps->is2d = true; + dxf_tesselate(ps, *dd, 0, true, false, 0); + dxf_border_to_ps(ps, *dd); + delete dd; + } + else if (this->dim == 3) { + CGAL_Polyhedron P; + this->p3->convert_to_Polyhedron(P); + + typedef CGAL_Polyhedron::Vertex Vertex; + typedef CGAL_Polyhedron::Vertex_const_iterator VCI; + typedef CGAL_Polyhedron::Facet_const_iterator FCI; + typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; + + for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { + HFCC hc = fi->facet_begin(); + HFCC hc_end = hc; + Vertex v1, v2, v3; + v1 = *VCI((hc++)->vertex()); v3 = *VCI((hc++)->vertex()); - double x1 = CGAL::to_double(v1.point().x()); - double y1 = CGAL::to_double(v1.point().y()); - double z1 = CGAL::to_double(v1.point().z()); - double x2 = CGAL::to_double(v2.point().x()); - double y2 = CGAL::to_double(v2.point().y()); - double z2 = CGAL::to_double(v2.point().z()); - double x3 = CGAL::to_double(v3.point().x()); - double y3 = CGAL::to_double(v3.point().y()); - double z3 = CGAL::to_double(v3.point().z()); - ps->append_poly(); - ps->append_vertex(x1, y1, z1); - ps->append_vertex(x2, y2, z2); - ps->append_vertex(x3, y3, z3); - } while (hc != hc_end); + do { + v2 = v3; + v3 = *VCI((hc++)->vertex()); + double x1 = CGAL::to_double(v1.point().x()); + double y1 = CGAL::to_double(v1.point().y()); + double z1 = CGAL::to_double(v1.point().z()); + double x2 = CGAL::to_double(v2.point().x()); + double y2 = CGAL::to_double(v2.point().y()); + double z2 = CGAL::to_double(v2.point().z()); + double x3 = CGAL::to_double(v3.point().x()); + double y3 = CGAL::to_double(v3.point().y()); + double z3 = CGAL::to_double(v3.point().z()); + ps->append_poly(); + ps->append_vertex(x1, y1, z1); + ps->append_vertex(x2, y2, z2); + ps->append_vertex(x3, y3, z3); + } while (hc != hc_end); + } } return ps; } diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index b75babe..b59f4db 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -7,7 +7,9 @@ #include "transformnode.h" #include "colornode.h" #include "rendernode.h" +#include "cgaladvnode.h" #include "printutils.h" +#include "PolySetEvaluator.h" #include <string> #include <map> @@ -88,7 +90,7 @@ static CSGTerm *evaluate_csg_term_from_ps(const State &state, vector<CSGTerm*> &background, PolySet *ps, const ModuleInstantiation *modinst, - const AbstractPolyNode &node) + const AbstractNode &node) { std::stringstream stream; stream << node.name() << node.index(); @@ -184,6 +186,25 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node) return ContinueTraversal; } +Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node) +{ + if (state.isPostfix()) { + CSGTerm *t1 = NULL; + // FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this. + PolySet *ps = NULL; + if (this->psevaluator) { + ps = this->psevaluator->evaluatePolySet(node, AbstractPolyNode::RENDER_OPENCSG); + } + if (ps) { + t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, + ps, node.modinst, node); + } + this->stored_term[node.index()] = t1; + addToParent(state, node); + } + return ContinueTraversal; +} + /*! Adds ourself to out parent's list of traversed children. Call this for _every_ node which affects output during the postfix traversal. diff --git a/src/CSGTermEvaluator.h b/src/CSGTermEvaluator.h index 6bff7f5..ac22906 100644 --- a/src/CSGTermEvaluator.h +++ b/src/CSGTermEvaluator.h @@ -29,6 +29,7 @@ public: virtual Response visit(State &state, const TransformNode &node); virtual Response visit(State &state, const ColorNode &node); virtual Response visit(State &state, const RenderNode &node); + virtual Response visit(State &state, const CgaladvNode &node); class CSGTerm *evaluateCSGTerm(const AbstractNode &node, vector<CSGTerm*> &highlights, diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 8c5c2f9..c42d806 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -5,6 +5,7 @@ #include "projectionnode.h" #include "dxflinextrudenode.h" #include "dxfrotextrudenode.h" +#include "cgaladvnode.h" #include "dxfdata.h" #include "dxftess.h" #include "module.h" @@ -367,6 +368,15 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, return ps; } +PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e) +{ + CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node); + PolySet *ps = NULL; + if (!N.empty()) ps = N.convertToPolyset(); + return ps; +} + + PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, DxfData &dxf) { PolySet *ps = new PolySet(); diff --git a/src/PolySetCGALEvaluator.h b/src/PolySetCGALEvaluator.h index a39e4ff..cf3c5b2 100644 --- a/src/PolySetCGALEvaluator.h +++ b/src/PolySetCGALEvaluator.h @@ -16,6 +16,7 @@ public: virtual PolySet *evaluatePolySet(const ProjectionNode &node, AbstractPolyNode::render_mode_e); virtual PolySet *evaluatePolySet(const DxfLinearExtrudeNode &node, AbstractPolyNode::render_mode_e); virtual PolySet *evaluatePolySet(const DxfRotateExtrudeNode &node, AbstractPolyNode::render_mode_e); + virtual PolySet *evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e); protected: PolySet *extrudeDxfData(const DxfLinearExtrudeNode &node, class DxfData &dxf); diff --git a/src/PolySetEvaluator.h b/src/PolySetEvaluator.h index dcc67db..9a72ff7 100644 --- a/src/PolySetEvaluator.h +++ b/src/PolySetEvaluator.h @@ -16,6 +16,7 @@ public: virtual PolySet *evaluatePolySet(const class ProjectionNode &, AbstractPolyNode::render_mode_e) = 0; virtual PolySet *evaluatePolySet(const class DxfLinearExtrudeNode &, AbstractPolyNode::render_mode_e) = 0; virtual PolySet *evaluatePolySet(const class DxfRotateExtrudeNode &, AbstractPolyNode::render_mode_e) = 0; + virtual PolySet *evaluatePolySet(const class CgaladvNode &, AbstractPolyNode::render_mode_e) = 0; void clearCache() { this->cache.clear(); diff --git a/src/cgaladv.cc b/src/cgaladv.cc index 6c4c222..8ffd626 100644 --- a/src/cgaladv.cc +++ b/src/cgaladv.cc @@ -24,24 +24,16 @@ * */ +#include "cgaladvnode.h" #include "module.h" -#include "node.h" #include "context.h" #include "builtin.h" #include "printutils.h" -#include "visitor.h" #include <sstream> #include <assert.h> #include <boost/assign/std/vector.hpp> using namespace boost::assign; // bring 'operator+=()' into scope -enum cgaladv_type_e { - MINKOWSKI, - GLIDE, - SUBDIV, - HULL -}; - class CgaladvModule : public AbstractModule { public: @@ -50,42 +42,6 @@ public: virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; }; -class CgaladvNode : public AbstractNode -{ -public: - CgaladvNode(const ModuleInstantiation *mi, cgaladv_type_e type) : AbstractNode(mi), type(type) { - convexity = 1; - } - virtual ~CgaladvNode() { } - virtual Response accept(class State &state, Visitor &visitor) const { - return visitor.visit(state, *this); - } - virtual std::string toString() const; - virtual std::string name() const { - switch (this->type) { - case MINKOWSKI: - return "minkowski"; - break; - case GLIDE: - return "glide"; - break; - case SUBDIV: - return "subdiv"; - break; - case HULL: - return "hull"; - break; - default: - assert(false); - } - } - - Value path; - std::string subdiv_type; - int convexity, level; - cgaladv_type_e type; -}; - AbstractNode *CgaladvModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const { CgaladvNode *node = new CgaladvNode(inst, type); @@ -144,6 +100,26 @@ void register_builtin_cgaladv() builtin_modules["hull"] = new CgaladvModule(HULL); } +std::string CgaladvNode::name() const +{ + switch (this->type) { + case MINKOWSKI: + return "minkowski"; + break; + case GLIDE: + return "glide"; + break; + case SUBDIV: + return "subdiv"; + break; + case HULL: + return "hull"; + break; + default: + assert(false); + } +} + std::string CgaladvNode::toString() const { std::stringstream stream; |