Clifford Wolf:

Added caching of cgal nef polyhydrons



git-svn-id: http://svn.clifford.at/openscad/trunk@49 b57f626f-c46c-0410-a088-ec61d464b74c
stl_dim
clifford 2009-07-03 07:51:22 +00:00
parent 5c239e7868
commit cb6dbb3a37
8 changed files with 131 additions and 42 deletions

View File

@ -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()

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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()