diff options
author | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-07-03 07:51:22 (GMT) |
---|---|---|
committer | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-07-03 07:51:22 (GMT) |
commit | cb6dbb3a37602a9113b970477fdffc827e239baa (patch) | |
tree | d1df82ebfa09ed529de1e1a6abb336586f008160 | |
parent | 5c239e7868842195189c9c5782ba8a07c948f1e5 (diff) |
Clifford Wolf:
Added caching of cgal nef polyhydrons
git-svn-id: http://svn.clifford.at/openscad/trunk@49 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r-- | csgops.cc | 31 | ||||
-rw-r--r-- | mainwin.cc | 44 | ||||
-rw-r--r-- | module.cc | 30 | ||||
-rw-r--r-- | openscad.cc | 6 | ||||
-rw-r--r-- | openscad.h | 4 | ||||
-rw-r--r-- | polyset.cc | 8 | ||||
-rw-r--r-- | primitives.cc | 19 | ||||
-rw-r--r-- | transform.cc | 31 |
8 files changed, 131 insertions, 42 deletions
@@ -63,6 +63,12 @@ AbstractNode *CsgModule::evaluate(const Context*, const ModuleInstanciation *ins CGAL_Nef_polyhedron CsgNode::render_cgal_nef_polyhedron() const { + QString cache_id = cgal_nef_cache_id(); + if (cgal_nef_cache.contains(cache_id)) { + progress_report(); + return *cgal_nef_cache[cache_id]; + } + bool first = true; CGAL_Nef_polyhedron N; foreach (AbstractNode *v, children) { @@ -77,6 +83,8 @@ CGAL_Nef_polyhedron CsgNode::render_cgal_nef_polyhedron() const N *= v->render_cgal_nef_polyhedron(); } } + + cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); progress_report(); return N; } @@ -107,16 +115,19 @@ CSGTerm *CsgNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights) c QString CsgNode::dump(QString indent) const { - QString text = indent + QString("n%1: ").arg(idx); - if (type == UNION) - text += "union() {\n"; - if (type == DIFFERENCE) - text += "difference() {\n"; - if (type == INTERSECTION) - text += "intersection() {\n"; - foreach (AbstractNode *v, children) - text += v->dump(indent + QString("\t")); - return text + indent + "}\n"; + if (dump_cache.isEmpty()) { + QString text = indent + QString("n%1: ").arg(idx); + if (type == UNION) + text += "union() {\n"; + if (type == DIFFERENCE) + text += "difference() {\n"; + if (type == INTERSECTION) + text += "intersection() {\n"; + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; + } + return dump_cache; } void register_builtin_csgops() @@ -23,6 +23,7 @@ #include "openscad.h" #include <QMenu> +#include <QTime> #include <QMenuBar> #include <QSplitter> #include <QFileDialog> @@ -520,6 +521,9 @@ static void report_func(const class AbstractNode*, void *vp, int mark) QProgressDialog *pd = (QProgressDialog*)vp; int v = (int)((mark*100.0) / progress_report_count); pd->setValue(v < 100 ? v : 99); + QString label; + label.sprintf("Rendering Polygon Mesh using CGAL (%d/%d)", mark, progress_report_count); + pd->setLabelText(label); QApplication::processEvents(); } @@ -541,6 +545,9 @@ void MainWindow::actionRenderCGAL() PRINT("Rendering Polygon Mesh using CGAL..."); QApplication::processEvents(); + QTime t; + t.start(); + QProgressDialog *pd = new QProgressDialog("Rendering Polygon Mesh using CGAL...", QString(), 0, 100); pd->setValue(0); pd->setAutoClose(false); @@ -551,14 +558,29 @@ void MainWindow::actionRenderCGAL() root_N = new CGAL_Nef_polyhedron(root_node->render_cgal_nef_polyhedron()); progress_report_fin(); + PRINTF("Number of vertices currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.totalCost()); + PRINTF("Number of objects currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.size()); + QApplication::processEvents(); + PRINTF(" Simple: %6s", root_N->is_simple() ? "yes" : "no"); + QApplication::processEvents(); PRINTF(" Valid: %6s", root_N->is_valid() ? "yes" : "no"); + QApplication::processEvents(); PRINTF(" Vertices: %6d", (int)root_N->number_of_vertices()); + QApplication::processEvents(); PRINTF(" Halfedges: %6d", (int)root_N->number_of_halfedges()); + QApplication::processEvents(); PRINTF(" Edges: %6d", (int)root_N->number_of_edges()); + QApplication::processEvents(); PRINTF(" Halffacets: %6d", (int)root_N->number_of_halffacets()); + QApplication::processEvents(); PRINTF(" Facets: %6d", (int)root_N->number_of_facets()); + QApplication::processEvents(); PRINTF(" Volumes: %6d", (int)root_N->number_of_volumes()); + QApplication::processEvents(); + + int s = t.elapsed() / 1000; + PRINTF("Total rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60); if (!actViewModeCGALSurface->isChecked() && !actViewModeCGALGrid->isChecked()) { viewModeCGALSurface(); @@ -809,20 +831,24 @@ static void renderGLThrownTogether(void *vp) MainWindow *m = (MainWindow*)vp; if (m->root_chain) { glDepthFunc(GL_LEQUAL); + QHash<PolySet*,int> polySetVisitMark; + bool showEdges = m->actViewModeShowEdges->isChecked(); for (int i = 0; i < m->root_chain->polysets.size(); i++) { + if (polySetVisitMark[m->root_chain->polysets[i]]++ > 0) + continue; if (m->root_chain->types[i] == CSGTerm::DIFFERENCE) { m->root_chain->polysets[i]->render_surface(PolySet::COLOR_CUTOUT); + if (showEdges) { + glDisable(GL_LIGHTING); + m->root_chain->polysets[i]->render_edges(PolySet::COLOR_CUTOUT); + glEnable(GL_LIGHTING); + } } else { m->root_chain->polysets[i]->render_surface(PolySet::COLOR_MATERIAL); - } - } - if (m->actViewModeShowEdges->isChecked()) { - glDisable(GL_LIGHTING); - for (int i = 0; i < m->root_chain->polysets.size(); i++) { - if (m->root_chain->types[i] == CSGTerm::DIFFERENCE) { - m->root_chain->polysets[i]->render_edges(PolySet::COLOR_CUTOUT); - } else { - m->root_chain->polysets[i]->render_edges(PolySet::COLOR_MATERIAL); + if (showEdges) { + glDisable(GL_LIGHTING); + m->root_chain->polysets[i]->render_edges(PolySet::COLOR_MATERIAL); + glEnable(GL_LIGHTING); } } } @@ -215,11 +215,30 @@ AbstractNode::~AbstractNode() #ifdef ENABLE_CGAL +QCache<QString, CGAL_Nef_polyhedron> AbstractNode::cgal_nef_cache; + +QString AbstractNode::cgal_nef_cache_id() const +{ + QString cache_id = dump(""); + cache_id.remove(' '); + cache_id.remove('\t'); + cache_id.remove('\n'); + return cache_id; +} + CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const { + QString cache_id = cgal_nef_cache_id(); + if (cgal_nef_cache.contains(cache_id)) { + progress_report(); + return *cgal_nef_cache[cache_id]; + } + CGAL_Nef_polyhedron N; foreach (AbstractNode *v, children) N += v->render_cgal_nef_polyhedron(); + + cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); progress_report(); return N; } @@ -244,10 +263,13 @@ CSGTerm *AbstractNode::render_csg_term(double m[16], QVector<CSGTerm*> *highligh QString AbstractNode::dump(QString indent) const { - QString text = indent + QString("n%1: group() {\n").arg(idx); - foreach (AbstractNode *v, children) - text += v->dump(indent + QString("\t")); - return text + indent + "}\n"; + if (dump_cache.isEmpty()) { + QString text = indent + QString("n%1: group() {\n").arg(idx); + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; + } + return dump_cache; } int progress_report_count; diff --git a/openscad.cc b/openscad.cc index 64eb5bf..51c2453 100644 --- a/openscad.cc +++ b/openscad.cc @@ -18,7 +18,7 @@ * */ -// #define INCLUDE_ABSTRACT_NODE_DETAILS +#define INCLUDE_ABSTRACT_NODE_DETAILS #include "openscad.h" @@ -35,6 +35,10 @@ int main(int argc, char **argv) { int rc; +#ifdef ENABLE_CGAL + AbstractNode::cgal_nef_cache.setMaxCost(200000); +#endif + initialize_builtin_functions(); initialize_builtin_modules(); @@ -37,6 +37,7 @@ static inline uint qHash(double v) { #endif #include <QHash> +#include <QCache> #include <QVector> #include <QMainWindow> #include <QSplitter> @@ -404,10 +405,13 @@ public: int idx; static int idx_counter; + QString dump_cache; AbstractNode(const ModuleInstanciation *mi); virtual ~AbstractNode(); #ifdef ENABLE_CGAL + static QCache<QString, CGAL_Nef_polyhedron> cgal_nef_cache; + virtual QString cgal_nef_cache_id() const; virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; #endif virtual CSGTerm *render_csg_term(double m[16], QVector<CSGTerm*> *highlights) const; @@ -256,8 +256,16 @@ PolySet *AbstractPolyNode::render_polyset(render_mode_e) const CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const { + QString cache_id = cgal_nef_cache_id(); + if (cgal_nef_cache.contains(cache_id)) { + progress_report(); + return *cgal_nef_cache[cache_id]; + } + PolySet *ps = render_polyset(RENDER_CGAL); CGAL_Nef_polyhedron N = ps->render_cgal_nef_polyhedron(); + + cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); progress_report(); delete ps; return N; diff --git a/primitives.cc b/primitives.cc index 4494b03..a2ca971 100644 --- a/primitives.cc +++ b/primitives.cc @@ -326,13 +326,16 @@ sphere_next_r2: QString PrimitiveNode::dump(QString indent) const { - QString text; - if (type == CUBE) - text.sprintf("cube(size = [%f %f %f], center = %s);\n", x, y, z, center ? "true" : "false"); - if (type == SPHERE) - text.sprintf("sphere(r = %f);\n", r1); - if (type == CYLINDER) - text.sprintf("cylinder(h = %f, r1 = %f, r2 = %f, center = %s);\n", h, r1, r2, center ? "true" : "false"); - return indent + QString("n%1: ").arg(idx) + text; + if (dump_cache.isEmpty()) { + QString text; + if (type == CUBE) + text.sprintf("cube(size = [%f %f %f], center = %s);\n", x, y, z, center ? "true" : "false"); + if (type == SPHERE) + text.sprintf("sphere($fn = %f, $fa = %f, $fs = %f, r = %f);\n", fn, fa, fs, r1); + if (type == CYLINDER) + text.sprintf("cylinder($fn = %f, $fa = %f, $fs = %f, h = %f, r1 = %f, r2 = %f, center = %s);\n", fn, fa, fs, h, r1, r2, center ? "true" : "false"); + ((AbstractNode*)this)->dump_cache = indent + QString("n%1: ").arg(idx) + text; + } + return dump_cache; } diff --git a/transform.cc b/transform.cc index eda8705..c4f76f6 100644 --- a/transform.cc +++ b/transform.cc @@ -146,6 +146,12 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanci CGAL_Nef_polyhedron TransformNode::render_cgal_nef_polyhedron() const { + QString cache_id = cgal_nef_cache_id(); + if (cgal_nef_cache.contains(cache_id)) { + progress_report(); + return *cgal_nef_cache[cache_id]; + } + CGAL_Nef_polyhedron N; foreach (AbstractNode *v, children) N += v->render_cgal_nef_polyhedron(); @@ -154,6 +160,8 @@ CGAL_Nef_polyhedron TransformNode::render_cgal_nef_polyhedron() const m[1], m[5], m[ 9], m[13], m[2], m[6], m[10], m[14], m[15]); N.transform(t); + + cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); progress_report(); return N; } @@ -190,16 +198,19 @@ CSGTerm *TransformNode::render_csg_term(double c[16], QVector<CSGTerm*> *highlig QString TransformNode::dump(QString indent) const { - QString text; - text.sprintf("n%d: multmatrix([[%f %f %f %f], [%f %f %f %f], [%f %f %f %f], [%f %f %f %f]])", idx, - m[0], m[4], m[ 8], m[12], - m[1], m[5], m[ 9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15]); - text = indent + text + " {\n"; - foreach (AbstractNode *v, children) - text += v->dump(indent + QString("\t")); - return text + indent + "}\n"; + if (dump_cache.isEmpty()) { + QString text; + text.sprintf("n%d: multmatrix([[%f %f %f %f], [%f %f %f %f], [%f %f %f %f], [%f %f %f %f]])", idx, + m[0], m[4], m[ 8], m[12], + m[1], m[5], m[ 9], m[13], + m[2], m[6], m[10], m[14], + m[3], m[7], m[11], m[15]); + text = indent + text + " {\n"; + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; + } + return dump_cache; } void register_builtin_transform() |