summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-07-03 07:51:22 (GMT)
committerclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-07-03 07:51:22 (GMT)
commitcb6dbb3a37602a9113b970477fdffc827e239baa (patch)
treed1df82ebfa09ed529de1e1a6abb336586f008160
parent5c239e7868842195189c9c5782ba8a07c948f1e5 (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.cc31
-rw-r--r--mainwin.cc44
-rw-r--r--module.cc30
-rw-r--r--openscad.cc6
-rw-r--r--openscad.h4
-rw-r--r--polyset.cc8
-rw-r--r--primitives.cc19
-rw-r--r--transform.cc31
8 files changed, 131 insertions, 42 deletions
diff --git a/csgops.cc b/csgops.cc
index 6f047f0..d2b3706 100644
--- a/csgops.cc
+++ b/csgops.cc
@@ -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()
diff --git a/mainwin.cc b/mainwin.cc
index 63cb35b..0905d66 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -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);
}
}
}
diff --git a/module.cc b/module.cc
index 2e9a3f6..a0c8423 100644
--- a/module.cc
+++ b/module.cc
@@ -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();
diff --git a/openscad.h b/openscad.h
index 27b0c70..551b488 100644
--- a/openscad.h
+++ b/openscad.h
@@ -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;
diff --git a/polyset.cc b/polyset.cc
index 4f7149d..7bb7f2c 100644
--- a/polyset.cc
+++ b/polyset.cc
@@ -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()
contact: Jan Huwald // Impressum