diff options
| -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; | 
