Green refactoring, but uncertain if we should keep it

customizer
Marius Kintel 2013-03-27 17:50:25 -04:00
parent e6bfee021b
commit acd08b6f1a
36 changed files with 380 additions and 170 deletions

View File

@ -233,6 +233,8 @@ HEADERS += src/typedefs.h \
src/rendernode.h \
src/openscad.h \
src/handle_dep.h \
src/Geometry.h \
src/Polygon2d.h \
src/polyset.h \
src/printutils.h \
src/fileutils.h \
@ -245,7 +247,7 @@ HEADERS += src/typedefs.h \
src/nodecache.h \
src/nodedumper.h \
src/ModuleCache.h \
src/PolySetCache.h \
src/GeometryCache.h \
src/PolySetEvaluator.h \
src/CSGTermEvaluator.h \
src/Tree.h \
@ -286,6 +288,8 @@ SOURCES += src/version_check.cc \
src/evalcontext.cc \
src/csgterm.cc \
src/csgtermnormalizer.cc \
src/Geometry.cc \
src/Polygon2d.cc \
src/polyset.cc \
src/csgops.cc \
src/transform.cc \
@ -312,7 +316,7 @@ SOURCES += src/version_check.cc \
src/traverser.cc \
src/PolySetEvaluator.cc \
src/ModuleCache.cc \
src/PolySetCache.cc \
src/GeometryCache.cc \
src/Tree.cc \
\
src/rendersettings.cc \

View File

@ -353,12 +353,14 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node)
CGAL_Nef_polyhedron N;
if (!isCached(node)) {
// Apply polyset operation
shared_ptr<PolySet> ps = this->psevaluator.getPolySet(node, false);
shared_ptr<Geometry> geom = this->psevaluator.getGeometry(node, false);
shared_ptr<PolySet> ps = dynamic_pointer_cast<PolySet>(geom);
if (ps) {
N = evaluateCGALMesh(*ps);
// print_messages_pop();
node.progress_report();
}
// else FIXME: Support other Geometry instances
}
else {
N = CGALCache::instance()->get(this->tree.getIdString(node));

View File

@ -10,6 +10,7 @@
#include "cgaladvnode.h"
#include "printutils.h"
#include "PolySetEvaluator.h"
#include "polyset.h"
#include <string>
#include <map>
@ -111,8 +112,12 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node)
if (state.isPrefix()) {
shared_ptr<CSGTerm> t1;
if (this->psevaluator) {
shared_ptr<PolySet> ps = this->psevaluator->getPolySet(node, true);
if (ps) {
shared_ptr<Geometry> geom = this->psevaluator->getGeometry(node, true);
if (geom) {
shared_ptr<PolySet> ps = dynamic_pointer_cast<PolySet>(geom);
if (!ps) {
// FIXME: Convert geom to polyset. Refacting may resume here
}
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
ps, node.modinst, node);
node.progress_report();
@ -178,7 +183,8 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node)
shared_ptr<CSGTerm> t1;
shared_ptr<PolySet> ps;
if (this->psevaluator) {
ps = this->psevaluator->getPolySet(node, true);
shared_ptr<Geometry> geom = this->psevaluator->getGeometry(node, true);
ps = dynamic_pointer_cast<PolySet>(geom);
node.progress_report();
}
if (ps) {
@ -198,7 +204,8 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node)
// FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this.
shared_ptr<PolySet> ps;
if (this->psevaluator) {
ps = this->psevaluator->getPolySet(node, true);
shared_ptr<Geometry> geom = this->psevaluator->getGeometry(node, true);
ps = dynamic_pointer_cast<PolySet>(geom);
}
if (ps) {
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,

1
src/Geometry.cc Normal file
View File

@ -0,0 +1 @@
#include "Geometry.h"

16
src/Geometry.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef GEOMETRY_H_
#define GEOMETRY_H_
#include <stddef.h>
#include <string>
#include "linalg.h"
class Geometry
{
public:
virtual size_t memsize() const = 0;
virtual BoundingBox getBoundingBox() const = 0;
virtual std::string dump() const = 0;
};
#endif

31
src/GeometryCache.cc Normal file
View File

@ -0,0 +1,31 @@
#include "GeometryCache.h"
#include "printutils.h"
#include "geometry.h"
GeometryCache *GeometryCache::inst = NULL;
void GeometryCache::insert(const std::string &id, const shared_ptr<Geometry> &ps)
{
this->cache.insert(id, new cache_entry(ps), ps ? ps->memsize() : 0);
}
size_t GeometryCache::maxSize() const
{
return this->cache.maxCost();
}
void GeometryCache::setMaxSize(size_t limit)
{
this->cache.setMaxCost(limit);
}
void GeometryCache::print()
{
PRINTB("Geometrys in cache: %d", this->cache.size());
PRINTB("Geometry cache size in bytes: %d", this->cache.totalCost());
}
GeometryCache::cache_entry::cache_entry(const shared_ptr<Geometry> &ps) : ps(ps)
{
if (print_messages_stack.size() > 0) this->msg = print_messages_stack.back();
}

36
src/GeometryCache.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef GEOMETRYCACHE_H_
#define GEOMETRYCACHE_H_
#include "cache.h"
#include "memory.h"
#include "Geometry.h"
class GeometryCache
{
public:
GeometryCache(size_t memorylimit = 100*1024*1024) : cache(memorylimit) {}
static GeometryCache *instance() { if (!inst) inst = new GeometryCache; return inst; }
bool contains(const std::string &id) const { return this->cache.contains(id); }
shared_ptr<class Geometry> get(const std::string &id) const { return this->cache[id]->ps; }
void insert(const std::string &id, const shared_ptr<Geometry> &ps);
size_t maxSize() const;
void setMaxSize(size_t limit);
void clear() { cache.clear(); }
void print();
private:
static GeometryCache *inst;
struct cache_entry {
shared_ptr<class Geometry> ps;
std::string msg;
cache_entry(const shared_ptr<Geometry> &ps);
~cache_entry() { }
};
Cache<std::string, cache_entry> cache;
};
#endif

View File

@ -14,6 +14,7 @@
#include "dxftess.h"
#include "module.h"
#include "calc.h"
#include "polyset.h"
#include "svg.h"
#include "printutils.h"
@ -25,7 +26,7 @@ PolySetCGALEvaluator::PolySetCGALEvaluator(CGALEvaluator &cgalevaluator)
{
}
PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node)
Geometry *PolySetCGALEvaluator::evaluateGeometry(const ProjectionNode &node)
{
//openscad_loglevel = 6;
logstream log(5);
@ -286,14 +287,14 @@ static void add_slice(PolySet *ps, const DxfData &dxf, DxfData::Path &path,
}
}
PolySet *PolySetCGALEvaluator::evaluatePolySet(const LinearExtrudeNode &node)
Geometry *PolySetCGALEvaluator::evaluateGeometry(const LinearExtrudeNode &node)
{
DxfData *dxf;
if (node.filename.empty())
{
// Before extruding, union all (2D) children nodes
// to a single DxfData, then tesselate this into a PolySet
// to a single DxfData, then tesselate this into a Geometry
CGAL_Nef_polyhedron sum;
BOOST_FOREACH (AbstractNode * v, node.getChildren()) {
if (v->modinst->isBackground()) continue;
@ -315,12 +316,12 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const LinearExtrudeNode &node)
dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale_x);
}
PolySet *ps = extrudeDxfData(node, *dxf);
Geometry *geom = extrudeDxfData(node, *dxf);
delete dxf;
return ps;
return geom;
}
PolySet *PolySetCGALEvaluator::extrudeDxfData(const LinearExtrudeNode &node, DxfData &dxf)
Geometry *PolySetCGALEvaluator::extrudeDxfData(const LinearExtrudeNode &node, DxfData &dxf)
{
PolySet *ps = new PolySet();
ps->convexity = node.convexity;
@ -386,7 +387,7 @@ PolySet *PolySetCGALEvaluator::extrudeDxfData(const LinearExtrudeNode &node, Dxf
return ps;
}
PolySet *PolySetCGALEvaluator::evaluatePolySet(const RotateExtrudeNode &node)
Geometry *PolySetCGALEvaluator::evaluateGeometry(const RotateExtrudeNode &node)
{
DxfData *dxf;
@ -415,12 +416,12 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const RotateExtrudeNode &node)
dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale);
}
PolySet *ps = rotateDxfData(node, *dxf);
Geometry *geom = rotateDxfData(node, *dxf);
delete dxf;
return ps;
return geom;
}
PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node)
Geometry *PolySetCGALEvaluator::evaluateGeometry(const CgaladvNode &node)
{
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node);
PolySet *ps = NULL;
@ -432,7 +433,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node)
return ps;
}
PolySet *PolySetCGALEvaluator::evaluatePolySet(const RenderNode &node)
Geometry *PolySetCGALEvaluator::evaluateGeometry(const RenderNode &node)
{
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node);
PolySet *ps = NULL;
@ -448,7 +449,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const RenderNode &node)
return ps;
}
PolySet *PolySetCGALEvaluator::rotateDxfData(const RotateExtrudeNode &node, DxfData &dxf)
Geometry *PolySetCGALEvaluator::rotateDxfData(const RotateExtrudeNode &node, DxfData &dxf)
{
PolySet *ps = new PolySet();
ps->convexity = node.convexity;

View File

@ -4,23 +4,23 @@
#include "PolySetEvaluator.h"
/*!
This is a PolySet evaluator which uses the CGALEvaluator to support building
polysets.
This is a Geometry evaluator which uses the CGALEvaluator to support building
geometrys.
*/
class PolySetCGALEvaluator : public PolySetEvaluator
{
public:
PolySetCGALEvaluator(class CGALEvaluator &cgalevaluator);
virtual ~PolySetCGALEvaluator() { }
virtual PolySet *evaluatePolySet(const ProjectionNode &node);
virtual PolySet *evaluatePolySet(const LinearExtrudeNode &node);
virtual PolySet *evaluatePolySet(const RotateExtrudeNode &node);
virtual PolySet *evaluatePolySet(const CgaladvNode &node);
virtual PolySet *evaluatePolySet(const RenderNode &node);
virtual Geometry *evaluateGeometry(const ProjectionNode &node);
virtual Geometry *evaluateGeometry(const LinearExtrudeNode &node);
virtual Geometry *evaluateGeometry(const RotateExtrudeNode &node);
virtual Geometry *evaluateGeometry(const CgaladvNode &node);
virtual Geometry *evaluateGeometry(const RenderNode &node);
bool debug;
protected:
PolySet *extrudeDxfData(const LinearExtrudeNode &node, class DxfData &dxf);
PolySet *rotateDxfData(const RotateExtrudeNode &node, class DxfData &dxf);
Geometry *extrudeDxfData(const LinearExtrudeNode &node, class DxfData &dxf);
Geometry *rotateDxfData(const RotateExtrudeNode &node, class DxfData &dxf);
CGALEvaluator &cgalevaluator;
};

View File

@ -1,31 +0,0 @@
#include "PolySetCache.h"
#include "printutils.h"
#include "polyset.h"
PolySetCache *PolySetCache::inst = NULL;
void PolySetCache::insert(const std::string &id, const shared_ptr<PolySet> &ps)
{
this->cache.insert(id, new cache_entry(ps), ps ? ps->memsize() : 0);
}
size_t PolySetCache::maxSize() const
{
return this->cache.maxCost();
}
void PolySetCache::setMaxSize(size_t limit)
{
this->cache.setMaxCost(limit);
}
void PolySetCache::print()
{
PRINTB("PolySets in cache: %d", this->cache.size());
PRINTB("PolySet cache size in bytes: %d", this->cache.totalCost());
}
PolySetCache::cache_entry::cache_entry(const shared_ptr<PolySet> &ps) : ps(ps)
{
if (print_messages_stack.size() > 0) this->msg = print_messages_stack.back();
}

View File

@ -1,35 +0,0 @@
#ifndef POLYSETCACHE_H_
#define POLYSETCACHE_H_
#include "cache.h"
#include "memory.h"
class PolySetCache
{
public:
PolySetCache(size_t memorylimit = 100*1024*1024) : cache(memorylimit) {}
static PolySetCache *instance() { if (!inst) inst = new PolySetCache; return inst; }
bool contains(const std::string &id) const { return this->cache.contains(id); }
shared_ptr<class PolySet> get(const std::string &id) const { return this->cache[id]->ps; }
void insert(const std::string &id, const shared_ptr<PolySet> &ps);
size_t maxSize() const;
void setMaxSize(size_t limit);
void clear() { cache.clear(); }
void print();
private:
static PolySetCache *inst;
struct cache_entry {
shared_ptr<class PolySet> ps;
std::string msg;
cache_entry(const shared_ptr<PolySet> &ps);
~cache_entry() { }
};
Cache<std::string, cache_entry> cache;
};
#endif

View File

@ -1,35 +1,35 @@
#include "PolySetCache.h"
#include "GeometryCache.h"
#include "PolySetEvaluator.h"
#include "printutils.h"
#include "polyset.h"
#include "Tree.h"
/*!
The task of PolySetEvaluator is to create, keep track of and cache PolySet instances.
The task of PolySetEvaluator is to create, keep track of and cache Geometry instances.
All instances of PolySet which are not strictly temporary should be
All instances of Geometry which are not strictly temporary should be
requested through this class.
*/
/*!
Factory method returning a PolySet from the given node. If the
node is already cached, the cached PolySet will be returned
otherwise a new PolySet will be created from the node. If cache is
true, the newly created PolySet will be cached.
Factory method returning a Geometry from the given node. If the
node is already cached, the cached Geometry will be returned
otherwise a new Geometry will be created from the node. If cache is
true, the newly created Geometry will be cached.
*/
shared_ptr<PolySet> PolySetEvaluator::getPolySet(const AbstractNode &node, bool cache)
shared_ptr<Geometry> PolySetEvaluator::getGeometry(const AbstractNode &node, bool cache)
{
std::string cacheid = this->tree.getIdString(node);
if (PolySetCache::instance()->contains(cacheid)) {
if (GeometryCache::instance()->contains(cacheid)) {
#ifdef DEBUG
// For cache debugging
PRINTB("PolySetCache hit: %s", cacheid.substr(0, 40));
PRINTB("GeometryCache hit: %s", cacheid.substr(0, 40));
#endif
return PolySetCache::instance()->get(cacheid);
return GeometryCache::instance()->get(cacheid);
}
shared_ptr<PolySet> ps(node.evaluate_polyset(this));
if (cache) PolySetCache::instance()->insert(cacheid, ps);
return ps;
shared_ptr<Geometry> geom(node.evaluate_geometry(this));
if (cache) GeometryCache::instance()->insert(cacheid, geom);
return geom;
}

View File

@ -11,13 +11,13 @@ public:
const Tree &getTree() const { return this->tree; }
virtual shared_ptr<class PolySet> getPolySet(const class AbstractNode &, bool cache);
virtual shared_ptr<class Geometry> getGeometry(const class AbstractNode &, bool cache);
virtual PolySet *evaluatePolySet(const class ProjectionNode &) { return NULL; }
virtual PolySet *evaluatePolySet(const class LinearExtrudeNode &) { return NULL; }
virtual PolySet *evaluatePolySet(const class RotateExtrudeNode &) { return NULL; }
virtual PolySet *evaluatePolySet(const class CgaladvNode &) { return NULL; }
virtual PolySet *evaluatePolySet(const class RenderNode &) { return NULL; }
virtual Geometry *evaluateGeometry(const class ProjectionNode &) { return NULL; }
virtual Geometry *evaluateGeometry(const class LinearExtrudeNode &) { return NULL; }
virtual Geometry *evaluateGeometry(const class RotateExtrudeNode &) { return NULL; }
virtual Geometry *evaluateGeometry(const class CgaladvNode &) { return NULL; }
virtual Geometry *evaluateGeometry(const class RenderNode &) { return NULL; }
private:
const Tree &tree;

60
src/Polygon2d.cc Normal file
View File

@ -0,0 +1,60 @@
#include "Polygon2d.h"
#include <boost/foreach.hpp>
size_t Polygon2d::memsize() const
{
size_t mem = 0;
BOOST_FOREACH(const Outline2d &o, this->outlines) {
mem += o.size() * sizeof(Vector2d) + sizeof(Outline2d);
}
mem += sizeof(Polygon2d);
return mem;
}
BoundingBox Polygon2d::getBoundingBox() const
{
BoundingBox bbox;
BOOST_FOREACH(const Outline2d &o, this->outlines) {
BOOST_FOREACH(const Vector2d &v, o) {
bbox.extend(Vector3d(v[0], v[1], 0));
}
}
return bbox;
}
std::string Polygon2d::dump() const
{
std::stringstream out;
out << "Polygon2d:";
//FIXME: Implement
/*
<< "\n convexity:" << this->convexity
<< "\n num polygons: " << polygons.size()
<< "\n num borders: " << borders.size()
<< "\n polygons data:";
for (size_t i = 0; i < polygons.size(); i++) {
out << "\n polygon begin:";
const Polygon *poly = &polygons[i];
for (size_t j = 0; j < poly->size(); j++) {
Vector3d v = poly->at(j);
out << "\n vertex:" << v.transpose();
}
}
out << "\n borders data:";
for (size_t i = 0; i < borders.size(); i++) {
out << "\n border polygon begin:";
const Polygon *poly = &borders[i];
for (size_t j = 0; j < poly->size(); j++) {
Vector3d v = poly->at(j);
out << "\n vertex:" << v.transpose();
}
}
out << "\nPolySet end";
*/
return out.str();
}
// PolySet *Polygon2d::tessellate()
// {
// return NULL;
// }

23
src/Polygon2d.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef POLYGON2D_H_
#define POLYGON2D_H_
#include "Geometry.h"
#include "linalg.h"
#include <vector>
typedef std::vector<Vector2d> Outline2d;
class Polygon2d : public Geometry
{
public:
virtual size_t memsize() const;
virtual BoundingBox getBoundingBox() const;
virtual std::string dump() const;
void addOutline(const Outline2d &outline);
// class PolySet *tessellate();
private:
std::vector<Outline2d> outlines;
};
#endif

View File

@ -31,7 +31,7 @@
#include <QKeyEvent>
#include <QSettings>
#include <QStatusBar>
#include "PolySetCache.h"
#include "GeometryCache.h"
#include "AutoUpdater.h"
#include "feature.h"
#ifdef ENABLE_CGAL
@ -84,7 +84,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
this->defaultmap["3dview/colorscheme"] = this->colorSchemeChooser->currentItem()->text();
this->defaultmap["advanced/opencsg_show_warning"] = true;
this->defaultmap["advanced/enable_opencsg_opengl1x"] = true;
this->defaultmap["advanced/polysetCacheSize"] = uint(PolySetCache::instance()->maxSize());
this->defaultmap["advanced/polysetCacheSize"] = uint(GeometryCache::instance()->maxSize());
#ifdef ENABLE_CGAL
this->defaultmap["advanced/cgalCacheSize"] = uint(CGALCache::instance()->maxSize());
#endif
@ -348,7 +348,7 @@ void Preferences::on_polysetCacheSizeEdit_textChanged(const QString &text)
{
QSettings settings;
settings.setValue("advanced/polysetCacheSize", text);
PolySetCache::instance()->setMaxSize(text.toULong());
GeometryCache::instance()->setMaxSize(text.toULong());
}
void Preferences::on_opencsgLimitEdit_textChanged(const QString &text)

View File

@ -29,6 +29,7 @@
#include "evalcontext.h"
#include "builtin.h"
#include "PolySetEvaluator.h"
#include "polyset.h"
#include <sstream>
#include <assert.h>
#include <boost/assign/std/vector.hpp>
@ -116,9 +117,9 @@ AbstractNode *CgaladvModule::instantiate(const Context *ctx, const ModuleInstant
return node;
}
PolySet *CgaladvNode::evaluate_polyset(PolySetEvaluator *ps) const
Geometry *CgaladvNode::evaluate_geometry(PolySetEvaluator *ps) const
{
return ps->evaluatePolySet(*this);
return ps->evaluateGeometry(*this);
}
std::string CgaladvNode::name() const

View File

@ -26,7 +26,7 @@ public:
}
virtual std::string toString() const;
virtual std::string name() const;
PolySet *evaluate_polyset(class PolySetEvaluator *ps) const;
Geometry *evaluate_geometry(class PolySetEvaluator *ps) const;
Value path;
std::string subdiv_type;

View File

@ -182,7 +182,7 @@ void read_stl_facet( std::ifstream &f, stl_facet &facet )
#endif
}
PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const
Geometry *ImportNode::evaluate_geometry(class PolySetEvaluator *) const
{
PolySet *p = NULL;

View File

@ -28,7 +28,7 @@ public:
int convexity;
double fn, fs, fa;
double origin_x, origin_y, scale;
virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const;
virtual Geometry *evaluate_geometry(class PolySetEvaluator *) const;
};
#endif

View File

@ -127,7 +127,7 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI
return node;
}
class PolySet *LinearExtrudeNode::evaluate_polyset(PolySetEvaluator *evaluator) const
class Geometry *LinearExtrudeNode::evaluate_geometry(PolySetEvaluator *evaluator) const
{
if (!evaluator) {
PRINTB("WARNING: No suitable PolySetEvaluator found for %s module!", this->name());
@ -136,7 +136,7 @@ class PolySet *LinearExtrudeNode::evaluate_polyset(PolySetEvaluator *evaluator)
print_messages_push();
PolySet *ps = evaluator->evaluatePolySet(*this);
Geometry *ps = evaluator->evaluateGeometry(*this);
print_messages_pop();

View File

@ -27,7 +27,7 @@ public:
bool center, has_twist;
Filename filename;
std::string layername;
virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const;
virtual Geometry *evaluate_geometry(class PolySetEvaluator *) const;
};
#endif

View File

@ -24,7 +24,7 @@
*
*/
#include "PolySetCache.h"
#include "GeometryCache.h"
#include "ModuleCache.h"
#include "MainWindow.h"
#include "parsersettings.h"
@ -81,7 +81,6 @@
#include <algorithm>
#include <boost/version.hpp>
#include <boost/foreach.hpp>
#include <boost/version.hpp>
#include <sys/stat.h>
#ifdef ENABLE_CGAL
@ -436,7 +435,7 @@ MainWindow::loadDesignSettings()
designActionAutoReload->setChecked(true);
}
uint polySetCacheSize = Preferences::inst()->getValue("advanced/polysetCacheSize").toUInt();
PolySetCache::instance()->setMaxSize(polySetCacheSize);
GeometryCache::instance()->setMaxSize(polySetCacheSize);
#ifdef ENABLE_CGAL
uint cgalCacheSize = Preferences::inst()->getValue("advanced/cgalCacheSize").toUInt();
CGALCache::instance()->setMaxSize(cgalCacheSize);
@ -803,7 +802,7 @@ void MainWindow::compileCSG(bool procevents)
if (!root_raw_term) {
PRINT("ERROR: CSG generation failed! (no top level object found)");
}
PolySetCache::instance()->print();
GeometryCache::instance()->print();
#ifdef ENABLE_CGAL
CGALCache::instance()->print();
#endif
@ -1312,7 +1311,7 @@ void MainWindow::actionRenderCGALDone(CGAL_Nef_polyhedron *root_N)
progress_report_fin();
if (root_N) {
PolySetCache::instance()->print();
GeometryCache::instance()->print();
#ifdef ENABLE_CGAL
CGALCache::instance()->print();
#endif
@ -1582,7 +1581,7 @@ void MainWindow::actionExportImage()
void MainWindow::actionFlushCaches()
{
PolySetCache::instance()->clear();
GeometryCache::instance()->clear();
#ifdef ENABLE_CGAL
CGALCache::instance()->clear();
#endif

View File

@ -3,5 +3,6 @@
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
#endif

View File

@ -35,10 +35,10 @@ public:
overloaded to provide specialization for e.g. CSG nodes, primitive nodes etc.
Used for human-readable output. */
virtual std::string name() const;
/*! Should return a PolySet of the given geometry. Returns NULL if smth. goes wrong.
This is only called by PolySetEvaluator, to make sure polysets are inserted into
the cache*/
virtual class PolySet *evaluate_polyset(class PolySetEvaluator *) const { return NULL; }
/*! Should return a Geometry instance describing the node. Returns NULL if smth.
goes wrong. This is only called by PolySetEvaluator, to make sure polysets
are inserted into the cache*/
virtual class Geometry *evaluate_geometry(class PolySetEvaluator *) const { return NULL; }
const std::vector<AbstractNode*> &getChildren() const {
return this->children;

View File

@ -35,9 +35,12 @@
FIXME: It's a bit messy and is a prime target for refactoring.
1) Store 2D and 3D polygon meshes from all origins
2) Store 2D outlines, used for rendering edges
2) Store 2D outlines, used for rendering edges (2D only)
3) Rendering of polygons and edges
PolySet must only contain convex polygons
*/
PolySet::PolySet() : grid(GRID_FINE), is2d(false), convexity(1)

View File

@ -1,13 +1,14 @@
#ifndef POLYSET_H_
#define POLYSET_H_
#include "Geometry.h"
#include "system-gl.h"
#include "grid.h"
#include "linalg.h"
#include <vector>
#include <string>
class PolySet
class PolySet : public Geometry
{
public:
typedef std::vector<Vector3d> Polygon;
@ -21,12 +22,15 @@ public:
PolySet();
~PolySet();
virtual size_t memsize() const;
virtual BoundingBox getBoundingBox() const;
virtual std::string dump() const;
bool empty() const { return polygons.size() == 0; }
void append_poly();
void append_vertex(double x, double y, double z = 0.0);
void insert_vertex(double x, double y, double z = 0.0);
size_t memsize() const;
BoundingBox getBoundingBox() const;
#define CSGMODE_DIFFERENCE_FLAG 0x10
@ -42,7 +46,6 @@ public:
void render_surface(csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo = NULL) const;
void render_edges(csgmode_e csgmode) const;
std::string dump() const;
};
#endif

View File

@ -28,6 +28,7 @@
#include "node.h"
#include "polyset.h"
#include "evalcontext.h"
#include "Polygon2d.h"
#include "dxfdata.h"
#include "dxftess.h"
#include "builtin.h"
@ -37,6 +38,7 @@
#include "calc.h"
#include <sstream>
#include <assert.h>
#include <boost/foreach.hpp>
#include <boost/assign/std/vector.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
@ -105,7 +107,7 @@ public:
primitive_type_e type;
int convexity;
Value points, paths, faces;
virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const;
virtual Geometry *evaluate_geometry(class PolySetEvaluator *) const;
};
/**
@ -188,8 +190,8 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta
node->fa = F_MINIMUM;
}
if (type == CUBE) {
switch (this->type) {
case CUBE: {
Value size = c.lookup_variable("size");
Value center = c.lookup_variable("center");
size.getDouble(node->x);
@ -199,16 +201,16 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta
if (center.type() == Value::BOOL) {
node->center = center.toBool();
}
break;
}
if (type == SPHERE) {
case SPHERE: {
const Value r = lookup_radius(c, "d", "r");
if (r.type() == Value::NUMBER) {
node->r1 = r.toDouble();
}
break;
}
if (type == CYLINDER) {
case CYLINDER: {
const Value h = c.lookup_variable("h");
if (h.type() == Value::NUMBER) {
node->h = h.toDouble();
@ -232,21 +234,20 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta
if (center.type() == Value::BOOL) {
node->center = center.toBool();
}
break;
}
if (type == POLYHEDRON) {
case POLYHEDRON: {
node->points = c.lookup_variable("points");
node->faces = c.lookup_variable("faces");
if (node->faces.type() == Value::UNDEFINED) {
// backwards compatable
// backwards compatible
node->faces = c.lookup_variable("triangles");
if (node->faces.type() != Value::UNDEFINED) {
PRINT("DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use polyhedron(faces=[]) instead.");
}
}
}
if (type == SQUARE) {
case SQUARE: {
Value size = c.lookup_variable("size");
Value center = c.lookup_variable("center");
size.getDouble(node->x);
@ -255,18 +256,20 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta
if (center.type() == Value::BOOL) {
node->center = center.toBool();
}
break;
}
if (type == CIRCLE) {
case CIRCLE: {
const Value r = lookup_radius(c, "d", "r");
if (r.type() == Value::NUMBER) {
node->r1 = r.toDouble();
}
break;
}
if (type == POLYGON) {
case POLYGON: {
node->points = c.lookup_variable("points");
node->paths = c.lookup_variable("paths");
break;
}
}
node->convexity = c.lookup_variable("convexity", true).toDouble();
@ -289,12 +292,14 @@ static void generate_circle(point2d *circle, double r, int fragments)
}
}
PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const
Geometry *PrimitiveNode::evaluate_geometry(class PolySetEvaluator *) const
{
PolySet *p = new PolySet();
Geometry *g = NULL;
if (this->type == CUBE && this->x > 0 && this->y > 0 && this->z > 0)
{
PolySet *p = new PolySet();
g = p;
double x1, x2, y1, y2, z1, z2;
if (this->center) {
x1 = -this->x/2;
@ -349,6 +354,8 @@ PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const
if (this->type == SPHERE && this->r1 > 0)
{
PolySet *p = new PolySet();
g = p;
struct ring_s {
point2d *points;
double z;
@ -417,6 +424,8 @@ sphere_next_r2:
if (this->type == CYLINDER &&
this->h > 0 && this->r1 >=0 && this->r2 >= 0 && (this->r1 > 0 || this->r2 > 0))
{
PolySet *p = new PolySet();
g = p;
int fragments = Calc::get_fragments_from_r(fmax(this->r1, this->r2), this->fn, this->fs, this->fa);
double z1, z2;
@ -476,6 +485,8 @@ sphere_next_r2:
if (this->type == POLYHEDRON)
{
PolySet *p = new PolySet();
g = p;
p->convexity = this->convexity;
for (size_t i=0; i<this->faces.toVector().size(); i++)
{
@ -493,6 +504,30 @@ sphere_next_r2:
if (this->type == SQUARE && x > 0 && y > 0)
{
/*
Polygon2d *p = new Polygon2d();
g = p;
double x1, x2, y1, y2;
if (this->center) {
x1 = -this->x/2;
x2 = +this->x/2;
y1 = -this->y/2;
y2 = +this->y/2;
} else {
x1 = y1 = 0;
x2 = this->x;
y2 = this->y;
}
Outline2d o(4);
o.push_back(Vector2d(x1, y1));
o.push_back(Vector2d(x2, y1));
o.push_back(Vector2d(x2, y2));
o.push_back(Vector2d(x1, y2));
*/
PolySet *p = new PolySet();
g = p;
double x1, x2, y1, y2;
if (this->center) {
x1 = -this->x/2;
@ -515,6 +550,8 @@ sphere_next_r2:
if (this->type == CIRCLE)
{
PolySet *p = new PolySet();
g = p;
int fragments = Calc::get_fragments_from_r(this->r1, this->fn, this->fs, this->fa);
p->is2d = true;
@ -528,6 +565,8 @@ sphere_next_r2:
if (this->type == POLYGON)
{
PolySet *p = new PolySet();
g = p;
DxfData dd;
for (size_t i=0; i<this->points.toVector().size(); i++) {
@ -580,9 +619,54 @@ sphere_next_r2:
p->convexity = convexity;
dxf_tesselate(p, dd, 0, Vector2d(1,1), true, false, 0);
dxf_border_to_ps(p, dd);
/*
Polygon2D *p = new Polygon2D();
g = p;
// Collect vertices
std::vector<Vector2d> vertices;
for (size_t i=0; i<this->points.toVector().size(); i++) {
double x,y;
if (!this->points.toVector()[i].getVec2(x, y)) {
PRINTB("ERROR: Unable to convert point at index %d to a vec2 of numbers", i);
delete p;
return NULL;
}
vertices.push_back(Vector2d(x, y));
}
Polygon2d polygon;
// If no indices, assume one single polygon
if (this->paths.toVector().size() == 0) {
assert(vertices.size() >= 3); // FIXME: Fail gracefully
Outline2d outline;
BOOST_FOREACH(const Vector2d &p, vertices) outline.push_back(p);
polygon.addOutline(outline);
}
else {
BOOST_FOREACH(const Value &val, this->paths.toVector()) {
Outline2d outline;
BOOST_FOREACH(const Value &idxval, val.toVector()) {
unsigned int idx = idxval.toDouble();
if (idx < vertices.size()) outline.push_back(vertices[idx]);
}
polygon.addOutline(outline);
}
}
ScadPolygon::tessellate(polygons);
ScadPolygon::createPolyset(*p, polygons);
p->is2d = true;
p->convexity = convexity;
// dxf_tesselate(p, dd, 0, true, false, 0);
// dxf_border_to_ps(p, dd);
*/
}
return p;
// FIXME: IF the above failed, create an empty polyset as that's required later on
if (!g) g = new PolySet();
return g;
}
std::string PrimitiveNode::toString() const

View File

@ -31,6 +31,7 @@
#include "builtin.h"
#include "visitor.h"
#include "PolySetEvaluator.h"
#include "polyset.h"
#include <assert.h>
#include <sstream>
@ -68,7 +69,7 @@ AbstractNode *ProjectionModule::instantiate(const Context *ctx, const ModuleInst
return node;
}
PolySet *ProjectionNode::evaluate_polyset(PolySetEvaluator *evaluator) const
Geometry *ProjectionNode::evaluate_geometry(PolySetEvaluator *evaluator) const
{
if (!evaluator) {
PRINTB("WARNING: No suitable PolySetEvaluator found for %s module!", this->name());
@ -77,7 +78,7 @@ PolySet *ProjectionNode::evaluate_polyset(PolySetEvaluator *evaluator) const
print_messages_push();
PolySet *ps = evaluator->evaluatePolySet(*this);
Geometry *ps = evaluator->evaluateGeometry(*this);
print_messages_pop();

View File

@ -19,7 +19,7 @@ public:
int convexity;
bool cut_mode;
virtual PolySet *evaluate_polyset(class PolySetEvaluator *evaluator) const;
virtual class Geometry *evaluate_geometry(class PolySetEvaluator *evaluator) const;
};
#endif

View File

@ -29,6 +29,7 @@
#include "evalcontext.h"
#include "builtin.h"
#include "PolySetEvaluator.h"
#include "polyset.h"
#include <sstream>
#include <boost/assign/std/vector.hpp>
@ -61,9 +62,9 @@ AbstractNode *RenderModule::instantiate(const Context *ctx, const ModuleInstanti
return node;
}
class PolySet *RenderNode::evaluate_polyset(PolySetEvaluator *ps) const
class Geometry *RenderNode::evaluate_geometry(PolySetEvaluator *ps) const
{
return ps->evaluatePolySet(*this);
return ps->evaluateGeometry(*this);
}
std::string RenderNode::toString() const

View File

@ -14,7 +14,7 @@ public:
}
virtual std::string toString() const;
virtual std::string name() const { return "render"; }
PolySet *evaluate_polyset(class PolySetEvaluator *ps) const;
Geometry *evaluate_geometry(class PolySetEvaluator *ps) const;
int convexity;
};

View File

@ -92,7 +92,7 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI
return node;
}
PolySet *RotateExtrudeNode::evaluate_polyset(PolySetEvaluator *evaluator) const
Geometry *RotateExtrudeNode::evaluate_geometry(PolySetEvaluator *evaluator) const
{
if (!evaluator) {
PRINTB("WARNING: No suitable PolySetEvaluator found for %s module!", this->name());
@ -101,7 +101,7 @@ PolySet *RotateExtrudeNode::evaluate_polyset(PolySetEvaluator *evaluator) const
print_messages_push();
PolySet *ps = evaluator->evaluatePolySet(*this);
Geometry *ps = evaluator->evaluateGeometry(*this);
print_messages_pop();

View File

@ -24,7 +24,7 @@ public:
double origin_x, origin_y, scale;
Filename filename;
std::string layername;
virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const;
virtual Geometry *evaluate_geometry(class PolySetEvaluator *) const;
};
#endif

View File

@ -67,7 +67,7 @@ public:
Filename filename;
bool center;
int convexity;
virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const;
virtual Geometry *evaluate_geometry(class PolySetEvaluator *) const;
};
AbstractNode *SurfaceModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
@ -98,7 +98,7 @@ AbstractNode *SurfaceModule::instantiate(const Context *ctx, const ModuleInstant
return node;
}
PolySet *SurfaceNode::evaluate_polyset(class PolySetEvaluator *) const
Geometry *SurfaceNode::evaluate_geometry(class PolySetEvaluator *) const
{
handle_dep(filename);
std::ifstream stream(filename.c_str());

View File

@ -521,6 +521,8 @@ set(CORE_SOURCES
../src/feature.cc
../src/csgterm.cc
../src/csgtermnormalizer.cc
../src/Geometry.cc
../src/Polygon2d.cc
../src/polyset.cc
../src/csgops.cc
../src/transform.cc
@ -565,7 +567,7 @@ set(COMMON_SOURCES
../src/nodedumper.cc
../src/traverser.cc
../src/PolySetEvaluator.cc
../src/PolySetCache.cc
../src/GeometryCache.cc
../src/Tree.cc
../src/lodepng.cpp)