Clifford Wolf:

Added dxf polyset caching



git-svn-id: http://svn.clifford.at/openscad/trunk@83 b57f626f-c46c-0410-a088-ec61d464b74c
stl_dim
clifford 2009-07-28 12:53:52 +00:00
parent b7cb05dbbd
commit 7b4cc84cda
11 changed files with 107 additions and 97 deletions

View File

@ -63,7 +63,7 @@ AbstractNode *CsgModule::evaluate(const Context*, const ModuleInstanciation *ins
CGAL_Nef_polyhedron CsgNode::render_cgal_nef_polyhedron() const
{
QString cache_id = cgal_nef_cache_id();
QString cache_id = mk_cache_id();
if (cgal_nef_cache.contains(cache_id)) {
progress_report();
return *cgal_nef_cache[cache_id];

View File

@ -22,13 +22,15 @@
#include "openscad.h"
CSGTerm::CSGTerm(PolySet *polyset, QString label)
CSGTerm::CSGTerm(PolySet *polyset, double m[16], QString label)
{
this->type = PRIMITIVE;
this->polyset = polyset;
this->label = label;
this->left = NULL;
this->right = NULL;
for (int i = 0; i < 16; i++)
this->m[i] = m[i];
refcounter = 1;
}
@ -141,7 +143,7 @@ void CSGTerm::unlink()
{
if (--refcounter <= 0) {
if (polyset)
delete polyset;
polyset->unlink();
if (left)
left->unlink();
if (right)
@ -165,9 +167,10 @@ CSGChain::CSGChain()
{
}
void CSGChain::add(PolySet *polyset, CSGTerm::type_e type, QString label)
void CSGChain::add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label)
{
polysets.append(polyset);
matrices.append(m);
types.append(type);
labels.append(label);
}
@ -175,7 +178,7 @@ void CSGChain::add(PolySet *polyset, CSGTerm::type_e type, QString label)
void CSGChain::import(CSGTerm *term, CSGTerm::type_e type)
{
if (term->type == CSGTerm::PRIMITIVE) {
add(term->polyset, type, term->label);
add(term->polyset, term->m, type, term->label);
} else {
import(term->left, type);
import(term->right, term->type);

View File

@ -55,7 +55,7 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI
{
DxfLinearExtrudeNode *node = new DxfLinearExtrudeNode(inst);
QVector<QString> argnames = QVector<QString>() << "file" << "layer" << "height" << "origin" << "scale" << "center";
QVector<QString> argnames = QVector<QString>() << "file" << "layer" << "height" << "origin" << "scale" << "center" << "twist" << "slices";
QVector<Expression*> argexpr;
Context c(ctx);
@ -155,8 +155,14 @@ static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2,
}
}
static QCache<QString,PolySetPtr> ps_cache(100);
PolySet *DxfLinearExtrudeNode::render_polyset(render_mode_e) const
{
QString key = mk_cache_id();
if (ps_cache.contains(key))
return ps_cache[key]->ps->link();
DxfData dxf(fn, fs, fa, filename, layername, origin_x, origin_y, scale);
PolySet *ps = new PolySet();
@ -220,6 +226,7 @@ PolySet *DxfLinearExtrudeNode::render_polyset(render_mode_e) const
}
}
ps_cache.insert(key, new PolySetPtr(ps->link()));
return ps;
}
@ -230,10 +237,19 @@ QString DxfLinearExtrudeNode::dump(QString indent) const
struct stat st;
memset(&st, 0, sizeof(struct stat));
stat(filename.toAscii().data(), &st);
text.sprintf("dxf_linear_extrude(file = \"%s\", cache = \"%x.%x\", layer = \"%s\", height = %f, "
"origin = [ %f %f ], scale = %f, $fn = %f, $fa = %f, $fs = %f);\n",
text.sprintf("dxf_linear_extrude(file = \"%s\", cache = \"%x.%x\", layer = \"%s\", "
"height = %f, origin = [ %f %f ], scale = %f, center = %s",
filename.toAscii().data(), (int)st.st_mtime, (int)st.st_size,
layername.toAscii().data(), height, origin_x, origin_y, scale, fn, fs, fa);
layername.toAscii().data(), height, origin_x, origin_y, scale,
center ? "true" : "false");
if (has_twist) {
QString t2;
t2.sprintf(", twist = %f, slices = %d", twist, slices);
text += t2;
}
QString t3;
t3.sprintf(", $fn = %f, $fa = %f, $fs = %f);\n", fn, fs, fa);
text += t3;
((AbstractNode*)this)->dump_cache = indent + QString("n%1: ").arg(idx) + text;
}
return dump_cache;

View File

@ -89,8 +89,15 @@ void register_builtin_dxf_rotate_extrude()
builtin_modules["dxf_rotate_extrude"] = new DxfRotateExtrudeModule();
}
static QCache<QString,PolySetPtr> ps_cache(100);
PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e) const
{
QString key = mk_cache_id();
if (ps_cache.contains(key))
return ps_cache[key]->ps->link();
DxfData dxf(fn, fs, fa, filename, layername, origin_x, origin_y, scale);
PolySet *ps = new PolySet();
@ -151,6 +158,7 @@ PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e) const
}
}
ps_cache.insert(key, new PolySetPtr(ps->link()));
return ps;
}
@ -162,9 +170,11 @@ QString DxfRotateExtrudeNode::dump(QString indent) const
memset(&st, 0, sizeof(struct stat));
stat(filename.toAscii().data(), &st);
text.sprintf("dxf_rotate_extrude(file = \"%s\", cache = \"%x.%x\", layer = \"%s\", "
"origin = [ %f %f ], scale = %f, $fn = %f, $fa = %f, $fs = %f);\n",
"origin = [ %f %f ], scale = %f, convexity = %d, "
"$fn = %f, $fa = %f, $fs = %f);\n",
filename.toAscii().data(), (int)st.st_mtime, (int)st.st_size,
layername.toAscii().data(), origin_x, origin_y, scale, fn, fs, fa);
layername.toAscii().data(), origin_x, origin_y, scale, convexity,
fn, fs, fa);
((AbstractNode*)this)->dump_cache = indent + QString("n%1: ").arg(idx) + text;
}
return dump_cache;

View File

@ -297,6 +297,7 @@ void MainWindow::compile()
find_root_tag(absolute_root_node);
if (!root_node)
root_node = absolute_root_node;
root_node->dump("");
PRINT("Compiling design (CSG Products generation)...");
QApplication::processEvents();
@ -814,8 +815,12 @@ public:
OpenCSGPrim(OpenCSG::Operation operation, unsigned int convexity) :
OpenCSG::Primitive(operation, convexity) { }
PolySet *p;
double *m;
virtual void render() {
glPushMatrix();
glMultMatrixd(m);
p->render_surface(PolySet::COLOR_NONE);
glPopMatrix();
}
};
@ -834,6 +839,8 @@ static void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool hi
if (shaderinfo)
glUseProgram(shaderinfo[0]);
for (; j < i; j++) {
glPushMatrix();
glMultMatrixd(chain->matrices[j]);
if (highlight) {
chain->polysets[j]->render_surface(PolySet::COLOR_HIGHLIGHT, shaderinfo);
} else if (background) {
@ -843,6 +850,7 @@ static void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool hi
} else {
chain->polysets[j]->render_surface(PolySet::COLOR_MATERIAL, shaderinfo);
}
glPopMatrix();
}
if (shaderinfo)
glUseProgram(0);
@ -859,6 +867,7 @@ static void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool hi
OpenCSGPrim *prim = new OpenCSGPrim(chain->types[i] == CSGTerm::DIFFERENCE ?
OpenCSG::Subtraction : OpenCSG::Intersection, chain->polysets[i]->convexity);
prim->p = chain->polysets[i];
prim->m = chain->matrices[i];
primitives.push_back(prim);
}
}
@ -972,11 +981,13 @@ void MainWindow::viewModeCGALGrid()
static void renderGLThrownTogetherChain(MainWindow *m, CSGChain *chain, bool highlight, bool background)
{
glDepthFunc(GL_LEQUAL);
QHash<PolySet*,int> polySetVisitMark;
QHash<QPair<PolySet*,double*>,int> polySetVisitMark;
bool showEdges = m->actViewModeShowEdges->isChecked();
for (int i = 0; i < chain->polysets.size(); i++) {
if (polySetVisitMark[chain->polysets[i]]++ > 0)
if (polySetVisitMark[QPair<PolySet*,double*>(chain->polysets[i], chain->matrices[i])]++ > 0)
continue;
glPushMatrix();
glMultMatrixd(chain->matrices[i]);
if (highlight) {
chain->polysets[i]->render_surface(PolySet::COLOR_HIGHLIGHT);
if (showEdges) {
@ -1006,6 +1017,7 @@ static void renderGLThrownTogetherChain(MainWindow *m, CSGChain *chain, bool hig
glEnable(GL_LIGHTING);
}
}
glPopMatrix();
}
}

View File

@ -217,11 +217,7 @@ AbstractNode::~AbstractNode()
delete v;
}
#ifdef ENABLE_CGAL
QCache<QString, CGAL_Nef_polyhedron> AbstractNode::cgal_nef_cache;
QString AbstractNode::cgal_nef_cache_id() const
QString AbstractNode::mk_cache_id() const
{
QString cache_id = dump("");
cache_id.remove(QRegExp("[a-zA-Z_][a-zA-Z_0-9]*:"));
@ -231,9 +227,13 @@ QString AbstractNode::cgal_nef_cache_id() const
return cache_id;
}
#ifdef ENABLE_CGAL
QCache<QString, CGAL_Nef_polyhedron> AbstractNode::cgal_nef_cache(100000);
CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const
{
QString cache_id = cgal_nef_cache_id();
QString cache_id = mk_cache_id();
if (cgal_nef_cache.contains(cache_id)) {
progress_report();
return *cgal_nef_cache[cache_id];

View File

@ -24,21 +24,10 @@
#include <QApplication>
#if 0
void report_func(const class AbstractNode*, void*, int mark)
{
printf("CSG rendering progress: %.2f%%\n", (mark*100.0) / progress_report_count);
}
#endif
int main(int argc, char **argv)
{
int rc;
#ifdef ENABLE_CGAL
AbstractNode::cgal_nef_cache.setMaxCost(100000);
#endif
initialize_builtin_functions();
initialize_builtin_modules();
@ -58,44 +47,6 @@ int main(int argc, char **argv)
a.connect(m, SIGNAL(destroyed()), &a, SLOT(quit()));
rc = a.exec();
#if 0
Context root_ctx(NULL);
root_ctx.functions_p = &builtin_functions;
root_ctx.modules_p = &builtin_modules;
AbstractModule *root_module = parse(stdin, 0);
printf("--- Abstract Syntax Tree ---\n");
QString ast_text = root_module->dump("", "**root**");
printf("%s", ast_text.toAscii().data());
AbstractNode *root_node = root_module->evaluate(&root_ctx, QVector<QString>(), QVector<Value>(), QVector<AbstractNode*>());
printf("--- Compiled CSG Tree ---\n");
QString csg_text = root_node->dump("");
printf("%s", csg_text.toAscii().data());
CGAL_Nef_polyhedron N;
CGAL_Polyhedron P;
progress_report_prep(root_node, report_func, NULL);
N = root_node->render_cgal_nef_polyhedron();
progress_report_fin();
printf("CSG rendering finished.\n");
N.convert_to_Polyhedron(P);
std::ofstream outFile("output.off");
if (outFile.fail()) {
std::cerr << "unable to open output file merged.off for writing!" << std::endl;
exit(1);
}
outFile << P;
delete root_node;
delete root_module;
#endif
destroy_builtin_functions();
destroy_builtin_modules();

View File

@ -487,17 +487,15 @@ public:
typedef QList<Point> Polygon;
QVector<Polygon> polygons;
Grid3d<void*> grid;
double m[16];
int convexity;
PolySet();
~PolySet();
void append_poly();
void append_vertex(double x, double y, double z);
void insert_vertex(double x, double y, double z);
void setmatrix(double m[16]);
enum colormode_e {
COLOR_NONE,
COLOR_MATERIAL,
@ -512,6 +510,22 @@ public:
#ifdef ENABLE_CGAL
CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
int refcount;
PolySet *link();
void unlink();
};
class PolySetPtr
{
public:
PolySet *ps;
PolySetPtr(PolySet *ps) {
this->ps = ps;
}
~PolySetPtr() {
ps->unlink();
}
};
class CSGTerm
@ -529,9 +543,10 @@ public:
QString label;
CSGTerm *left;
CSGTerm *right;
double m[16];
int refcounter;
CSGTerm(PolySet *polyset, QString label);
CSGTerm(PolySet *polyset, double m[16], QString label);
CSGTerm(type_e type, CSGTerm *left, CSGTerm *right);
CSGTerm *normalize();
@ -546,12 +561,13 @@ class CSGChain
{
public:
QVector<PolySet*> polysets;
QVector<double*> matrices;
QVector<CSGTerm::type_e> types;
QVector<QString> labels;
CSGChain();
void add(PolySet *polyset, CSGTerm::type_e type, QString label);
void add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label);
void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::UNION);
QString dump();
};
@ -572,9 +588,9 @@ public:
AbstractNode(const ModuleInstanciation *mi);
virtual ~AbstractNode();
virtual QString mk_cache_id() const;
#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, QVector<CSGTerm*> *background) const;

View File

@ -24,9 +24,25 @@
PolySet::PolySet()
{
for (int i = 0; i < 16; i++)
m[i] = i % 5 == 0 ? 1.0 : 0.0;
convexity = 1;
refcount = 1;
}
PolySet::~PolySet()
{
assert(refcount == 0);
}
PolySet* PolySet::link()
{
refcount++;
return this;
}
void PolySet::unlink()
{
if (--refcount == 0)
delete this;
}
void PolySet::append_poly()
@ -46,12 +62,6 @@ void PolySet::insert_vertex(double x, double y, double z)
polygons.last().insert(0, Point(x, y, z));
}
void PolySet::setmatrix(double m[16])
{
for (int i = 0; i < 16; i++)
this->m[i] = m[i];
}
static void gl_draw_triangle(GLint *shaderinfo, const PolySet::Point *p0, const PolySet::Point *p1, const PolySet::Point *p2, bool e0, bool e1, bool e2)
{
double ax = p1->x - p0->x, bx = p1->x - p2->x;
@ -94,8 +104,6 @@ static void gl_draw_triangle(GLint *shaderinfo, const PolySet::Point *p0, const
void PolySet::render_surface(colormode_e colormode, GLint *shaderinfo) const
{
glPushMatrix();
glMultMatrixd(m);
if (colormode == COLOR_MATERIAL) {
glColor3ub(249, 215, 44);
#ifdef ENABLE_OPENCSG
@ -164,13 +172,10 @@ void PolySet::render_surface(colormode_e colormode, GLint *shaderinfo) const
}
glEnd();
}
glPopMatrix();
}
void PolySet::render_edges(colormode_e colormode) const
{
glPushMatrix();
glMultMatrixd(m);
if (colormode == COLOR_MATERIAL)
glColor3ub(255, 236, 94);
if (colormode == COLOR_CUTOUT)
@ -188,7 +193,6 @@ void PolySet::render_edges(colormode_e colormode) const
}
glEnd();
}
glPopMatrix();
}
#ifdef ENABLE_CGAL
@ -299,7 +303,7 @@ PolySet *AbstractPolyNode::render_polyset(render_mode_e) const
CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
{
QString cache_id = cgal_nef_cache_id();
QString cache_id = mk_cache_id();
if (cgal_nef_cache.contains(cache_id)) {
progress_report();
return *cgal_nef_cache[cache_id];
@ -310,7 +314,7 @@ CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices());
progress_report();
delete ps;
ps->unlink();
return N;
}
@ -319,8 +323,7 @@ CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
CSGTerm *AbstractPolyNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
{
PolySet *ps = render_polyset(RENDER_OPENCSG);
ps->setmatrix(m);
CSGTerm *t = new CSGTerm(ps, QString("n%1").arg(idx));
CSGTerm *t = new CSGTerm(ps, m, QString("n%1").arg(idx));
if (modinst->tag_highlight && highlights)
highlights->append(t->link());
if (modinst->tag_background && background) {

View File

@ -76,7 +76,7 @@ void register_builtin_render()
CGAL_Nef_polyhedron RenderNode::render_cgal_nef_polyhedron() const
{
QString cache_id = cgal_nef_cache_id();
QString cache_id = mk_cache_id();
if (cgal_nef_cache.contains(cache_id)) {
progress_report();
return *cgal_nef_cache[cache_id];
@ -116,7 +116,7 @@ CSGTerm *RenderNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights
{
CGAL_Nef_polyhedron N;
QString cache_id = cgal_nef_cache_id();
QString cache_id = mk_cache_id();
if (cgal_nef_cache.contains(cache_id))
{
N = *cgal_nef_cache[cache_id];
@ -152,7 +152,6 @@ CSGTerm *RenderNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights
}
PolySet *ps = new PolySet();
ps->setmatrix(m);
ps->convexity = convexity;
CGAL_Polyhedron P;
@ -176,7 +175,7 @@ CSGTerm *RenderNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights
} while (hc != hc_end);
}
CSGTerm *term = new CSGTerm(ps, QString("n%1").arg(idx));
CSGTerm *term = new CSGTerm(ps, m, QString("n%1").arg(idx));
if (modinst->tag_highlight && highlights)
highlights->append(term->link());
if (modinst->tag_background && background) {

View File

@ -146,7 +146,7 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanci
CGAL_Nef_polyhedron TransformNode::render_cgal_nef_polyhedron() const
{
QString cache_id = cgal_nef_cache_id();
QString cache_id = mk_cache_id();
if (cgal_nef_cache.contains(cache_id)) {
progress_report();
return *cgal_nef_cache[cache_id];