mirror of https://github.com/vitalif/openscad
Clifford Wolf:
Added caching of cgal nef polyhydrons git-svn-id: http://svn.clifford.at/openscad/trunk@49 b57f626f-c46c-0410-a088-ec61d464b74cstl_dim
parent
5c239e7868
commit
cb6dbb3a37
31
csgops.cc
31
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()
|
||||
|
|
44
mainwin.cc
44
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
30
module.cc
30
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
31
transform.cc
31
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()
|
||||
|
|
Loading…
Reference in New Issue