diff options
| author | Marius Kintel <marius@kintel.net> | 2010-03-30 20:49:33 (GMT) | 
|---|---|---|
| committer | Marius Kintel <marius@kintel.net> | 2010-10-31 00:42:35 (GMT) | 
| commit | 398571275e58b4b17963db1d318dc4155d219da4 (patch) | |
| tree | f16cba0dd90a2c66725f700e51644068981c2728 /test-code | |
| parent | 8e9fc2cabc4d0218534bb9d75c2fa70deb0d9616 (diff) | |
Compile fixes for test programs
Diffstat (limited to 'test-code')
| -rw-r--r-- | test-code/CSGTextRenderer.cc | 286 | ||||
| -rw-r--r-- | test-code/CSGTextRenderer.h | 48 | 
2 files changed, 334 insertions, 0 deletions
| diff --git a/test-code/CSGTextRenderer.cc b/test-code/CSGTextRenderer.cc new file mode 100644 index 0000000..a366fb7 --- /dev/null +++ b/test-code/CSGTextRenderer.cc @@ -0,0 +1,286 @@ +#include "CSGTextRenderer.h" +#include <string> +#include <map> +#include <list> +#include "visitor.h" +#include "state.h" +#include "nodecache.h" +#include "module.h" // FIXME: Temporarily for ModuleInstantiation + +#include "csgnode.h" +#include "transformnode.h" + +#include <sstream> +#include <iostream> +#include <assert.h> +#include <QRegExp> + +string CSGTextRenderer::getCGALMesh() const +{ +	assert(this->root);  +	// FIXME: assert that cache contains root +	return this->cache[mk_cache_id(*this->root)]; +} + +// CGAL_Nef_polyhedron CSGTextRenderer::getCGALMesh() const +// { +// 	assert(this->root);  +// // FIXME: assert that cache contains root +// 	return this->cache[*this->root]; +// } + +bool CSGTextRenderer::isCached(const AbstractNode &node) +{ +	return this->cache.contains(mk_cache_id(node)); +} + +/*! +	Modifies target by applying op to target and src: +	target = target [op] src + */ +void +CSGTextRenderer::process(string &target, const string &src, CSGTextRenderer::CsgOp op) +{ +// 	if (target.dim != 2 && target.dim != 3) { +// 		assert(false && "Dimension of Nef polyhedron must be 2 or 3"); +// 	} + +	switch (op) { +	case UNION: +		target += "+" + src; +		break; +	case INTERSECTION: +		target += "*" + src; +		break; +	case DIFFERENCE: +		target += "-" + src; +		break; +	case MINKOWSKI: +		target += "M" + src; +		break; +	} +} + +// /*! +// 	Modifies target by applying op to target and src: +// 	target = target [op] src +//  */ +// void process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, CsgOp op) +// { +// 	if (target.dim == 2) { +// 		switch (op) { +// 		case UNION: +// 			target.p2 += src.p2; +// 			break; +// 		case INTERSECTION: +// 			target.p2 *= src.p2; +// 			break; +// 		case DIFFERENCE: +// 			target.p2 -= src.p2; +// 			break; +// 		case MINKOWSKI: +// 			target.p2 = minkowski2(target.p2, src.p2); +// 			break; +// 		} +// 	} +// 	else if (target.dim == 3) { +// 		switch (op) { +// 		case UNION: +// 			target.p3 += src.p3; +// 			break; +// 		case INTERSECTION: +// 			target.p3 *= src.p3; +// 			break; +// 		case DIFFERENCE: +// 			target.p3 -= src.p3; +// 			break; +// 		case MINKOWSKI: +// 			target.p3 = minkowski3(target.p3, src.p3); +// 			break; +// 		} +// 	} +// 	else { +// 		assert(false && "Dimention of Nef polyhedron must be 2 or 3"); +// 	} +// } + +void CSGTextRenderer::applyToChildren(const AbstractNode &node, CSGTextRenderer::CsgOp op) +{ +	std::stringstream stream; +	stream << typeid(node).name(); +	stream << "<" << node.index() << ">"; +	string N = stream.str(); +	if (this->visitedchildren[node.index()].size() > 0) { +		// FIXME: assert that cache contains nodes in code below +		bool first = true; +//		CGAL_Nef_polyhedron N; +		for (ChildList::const_iterator iter = this->visitedchildren[node.index()].begin(); +				 iter != this->visitedchildren[node.index()].end(); +				 iter++) { +			const AbstractNode *chnode = iter->first; +			const QString &chcacheid = iter->second; +			// FIXME: Don't use deep access to modinst members +			if (chnode->modinst->tag_background) continue; +			if (first) { +				N += "(" + this->cache[chcacheid]; +// 				if (N.dim != 0) first = false; // FIXME: when can this happen? +				first = false; +			} else { +				process(N, this->cache[chcacheid], op); +			} +			chnode->progress_report(); +		} +		N += ")"; +	} +	QString cacheid = mk_cache_id(node); +	this->cache.insert(cacheid, N); +} + +/* +	Typical visitor behavior: +	o In prefix: Check if we're cached -> prune +	o In postfix: Check if we're cached -> don't apply operator to children +	o In postfix: addToParent() + */ + +Response CSGTextRenderer::visit(const State &state, const AbstractNode &node) +{ +	if (state.isPrefix() && isCached(node)) return PruneTraversal; +	if (state.isPostfix()) { +		if (!isCached(node)) applyToChildren(node, UNION); +		addToParent(state, node); +	} +	return ContinueTraversal; +} + +Response CSGTextRenderer::visit(const State &state, const AbstractIntersectionNode &node) +{ +	if (state.isPrefix() && isCached(node)) return PruneTraversal; +	if (state.isPostfix()) { +		if (!isCached(node)) applyToChildren(node, INTERSECTION); +		addToParent(state, node); +	} +	return ContinueTraversal; +} + +Response CSGTextRenderer::visit(const State &state, const CsgNode &node) +{ +	if (state.isPrefix() && isCached(node)) return PruneTraversal; +	if (state.isPostfix()) { +		if (!isCached(node)) { +			CsgOp op; +			switch (node.type) { +			case CSG_TYPE_UNION: +				op = UNION; +				break; +			case CSG_TYPE_DIFFERENCE: +				op = DIFFERENCE; +				break; +			case CSG_TYPE_INTERSECTION: +				op = INTERSECTION; +				break; +			} +			applyToChildren(node, op); +		} +		addToParent(state, node); +	} +	return ContinueTraversal; +} + +Response CSGTextRenderer::visit(const State &state, const TransformNode &node) +{ +	if (state.isPrefix() && isCached(node)) return PruneTraversal; +	if (state.isPostfix()) { +		if (!isCached(node)) { +			// First union all children +			applyToChildren(node, UNION); +			// FIXME: Then apply transform +		} +		addToParent(state, node); +	} +	return ContinueTraversal; +} + +// FIXME: RenderNode: Union over children + some magic +// FIXME: CgaladvNode: Iterate over children. Special operation + +// FIXME: Subtypes of AbstractPolyNode: +// ProjectionNode +// DxfLinearExtrudeNode +// DxfRotateExtrudeNode +// (SurfaceNode) +// (PrimitiveNode) +Response CSGTextRenderer::visit(const State &state, const AbstractPolyNode &node) +{ +	if (state.isPrefix() && isCached(node)) return PruneTraversal; +	if (state.isPostfix()) { +		if (!isCached(node)) { + +	// FIXME: Manage caching +	// FIXME: Will generate one single Nef polyhedron (no csg ops necessary) +  +// 	PolySet *ps = render_polyset(RENDER_CGAL); +// 	try { +// 		CGAL_Nef_polyhedron N = ps->renderCSGMesh(); +// 		cgal_nef_cache.insert(cache_id, new cgal_nef_cache_entry(N), N.weight()); +// 		print_messages_pop(); +// 		progress_report(); +		 +// 		ps->unlink(); +// 		return N; +// 	} +// 	catch (...) { // Don't leak the PolySet on ProgressCancelException +// 		ps->unlink(); +// 		throw; +// 	} + +			string N = typeid(node).name(); +			QString cacheid = mk_cache_id(node); +			this->cache.insert(cacheid, N); +		 +// 		std::cout << "Insert: " << N << "\n"; +// 		std::cout << "Node: " << cacheid.toStdString() << "\n\n"; +		} +		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. +*/ +void CSGTextRenderer::addToParent(const State &state, const AbstractNode &node) +{ +	assert(state.isPostfix()); +	QString cacheid = mk_cache_id(node); +	this->visitedchildren.erase(node.index()); +	if (!state.parent()) { +		this->root = &node; +	} +	else { +		this->visitedchildren[state.parent()->index()].push_back(std::make_pair(&node, cacheid)); +	} +} + +/*! +  Create a cache id of the entire tree under this node. This cache id +	is a non-whitespace plaintext of the evaluated scad tree and is used +	for lookup in cgal_nef_cache. +*/ +QString CSGTextRenderer::mk_cache_id(const AbstractNode &node) const +{ +	// FIXME: should we keep a cache of cache_id's to avoid recalculating this? +	// -> check how often we recalculate it. + +	// FIXME: Get dump from dump cache +	// FIXME: assert that cache contains node +	QString cache_id = QString::fromStdString(this->dumpcache[node]); +	// Remove all node indices and whitespace +	cache_id.remove(QRegExp("[a-zA-Z_][a-zA-Z_0-9]*:")); +	cache_id.remove(' '); +	cache_id.remove('\t'); +	cache_id.remove('\n'); +	return cache_id; +} diff --git a/test-code/CSGTextRenderer.h b/test-code/CSGTextRenderer.h new file mode 100644 index 0000000..84f3d30 --- /dev/null +++ b/test-code/CSGTextRenderer.h @@ -0,0 +1,48 @@ +#ifndef CSGTEXTRENDERER_H_ +#define CSGTEXTRENDERER_H_ + +#include <string> +#include <map> +#include <list> +#include "visitor.h" +#include "nodecache.h" + +using std::string; +using std::map; +using std::list; +using std::pair; + +class CSGTextRenderer : public Visitor +{ +public: +	enum CsgOp {UNION, INTERSECTION, DIFFERENCE, MINKOWSKI}; +	CSGTextRenderer(const NodeCache<string> &dumpcache) : root(NULL), dumpcache(dumpcache) {} +  virtual ~CSGTextRenderer() {} + +  virtual Response visit(const State &state, const AbstractNode &node); +	virtual Response visit(const State &state, const AbstractIntersectionNode &node); +	virtual Response visit(const State &state, const CsgNode &node); +	virtual Response visit(const State &state, const TransformNode &node); +	virtual Response visit(const State &state, const AbstractPolyNode &node); + +	string getCGALMesh() const; +// 	CGAL_Nef_polyhedron getCGALMesh() const; +private: +  void addToParent(const State &state, const AbstractNode &node); +  bool isCached(const AbstractNode &node); +	QString mk_cache_id(const AbstractNode &node) const; +	void process(string &target, const string &src, CSGTextRenderer::CsgOp op); +	void applyToChildren(const AbstractNode &node, CSGTextRenderer::CsgOp op); + +  string currindent; +  const AbstractNode *root; +  typedef list<pair<const AbstractNode *, QString> > ChildList; +  map<int, ChildList> visitedchildren; +//	hashmap<string, CGAL_Nef_polyhedron> cache; + +  // For now use strings instead of Nef polyhedrons for testing caching +	QHash<QString, string> cache; +	const NodeCache<string> &dumpcache; +}; + +#endif | 
