mirror of https://github.com/vitalif/openscad
Started refactoring of render_csg_term() into a visitor
parent
f2323c78b3
commit
f0b49ee9e9
|
@ -0,0 +1,335 @@
|
|||
#include "CSGTermRenderer.h"
|
||||
#include "visitor.h"
|
||||
#include "state.h"
|
||||
#include "csgterm.h"
|
||||
#include "module.h"
|
||||
#include "csgnode.h"
|
||||
#include "transformnode.h"
|
||||
#include "rendernode.h"
|
||||
#include "printutils.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
|
||||
/*!
|
||||
\class CSGTermRenderer
|
||||
|
||||
A visitor responsible for creating a tree of CSGTerm nodes used for rendering
|
||||
with OpenCSG.
|
||||
*/
|
||||
|
||||
void CSGTermRenderer::applyToChildren(const AbstractNode &node, CSGTermRenderer::CsgOp op)
|
||||
{
|
||||
if (this->visitedchildren[node.index()].size() == 0) return;
|
||||
|
||||
CSGTerm *t1 = NULL;
|
||||
for (ChildList::const_iterator iter = this->visitedchildren[node.index()].begin();
|
||||
iter != this->visitedchildren[node.index()].end();
|
||||
iter++) {
|
||||
const AbstractNode *chnode = *iter;
|
||||
CSGTerm *t2 = this->stored_term[chnode->index()];
|
||||
this->stored_term.erase(chnode->index());
|
||||
if (t2 && !t1) {
|
||||
t1 = t2;
|
||||
} else if (t2 && t1) {
|
||||
if (op == UNION) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
|
||||
} else if (op == DIFFERENCE) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_DIFFERENCE, t1, t2);
|
||||
} else if (op == INTERSECTION) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (t1 && node.modinst->tag_highlight && this->highlights) {
|
||||
this->highlights->push_back(t1->link());
|
||||
}
|
||||
if (t1 && node.modinst->tag_background && this->background) {
|
||||
this->background->push_back(t1);
|
||||
// FIXME: don't store in stored_term? return NULL;
|
||||
}
|
||||
this->stored_term[node.index()] = t1;
|
||||
}
|
||||
|
||||
Response CSGTermRenderer::visit(const State &state, const AbstractNode &node)
|
||||
{
|
||||
if (state.isPostfix()) {
|
||||
applyToChildren(node, UNION);
|
||||
addToParent(state, node);
|
||||
}
|
||||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
Response CSGTermRenderer::visit(const State &state, const AbstractIntersectionNode &node)
|
||||
{
|
||||
if (state.isPostfix()) {
|
||||
applyToChildren(node, INTERSECTION);
|
||||
addToParent(state, node);
|
||||
}
|
||||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
static CSGTerm *render_csg_term_from_ps(double m[20],
|
||||
QVector<CSGTerm*> *highlights,
|
||||
QVector<CSGTerm*> *background,
|
||||
PolySet *ps,
|
||||
const ModuleInstantiation *modinst,
|
||||
int idx)
|
||||
{
|
||||
CSGTerm *t = new CSGTerm(ps, m, QString("n%1").arg(idx));
|
||||
if (modinst->tag_highlight && highlights)
|
||||
highlights->push_back(t->link());
|
||||
if (modinst->tag_background && background) {
|
||||
background->push_back(t);
|
||||
return NULL;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
Response CSGTermRenderer::visit(const State &state, const AbstractPolyNode &node)
|
||||
{
|
||||
if (state.isPostfix()) {
|
||||
PolySet *ps = node.render_polyset(AbstractPolyNode::RENDER_OPENCSG);
|
||||
CSGTerm *t1 = render_csg_term_from_ps(m, this->highlights, this->background, ps, node.modinst, node.index());
|
||||
this->stored_term[node.index()] = t1;
|
||||
addToParent(state, node);
|
||||
}
|
||||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
Response CSGTermRenderer::visit(const State &state, const CsgNode &node)
|
||||
{
|
||||
if (state.isPostfix()) {
|
||||
CsgOp op;
|
||||
switch (node.type) {
|
||||
case CSG_TYPE_UNION:
|
||||
op = UNION;
|
||||
break;
|
||||
case CSG_TYPE_DIFFERENCE:
|
||||
op = DIFFERENCE;
|
||||
break;
|
||||
case CSG_TYPE_INTERSECTION:
|
||||
op = INTERSECTION;
|
||||
break;
|
||||
}
|
||||
applyToChildren(node, op);
|
||||
addToParent(state, node);
|
||||
}
|
||||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
Response CSGTermRenderer::visit(const State &state, const TransformNode &node)
|
||||
{
|
||||
if (state.isPostfix()) {
|
||||
double x[20];
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int c_row = i%4;
|
||||
int m_col = i/4;
|
||||
x[i] = 0;
|
||||
for (int j = 0; j < 4; j++)
|
||||
x[i] += c[c_row + j*4] * m[m_col*4 + j];
|
||||
}
|
||||
|
||||
for (int i = 16; i < 20; i++)
|
||||
x[i] = m[i] < 0 ? c[i] : m[i];
|
||||
|
||||
// FIXME: Apply the x matrix.
|
||||
// FIXME: Look into how bottom-up vs. top down affects matrix handling
|
||||
|
||||
applyToChildren(node, UNION);
|
||||
addToParent(state, node);
|
||||
}
|
||||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
// FIXME: Find out how to best call into CGAL from this visitor
|
||||
Response CSGTermRenderer::visit(const State &state, const RenderNode &node)
|
||||
{
|
||||
PRINT("WARNING: Found render() statement but compiled without CGAL support!");
|
||||
if (state.isPostfix()) {
|
||||
applyToChildren(node, UNION);
|
||||
addToParent(state, node);
|
||||
}
|
||||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds ourself to out parent's list of traversed children.
|
||||
Call this for _every_ node which affects output during the postfix traversal.
|
||||
*/
|
||||
void CSGTermRenderer::addToParent(const State &state, const AbstractNode &node)
|
||||
{
|
||||
assert(state.isPostfix());
|
||||
this->visitedchildren.erase(node.index());
|
||||
if (state.parent()) {
|
||||
this->visitedchildren[state.parent()->index()].push_back(&node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
// FIXME: #ifdef ENABLE_CGAL
|
||||
#if 0
|
||||
CSGTerm *CgaladvNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
if (type == MINKOWSKI)
|
||||
return render_csg_term_from_nef(m, highlights, background, "minkowski", this->convexity);
|
||||
|
||||
if (type == GLIDE)
|
||||
return render_csg_term_from_nef(m, highlights, background, "glide", this->convexity);
|
||||
|
||||
if (type == SUBDIV)
|
||||
return render_csg_term_from_nef(m, highlights, background, "subdiv", this->convexity);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else // ENABLE_CGAL
|
||||
|
||||
CSGTerm *CgaladvNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
PRINT("WARNING: Found minkowski(), glide() or subdiv() statement but compiled without CGAL support!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // ENABLE_CGAL
|
||||
|
||||
|
||||
|
||||
// FIXME: #ifdef ENABLE_CGAL
|
||||
#if 0
|
||||
CSGTerm *AbstractNode::render_csg_term_from_nef(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, const char *statement, int convexity) const
|
||||
{
|
||||
QString key = mk_cache_id();
|
||||
if (PolySet::ps_cache.contains(key)) {
|
||||
PRINT(PolySet::ps_cache[key]->msg);
|
||||
return AbstractPolyNode::render_csg_term_from_ps(m, highlights, background,
|
||||
PolySet::ps_cache[key]->ps->link(), modinst, idx);
|
||||
}
|
||||
|
||||
print_messages_push();
|
||||
CGAL_Nef_polyhedron N;
|
||||
|
||||
QString cache_id = mk_cache_id();
|
||||
if (cgal_nef_cache.contains(cache_id))
|
||||
{
|
||||
PRINT(cgal_nef_cache[cache_id]->msg);
|
||||
N = cgal_nef_cache[cache_id]->N;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF_NOCACHE("Processing uncached %s statement...", statement);
|
||||
// PRINTA("Cache ID: %1", cache_id);
|
||||
QApplication::processEvents();
|
||||
|
||||
QTime t;
|
||||
t.start();
|
||||
|
||||
N = this->renderCSGMesh();
|
||||
|
||||
int s = t.elapsed() / 1000;
|
||||
PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
|
||||
}
|
||||
|
||||
PolySet *ps = NULL;
|
||||
|
||||
if (N.dim == 2)
|
||||
{
|
||||
DxfData dd(N);
|
||||
ps = new PolySet();
|
||||
ps->is2d = true;
|
||||
dxf_tesselate(ps, &dd, 0, true, false, 0);
|
||||
dxf_border_to_ps(ps, &dd);
|
||||
}
|
||||
|
||||
if (N.dim == 3)
|
||||
{
|
||||
if (!N.p3.is_simple()) {
|
||||
PRINTF("WARNING: Result of %s() isn't valid 2-manifold! Modify your design..", statement);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ps = new PolySet();
|
||||
|
||||
CGAL_Polyhedron P;
|
||||
N.p3.convert_to_Polyhedron(P);
|
||||
|
||||
typedef CGAL_Polyhedron::Vertex Vertex;
|
||||
typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
|
||||
typedef CGAL_Polyhedron::Facet_const_iterator FCI;
|
||||
typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC;
|
||||
|
||||
for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
|
||||
HFCC hc = fi->facet_begin();
|
||||
HFCC hc_end = hc;
|
||||
ps->append_poly();
|
||||
do {
|
||||
Vertex v = *VCI((hc++)->vertex());
|
||||
double x = CGAL::to_double(v.point().x());
|
||||
double y = CGAL::to_double(v.point().y());
|
||||
double z = CGAL::to_double(v.point().z());
|
||||
ps->append_vertex(x, y, z);
|
||||
} while (hc != hc_end);
|
||||
}
|
||||
}
|
||||
|
||||
if (ps)
|
||||
{
|
||||
ps->convexity = convexity;
|
||||
PolySet::ps_cache.insert(key, new PolySet::ps_cache_entry(ps->link()));
|
||||
|
||||
CSGTerm *term = new CSGTerm(ps, m, QString("n%1").arg(idx));
|
||||
if (modinst->tag_highlight && highlights)
|
||||
highlights->push_back(term->link());
|
||||
if (modinst->tag_background && background) {
|
||||
background->push_back(term);
|
||||
return NULL;
|
||||
}
|
||||
return term;
|
||||
}
|
||||
print_messages_pop();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
return render_csg_term_from_nef(m, highlights, background, "render", this->convexity);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
CSGTerm *t1 = NULL;
|
||||
PRINT("WARNING: Found render() statement but compiled without CGAL support!");
|
||||
foreach(AbstractNode * v, children) {
|
||||
CSGTerm *t2 = v->render_csg_term(m, highlights, background);
|
||||
if (t2 && !t1) {
|
||||
t1 = t2;
|
||||
} else if (t2 && t1) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
|
||||
}
|
||||
}
|
||||
if (modinst->tag_highlight && highlights)
|
||||
highlights->push_back(t1->link());
|
||||
if (t1 && modinst->tag_background && background) {
|
||||
background->push_back(t1);
|
||||
return NULL;
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef CSGTERMRENDERER_H_
|
||||
#define CSGTERMRENDERER_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include "visitor.h"
|
||||
#include "node.h"
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
using std::list;
|
||||
using std::vector;
|
||||
|
||||
class CSGTermRenderer : public Visitor
|
||||
{
|
||||
public:
|
||||
CSGTermRenderer() {}
|
||||
virtual ~CSGTermRenderer() {}
|
||||
|
||||
virtual Response visit(const State &state, const AbstractNode &node);
|
||||
virtual Response visit(const State &state, const AbstractIntersectionNode &node);
|
||||
virtual Response visit(const State &state, const AbstractPolyNode &node);
|
||||
virtual Response visit(const State &state, const CsgNode &node);
|
||||
virtual Response visit(const State &state, const TransformNode &node);
|
||||
virtual Response visit(const State &state, const RenderNode &node);
|
||||
|
||||
private:
|
||||
enum CsgOp {UNION, INTERSECTION, DIFFERENCE, MINKOWSKI};
|
||||
void addToParent(const State &state, const AbstractNode &node);
|
||||
void applyToChildren(const AbstractNode &node, CSGTermRenderer::CsgOp op);
|
||||
|
||||
const AbstractNode *root;
|
||||
typedef list<const AbstractNode *> ChildList;
|
||||
map<int, ChildList> visitedchildren;
|
||||
map<int, class CSGTerm*> stored_term;
|
||||
|
||||
vector<CSGTerm*> *highlights;
|
||||
vector<CSGTerm*> *background;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -68,7 +68,6 @@ public:
|
|||
QString subdiv_type;
|
||||
int convexity, level;
|
||||
cgaladv_type_e type;
|
||||
virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
|
||||
};
|
||||
|
||||
AbstractNode *CgaladvModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const
|
||||
|
@ -131,32 +130,6 @@ void register_builtin_cgaladv()
|
|||
builtin_modules["subdiv"] = new CgaladvModule(SUBDIV);
|
||||
}
|
||||
|
||||
// FIXME: #ifdef ENABLE_CGAL
|
||||
#if 0
|
||||
CSGTerm *CgaladvNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
if (type == MINKOWSKI)
|
||||
return render_csg_term_from_nef(m, highlights, background, "minkowski", this->convexity);
|
||||
|
||||
if (type == GLIDE)
|
||||
return render_csg_term_from_nef(m, highlights, background, "glide", this->convexity);
|
||||
|
||||
if (type == SUBDIV)
|
||||
return render_csg_term_from_nef(m, highlights, background, "subdiv", this->convexity);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else // ENABLE_CGAL
|
||||
|
||||
CSGTerm *CgaladvNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
PRINT("WARNING: Found minkowski(), glide() or subdiv() statement but compiled without CGAL support!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // ENABLE_CGAL
|
||||
|
||||
std::string CgaladvNode::toString() const
|
||||
{
|
||||
std::stringstream stream;
|
||||
|
|
|
@ -19,8 +19,6 @@ public:
|
|||
return visitor.visit(state, *this);
|
||||
}
|
||||
virtual std::string toString() const;
|
||||
|
||||
CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -51,32 +51,6 @@ AbstractNode *CsgModule::evaluate(const Context*, const ModuleInstantiation *ins
|
|||
return node;
|
||||
}
|
||||
|
||||
CSGTerm *CsgNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
CSGTerm *t1 = NULL;
|
||||
foreach (AbstractNode *v, children) {
|
||||
CSGTerm *t2 = v->render_csg_term(m, highlights, background);
|
||||
if (t2 && !t1) {
|
||||
t1 = t2;
|
||||
} else if (t2 && t1) {
|
||||
if (type == CSG_TYPE_UNION) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
|
||||
} else if (type == CSG_TYPE_DIFFERENCE) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_DIFFERENCE, t1, t2);
|
||||
} else if (type == CSG_TYPE_INTERSECTION) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (t1 && modinst->tag_highlight && highlights)
|
||||
highlights->append(t1->link());
|
||||
if (t1 && modinst->tag_background && background) {
|
||||
background->append(t1);
|
||||
return NULL;
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
std::string CsgNode::toString() const
|
||||
{
|
||||
std::stringstream stream;
|
||||
|
|
51
src/node.cc
51
src/node.cc
|
@ -90,57 +90,6 @@ void AbstractNode::progress_report() const
|
|||
progress_update(this, this->progress_mark);
|
||||
}
|
||||
|
||||
static CSGTerm *render_csg_term_backend(const AbstractNode *that, bool intersect, double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background)
|
||||
{
|
||||
CSGTerm *t1 = NULL;
|
||||
foreach(AbstractNode *v, that->children) {
|
||||
CSGTerm *t2 = v->render_csg_term(m, highlights, background);
|
||||
if (t2 && !t1) {
|
||||
t1 = t2;
|
||||
} else if (t2 && t1) {
|
||||
if (intersect)
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2);
|
||||
else
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
|
||||
}
|
||||
}
|
||||
if (t1 && that->modinst->tag_highlight && highlights)
|
||||
highlights->append(t1->link());
|
||||
if (t1 && that->modinst->tag_background && background) {
|
||||
background->append(t1);
|
||||
return NULL;
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
CSGTerm *AbstractNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
return render_csg_term_backend(this, false, m, highlights, background);
|
||||
}
|
||||
|
||||
CSGTerm *AbstractIntersectionNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
return render_csg_term_backend(this, true, m, highlights, background);
|
||||
}
|
||||
|
||||
CSGTerm *AbstractPolyNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
PolySet *ps = render_polyset(RENDER_OPENCSG);
|
||||
return render_csg_term_from_ps(m, highlights, background, ps, modinst, idx);
|
||||
}
|
||||
|
||||
CSGTerm *AbstractPolyNode::render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, PolySet *ps, const ModuleInstantiation *modinst, int 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) {
|
||||
background->append(t);
|
||||
return NULL;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const QString &str)
|
||||
{
|
||||
stream << str.toStdString();
|
||||
|
|
|
@ -51,9 +51,6 @@ public:
|
|||
|
||||
int idx; // Node index (unique per tree)
|
||||
|
||||
// FIXME: Rewrite to visitor
|
||||
virtual class CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
|
||||
|
||||
// FIXME: Rewrite to visitor
|
||||
#ifdef ENABLE_CGAL
|
||||
class CSGTerm *render_csg_term_from_nef(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, const char *statement, int convexity) const;
|
||||
|
@ -67,8 +64,6 @@ public:
|
|||
virtual ~AbstractIntersectionNode() { };
|
||||
virtual Response accept(const class State &state, class Visitor &visitor) const;
|
||||
virtual std::string toString() const;
|
||||
|
||||
virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
|
||||
};
|
||||
|
||||
class AbstractPolyNode : public AbstractNode
|
||||
|
@ -86,8 +81,6 @@ public:
|
|||
empty PolySet if smth. is wrong, but don't return NULL unless we change the calling
|
||||
strategy for this method. */
|
||||
virtual class PolySet *render_polyset(render_mode_e mode) const = 0;
|
||||
virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
|
||||
static CSGTerm *render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, PolySet *ps, const ModuleInstantiation *modinst, int idx);
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const AbstractNode &node);
|
||||
|
|
126
src/render.cc
126
src/render.cc
|
@ -77,132 +77,6 @@ void register_builtin_render()
|
|||
builtin_modules["render"] = new RenderModule();
|
||||
}
|
||||
|
||||
// FIXME: #ifdef ENABLE_CGAL
|
||||
#if 0
|
||||
CSGTerm *AbstractNode::render_csg_term_from_nef(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, const char *statement, int convexity) const
|
||||
{
|
||||
QString key = mk_cache_id();
|
||||
if (PolySet::ps_cache.contains(key)) {
|
||||
PRINT(PolySet::ps_cache[key]->msg);
|
||||
return AbstractPolyNode::render_csg_term_from_ps(m, highlights, background,
|
||||
PolySet::ps_cache[key]->ps->link(), modinst, idx);
|
||||
}
|
||||
|
||||
print_messages_push();
|
||||
CGAL_Nef_polyhedron N;
|
||||
|
||||
QString cache_id = mk_cache_id();
|
||||
if (cgal_nef_cache.contains(cache_id))
|
||||
{
|
||||
PRINT(cgal_nef_cache[cache_id]->msg);
|
||||
N = cgal_nef_cache[cache_id]->N;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF_NOCACHE("Processing uncached %s statement...", statement);
|
||||
// PRINTA("Cache ID: %1", cache_id);
|
||||
QApplication::processEvents();
|
||||
|
||||
QTime t;
|
||||
t.start();
|
||||
|
||||
N = this->renderCSGMesh();
|
||||
|
||||
int s = t.elapsed() / 1000;
|
||||
PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
|
||||
}
|
||||
|
||||
PolySet *ps = NULL;
|
||||
|
||||
if (N.dim == 2)
|
||||
{
|
||||
DxfData dd(N);
|
||||
ps = new PolySet();
|
||||
ps->is2d = true;
|
||||
dxf_tesselate(ps, &dd, 0, true, false, 0);
|
||||
dxf_border_to_ps(ps, &dd);
|
||||
}
|
||||
|
||||
if (N.dim == 3)
|
||||
{
|
||||
if (!N.p3.is_simple()) {
|
||||
PRINTF("WARNING: Result of %s() isn't valid 2-manifold! Modify your design..", statement);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ps = new PolySet();
|
||||
|
||||
CGAL_Polyhedron P;
|
||||
N.p3.convert_to_Polyhedron(P);
|
||||
|
||||
typedef CGAL_Polyhedron::Vertex Vertex;
|
||||
typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
|
||||
typedef CGAL_Polyhedron::Facet_const_iterator FCI;
|
||||
typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC;
|
||||
|
||||
for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
|
||||
HFCC hc = fi->facet_begin();
|
||||
HFCC hc_end = hc;
|
||||
ps->append_poly();
|
||||
do {
|
||||
Vertex v = *VCI((hc++)->vertex());
|
||||
double x = CGAL::to_double(v.point().x());
|
||||
double y = CGAL::to_double(v.point().y());
|
||||
double z = CGAL::to_double(v.point().z());
|
||||
ps->append_vertex(x, y, z);
|
||||
} while (hc != hc_end);
|
||||
}
|
||||
}
|
||||
|
||||
if (ps)
|
||||
{
|
||||
ps->convexity = convexity;
|
||||
PolySet::ps_cache.insert(key, new PolySet::ps_cache_entry(ps->link()));
|
||||
|
||||
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) {
|
||||
background->append(term);
|
||||
return NULL;
|
||||
}
|
||||
return term;
|
||||
}
|
||||
print_messages_pop();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
return render_csg_term_from_nef(m, highlights, background, "render", this->convexity);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
CSGTerm *t1 = NULL;
|
||||
PRINT("WARNING: Found render() statement but compiled without CGAL support!");
|
||||
foreach(AbstractNode * v, children) {
|
||||
CSGTerm *t2 = v->render_csg_term(m, highlights, background);
|
||||
if (t2 && !t1) {
|
||||
t1 = t2;
|
||||
} else if (t2 && t1) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
|
||||
}
|
||||
}
|
||||
if (modinst->tag_highlight && highlights)
|
||||
highlights->append(t1->link());
|
||||
if (t1 && modinst->tag_background && background) {
|
||||
background->append(t1);
|
||||
return NULL;
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::string RenderNode::toString() const
|
||||
{
|
||||
std::stringstream stream;
|
||||
|
|
|
@ -14,7 +14,6 @@ public:
|
|||
virtual std::string toString() const;
|
||||
|
||||
int convexity;
|
||||
CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -228,41 +228,6 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
|
|||
return node;
|
||||
}
|
||||
|
||||
CSGTerm *TransformNode::render_csg_term(double c[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
|
||||
{
|
||||
double x[20];
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int c_row = i%4;
|
||||
int m_col = i/4;
|
||||
x[i] = 0;
|
||||
for (int j = 0; j < 4; j++)
|
||||
x[i] += c[c_row + j*4] * m[m_col*4 + j];
|
||||
}
|
||||
|
||||
for (int i = 16; i < 20; i++)
|
||||
x[i] = m[i] < 0 ? c[i] : m[i];
|
||||
|
||||
CSGTerm *t1 = NULL;
|
||||
foreach(AbstractNode *v, children)
|
||||
{
|
||||
CSGTerm *t2 = v->render_csg_term(x, highlights, background);
|
||||
if (t2 && !t1) {
|
||||
t1 = t2;
|
||||
} else if (t2 && t1) {
|
||||
t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
|
||||
}
|
||||
}
|
||||
if (t1 && modinst->tag_highlight && highlights)
|
||||
highlights->append(t1->link());
|
||||
if (t1 && modinst->tag_background && background) {
|
||||
background->append(t1);
|
||||
return NULL;
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
std::string TransformNode::toString() const
|
||||
{
|
||||
std::stringstream stream;
|
||||
|
|
|
@ -14,7 +14,6 @@ public:
|
|||
virtual std::string toString() const;
|
||||
|
||||
double m[20];
|
||||
virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* OpenSCAD (www.openscad.at)
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* As a special exception, you have permission to link this program
|
||||
* with the CGAL library and distribute executables, as long as you
|
||||
* follow the requirements of the GNU GPL in regard to all of the
|
||||
* software in the executable aside from CGAL.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "CSGTextRenderer.h"
|
||||
#include "CSGTextCache.h"
|
||||
#include "openscad.h"
|
||||
#include "node.h"
|
||||
#include "module.h"
|
||||
#include "context.h"
|
||||
#include "value.h"
|
||||
#include "export.h"
|
||||
#include "builtin.h"
|
||||
#include "Tree.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QSet>
|
||||
#include <getopt.h>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
QString commandline_commands;
|
||||
const char *make_command = NULL;
|
||||
QSet<QString> dependencies;
|
||||
QString currentdir;
|
||||
QString examplesdir;
|
||||
QString librarydir;
|
||||
|
||||
void handle_dep(QString filename)
|
||||
{
|
||||
if (filename.startsWith("/"))
|
||||
dependencies.insert(filename);
|
||||
else
|
||||
dependencies.insert(QDir::currentPath() + QString("/") + filename);
|
||||
if (!QFile(filename).exists() && make_command) {
|
||||
char buffer[4096];
|
||||
snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data());
|
||||
system(buffer); // FIXME: Handle error
|
||||
}
|
||||
}
|
||||
|
||||
void csgTree(CSGTextCache &cache, const AbstractNode &root)
|
||||
{
|
||||
CSGTextRenderer renderer(cache);
|
||||
Traverser render(renderer, root, Traverser::PRE_AND_POSTFIX);
|
||||
render.execute();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <file.scad>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const char *filename = argv[1];
|
||||
|
||||
int rc = 0;
|
||||
|
||||
initialize_builtin_functions();
|
||||
initialize_builtin_modules();
|
||||
|
||||
QApplication app(argc, argv, false);
|
||||
QDir original_path = QDir::current();
|
||||
|
||||
currentdir = QDir::currentPath();
|
||||
|
||||
QDir libdir(QApplication::instance()->applicationDirPath());
|
||||
#ifdef Q_WS_MAC
|
||||
libdir.cd("../Resources"); // Libraries can be bundled
|
||||
if (!libdir.exists("libraries")) libdir.cd("../../..");
|
||||
#elif defined(Q_OS_UNIX)
|
||||
if (libdir.cd("../share/openscad/libraries")) {
|
||||
librarydir = libdir.path();
|
||||
} else
|
||||
if (libdir.cd("../../share/openscad/libraries")) {
|
||||
librarydir = libdir.path();
|
||||
} else
|
||||
if (libdir.cd("../../libraries")) {
|
||||
librarydir = libdir.path();
|
||||
} else
|
||||
#endif
|
||||
if (libdir.cd("libraries")) {
|
||||
librarydir = libdir.path();
|
||||
}
|
||||
|
||||
Context root_ctx;
|
||||
root_ctx.functions_p = &builtin_functions;
|
||||
root_ctx.modules_p = &builtin_modules;
|
||||
root_ctx.set_variable("$fn", Value(0.0));
|
||||
root_ctx.set_variable("$fs", Value(1.0));
|
||||
root_ctx.set_variable("$fa", Value(12.0));
|
||||
root_ctx.set_variable("$t", Value(0.0));
|
||||
|
||||
Value zero3;
|
||||
zero3.type = Value::VECTOR;
|
||||
zero3.vec.append(new Value(0.0));
|
||||
zero3.vec.append(new Value(0.0));
|
||||
zero3.vec.append(new Value(0.0));
|
||||
root_ctx.set_variable("$vpt", zero3);
|
||||
root_ctx.set_variable("$vpr", zero3);
|
||||
|
||||
|
||||
AbstractModule *root_module;
|
||||
ModuleInstantiation root_inst;
|
||||
AbstractNode *root_node;
|
||||
|
||||
QFileInfo fileInfo(filename);
|
||||
handle_dep(filename);
|
||||
FILE *fp = fopen(filename, "rt");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Can't open input file `%s'!\n", filename);
|
||||
exit(1);
|
||||
} else {
|
||||
QString text;
|
||||
char buffer[513];
|
||||
int ret;
|
||||
while ((ret = fread(buffer, 1, 512, fp)) > 0) {
|
||||
buffer[ret] = 0;
|
||||
text += buffer;
|
||||
}
|
||||
fclose(fp);
|
||||
root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false);
|
||||
if (!root_module) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
QDir::setCurrent(fileInfo.absolutePath());
|
||||
|
||||
AbstractNode::resetIndexCounter();
|
||||
root_node = root_module->evaluate(&root_ctx, &root_inst);
|
||||
|
||||
Tree tree;
|
||||
tree.setRoot(root_node);
|
||||
|
||||
|
||||
|
||||
|
||||
destroy_builtin_functions();
|
||||
destroy_builtin_modules();
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
DEFINES += OPENSCAD_VERSION=test
|
||||
TEMPLATE = app
|
||||
|
||||
OBJECTS_DIR = objects
|
||||
MOC_DIR = objects
|
||||
UI_DIR = objects
|
||||
RCC_DIR = objects
|
||||
INCLUDEPATH += ../src
|
||||
|
||||
macx {
|
||||
CONFIG -= app_bundle
|
||||
LIBS += -framework Carbon
|
||||
}
|
||||
|
||||
CONFIG += qt
|
||||
QT += opengl
|
||||
|
||||
# Optionally specify location of Eigen2 using the
|
||||
# EIGEN2DIR env. variable
|
||||
EIGEN2_DIR = $$(EIGEN2DIR)
|
||||
!isEmpty(EIGEN2_DIR) {
|
||||
INCLUDEPATH += $$EIGEN2_DIR
|
||||
}
|
||||
else {
|
||||
macx {
|
||||
INCLUDEPATH += /opt/local/include/eigen2
|
||||
}
|
||||
else {
|
||||
INCLUDEPATH += /usr/include/eigen2
|
||||
}
|
||||
}
|
||||
|
||||
LEXSOURCES += ../src/lexer.l
|
||||
YACCSOURCES += ../src/parser.y
|
||||
|
||||
HEADERS += ../src/builtin.h \
|
||||
../src/context.h \
|
||||
../src/csgterm.h \
|
||||
../src/dxfdata.h \
|
||||
../src/dxfdim.h \
|
||||
../src/dxftess.h \
|
||||
../src/export.h \
|
||||
../src/expression.h \
|
||||
../src/function.h \
|
||||
../src/grid.h \
|
||||
../src/module.h \
|
||||
../src/node.h \
|
||||
../src/dxflinextrudenode.h \
|
||||
../src/dxfrotextrudenode.h \
|
||||
../src/projectionnode.h \
|
||||
../src/importnode.h \
|
||||
../src/csgnode.h \
|
||||
../src/transformnode.h \
|
||||
../src/rendernode.h \
|
||||
../src/openscad.h \
|
||||
../src/polyset.h \
|
||||
../src/printutils.h \
|
||||
../src/value.h \
|
||||
../src/progress.h \
|
||||
../src/traverser.h \
|
||||
../src/csgnode.h \
|
||||
../src/visitor.h \
|
||||
../src/nodedumper.h \
|
||||
../src/nodecache.h \
|
||||
../src/importnode.h \
|
||||
../src/state.h \
|
||||
../src/PolySetRenderer.h \
|
||||
../src/Tree.h \
|
||||
../src/myqhash.h \
|
||||
../src/CSGTermRenderer.h
|
||||
|
||||
SOURCES += csgtexttest.cc \
|
||||
../src/export.cc \
|
||||
../src/value.cc \
|
||||
../src/expr.cc \
|
||||
../src/func.cc \
|
||||
../src/module.cc \
|
||||
../src/node.cc \
|
||||
../src/context.cc \
|
||||
../src/csgterm.cc \
|
||||
../src/polyset.cc \
|
||||
../src/csgops.cc \
|
||||
../src/transform.cc \
|
||||
../src/primitives.cc \
|
||||
../src/projection.cc \
|
||||
../src/cgaladv.cc \
|
||||
../src/surface.cc \
|
||||
../src/control.cc \
|
||||
../src/render.cc \
|
||||
../src/import.cc \
|
||||
../src/dxfdata.cc \
|
||||
../src/dxftess.cc \
|
||||
../src/dxftess-glu.cc \
|
||||
../src/dxftess-cgal.cc \
|
||||
../src/dxfdim.cc \
|
||||
../src/dxflinextrude.cc \
|
||||
../src/dxfrotextrude.cc \
|
||||
../src/printutils.cc \
|
||||
../src/progress.cc \
|
||||
../src/nodedumper.cc \
|
||||
../src/traverser.cc \
|
||||
../src/PolySetRenderer.cc \
|
||||
../src/Tree.cc \
|
||||
../src/qhash.cc \
|
||||
../src/CSGTermRenderer.cc
|
Loading…
Reference in New Issue