mirror of https://github.com/vitalif/openscad
Refactoring: Moved color functionality into separate module and node
parent
287c20d2ff
commit
ed8a99ed55
|
@ -144,6 +144,7 @@ HEADERS += src/renderer.h \
|
|||
src/projectionnode.h \
|
||||
src/importnode.h \
|
||||
src/transformnode.h \
|
||||
src/colornode.h \
|
||||
src/rendernode.h \
|
||||
src/openscad.h \
|
||||
src/polyset.h \
|
||||
|
@ -178,6 +179,7 @@ SOURCES += src/openscad.cc \
|
|||
src/polyset.cc \
|
||||
src/csgops.cc \
|
||||
src/transform.cc \
|
||||
src/color.cc \
|
||||
src/primitives.cc \
|
||||
src/projection.cc \
|
||||
src/cgaladv.cc \
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "module.h"
|
||||
#include "csgnode.h"
|
||||
#include "transformnode.h"
|
||||
#include "colornode.h"
|
||||
#include "rendernode.h"
|
||||
#include "printutils.h"
|
||||
|
||||
|
@ -82,14 +83,14 @@ Response CSGTermEvaluator::visit(State &state, const AbstractIntersectionNode &n
|
|||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
static CSGTerm *evaluate_csg_term_from_ps(const double m[20],
|
||||
static CSGTerm *evaluate_csg_term_from_ps(const State &state,
|
||||
vector<CSGTerm*> &highlights,
|
||||
vector<CSGTerm*> &background,
|
||||
PolySet *ps,
|
||||
const ModuleInstantiation *modinst,
|
||||
const AbstractPolyNode &node)
|
||||
{
|
||||
CSGTerm *t = new CSGTerm(ps, m, QString("%1%2").arg(node.name().c_str()).arg(node.index()));
|
||||
CSGTerm *t = new CSGTerm(ps, state.matrix(), state.color(), QString("%1%2").arg(node.name().c_str()).arg(node.index()));
|
||||
if (modinst->tag_highlight)
|
||||
highlights.push_back(t->link());
|
||||
if (modinst->tag_background) {
|
||||
|
@ -105,7 +106,7 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node)
|
|||
CSGTerm *t1 = NULL;
|
||||
PolySet *ps = node.evaluate_polyset(AbstractPolyNode::RENDER_OPENCSG, this->psevaluator);
|
||||
if (ps) {
|
||||
t1 = evaluate_csg_term_from_ps(state.matrix(), this->highlights, this->background,
|
||||
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
|
||||
ps, node.modinst, node);
|
||||
}
|
||||
this->stored_term[node.index()] = t1;
|
||||
|
@ -138,7 +139,7 @@ Response CSGTermEvaluator::visit(State &state, const CsgNode &node)
|
|||
Response CSGTermEvaluator::visit(State &state, const TransformNode &node)
|
||||
{
|
||||
if (state.isPrefix()) {
|
||||
double m[20];
|
||||
double m[16];
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
|
@ -149,11 +150,6 @@ Response CSGTermEvaluator::visit(State &state, const TransformNode &node)
|
|||
m[i] += state.matrix()[c_row + j*4] * node.matrix[m_col*4 + j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 16; i < 20; i++) {
|
||||
m[i] = node.matrix[i] < 0 ? state.matrix()[i] : node.matrix[i];
|
||||
}
|
||||
|
||||
state.setMatrix(m);
|
||||
}
|
||||
if (state.isPostfix()) {
|
||||
|
@ -163,6 +159,18 @@ Response CSGTermEvaluator::visit(State &state, const TransformNode &node)
|
|||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
Response CSGTermEvaluator::visit(State &state, const ColorNode &node)
|
||||
{
|
||||
if (state.isPrefix()) {
|
||||
state.setColor(node.color);
|
||||
}
|
||||
if (state.isPostfix()) {
|
||||
applyToChildren(node, CSGT_UNION);
|
||||
addToParent(state, node);
|
||||
}
|
||||
return ContinueTraversal;
|
||||
}
|
||||
|
||||
// FIXME: If we've got CGAL support, render this node as a CGAL union into a PolySet
|
||||
Response CSGTermEvaluator::visit(State &state, const RenderNode &node)
|
||||
{
|
||||
|
@ -186,168 +194,3 @@ void CSGTermEvaluator::addToParent(const State &state, const AbstractNode &node)
|
|||
this->visitedchildren[state.parent()->index()].push_back(&node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
// FIXME: #ifdef ENABLE_CGAL
|
||||
#if 0
|
||||
CSGTerm *CgaladvNode::evaluate_csg_term(double m[20], QVector<CSGTerm*> &highlights, QVector<CSGTerm*> &background) const
|
||||
{
|
||||
if (type == MINKOWSKI)
|
||||
return evaluate_csg_term_from_nef(m, highlights, background, "minkowski", this->convexity);
|
||||
|
||||
if (type == GLIDE)
|
||||
return evaluate_csg_term_from_nef(m, highlights, background, "glide", this->convexity);
|
||||
|
||||
if (type == SUBDIV)
|
||||
return evaluate_csg_term_from_nef(m, highlights, background, "subdiv", this->convexity);
|
||||
|
||||
if (type == HULL)
|
||||
return evaluate_csg_term_from_nef(m, highlights, background, "hull", this->convexity);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else // ENABLE_CGAL
|
||||
|
||||
CSGTerm *CgaladvNode::evaluate_csg_term(double m[20], QVector<CSGTerm*> &highlights, QVector<CSGTerm*> &background) const
|
||||
{
|
||||
PRINT("WARNING: Found minkowski(), glide(), subdiv() or hull() statement but compiled without CGAL support!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // ENABLE_CGAL
|
||||
|
||||
|
||||
|
||||
// FIXME: #ifdef ENABLE_CGAL
|
||||
#if 0
|
||||
CSGTerm *AbstractNode::evaluate_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::evaluate_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->evaluateCSGMesh();
|
||||
|
||||
int s = t.elapsed() / 1000;
|
||||
PRINTF_NOCACHE("..processing 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.push_back(term->link());
|
||||
if (modinst->tag_background) {
|
||||
background.push_back(term);
|
||||
return NULL;
|
||||
}
|
||||
return term;
|
||||
}
|
||||
print_messages_pop();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CSGTerm *RenderNode::evaluate_csg_term(double m[20], QVector<CSGTerm*> &highlights, QVector<CSGTerm*> &background) const
|
||||
{
|
||||
return evaluate_csg_term_from_nef(m, highlights, background, "render", this->convexity);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CSGTerm *RenderNode::evaluate_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->evaluate_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.push_back(t1->link());
|
||||
if (t1 && modinst->tag_background) {
|
||||
background.push_back(t1);
|
||||
return NULL;
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
virtual Response visit(State &state, const AbstractPolyNode &node);
|
||||
virtual Response visit(State &state, const CsgNode &node);
|
||||
virtual Response visit(State &state, const TransformNode &node);
|
||||
virtual Response visit(State &state, const ColorNode &node);
|
||||
virtual Response visit(State &state, const RenderNode &node);
|
||||
|
||||
class CSGTerm *evaluateCSGTerm(const AbstractNode &node,
|
||||
|
|
|
@ -85,6 +85,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
|
|||
if (shaderinfo) glUseProgram(shaderinfo[0]);
|
||||
for (; j < i; j++) {
|
||||
double *m = chain->matrices[j];
|
||||
double *c = chain->colors[j];
|
||||
glPushMatrix();
|
||||
glMultMatrixd(m);
|
||||
int csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
|
||||
|
@ -92,12 +93,12 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
|
|||
chain->polysets[j]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m, shaderinfo);
|
||||
} else if (background) {
|
||||
chain->polysets[j]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m, shaderinfo);
|
||||
} else if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0 || m[19] >= 0) {
|
||||
} else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) {
|
||||
// User-defined color from source
|
||||
glColor4d(m[16], m[17], m[18], m[19]);
|
||||
glColor4dv(c);
|
||||
if (shaderinfo) {
|
||||
glUniform4f(shaderinfo[1], m[16], m[17], m[18], m[19]);
|
||||
glUniform4f(shaderinfo[2], (m[16]+1)/2, (m[17]+1)/2, (m[18]+1)/2, 1.0);
|
||||
glUniform4f(shaderinfo[1], c[0], c[1], c[2], c[3]);
|
||||
glUniform4f(shaderinfo[2], (c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0);
|
||||
}
|
||||
chain->polysets[j]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m, shaderinfo);
|
||||
} else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) {
|
||||
|
|
|
@ -66,6 +66,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,
|
|||
if (polySetVisitMark[QPair<PolySet*,double*>(chain->polysets[i], chain->matrices[i])]++ > 0)
|
||||
continue;
|
||||
double *m = chain->matrices[i];
|
||||
double *c = chain->colors[i];
|
||||
glPushMatrix();
|
||||
glMultMatrixd(m);
|
||||
int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
|
||||
|
@ -91,12 +92,12 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,
|
|||
} else {
|
||||
chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
|
||||
}
|
||||
} else if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0 || m[19] >= 0) {
|
||||
glColor4d(m[16], m[17], m[18], m[19]);
|
||||
} else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) {
|
||||
glColor4dv(c);
|
||||
chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
|
||||
if (showedges) {
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4d((m[16]+1)/2, (m[17]+1)/2, (m[18]+1)/2, 1.0);
|
||||
glColor4d((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0);
|
||||
chain->polysets[i]->render_edges(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode));
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ extern void destroy_builtin_modules();
|
|||
|
||||
extern void register_builtin_csgops();
|
||||
extern void register_builtin_transform();
|
||||
extern void register_builtin_color();
|
||||
extern void register_builtin_primitives();
|
||||
extern void register_builtin_surface();
|
||||
extern void register_builtin_control();
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* OpenSCAD (www.openscad.org)
|
||||
* Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
|
||||
* Marius Kintel <marius@kintel.net>
|
||||
*
|
||||
* 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 "colornode.h"
|
||||
#include "module.h"
|
||||
#include "context.h"
|
||||
#include "builtin.h"
|
||||
#include "printutils.h"
|
||||
#include "visitor.h"
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
#include <QColor>
|
||||
|
||||
class ColorModule : public AbstractModule
|
||||
{
|
||||
public:
|
||||
ColorModule() { }
|
||||
virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const;
|
||||
};
|
||||
|
||||
using std::string;
|
||||
|
||||
AbstractNode *ColorModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const
|
||||
{
|
||||
ColorNode *node = new ColorNode(inst);
|
||||
|
||||
for (int i = 0; i < 4; i++) node->color[i] = -1;
|
||||
|
||||
QVector<QString> argnames;
|
||||
QVector<Expression*> argexpr;
|
||||
|
||||
argnames = QVector<QString>() << "c" << "alpha";
|
||||
|
||||
Context c(ctx);
|
||||
c.args(argnames, argexpr, inst->argnames, inst->argvalues);
|
||||
|
||||
Value v = c.lookup_variable("c");
|
||||
if (v.type == Value::VECTOR) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
node->color[i] = i < v.vec.size() ? v.vec[i]->num : 1.0;
|
||||
} else if (v.type == Value::STRING) {
|
||||
QString colorname = QString::fromStdString(v.text);
|
||||
QColor color;
|
||||
color.setNamedColor(colorname);
|
||||
if (color.isValid()) {
|
||||
node->color[0] = color.redF();
|
||||
node->color[1] = color.greenF();
|
||||
node->color[2] = color.blueF();
|
||||
} else {
|
||||
PRINTA_NOCACHE("WARNING: Color name \"%1\" unknown. Please see", colorname);
|
||||
PRINTF_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors");
|
||||
}
|
||||
}
|
||||
Value alpha = c.lookup_variable("alpha");
|
||||
if (alpha.type == Value::NUMBER) {
|
||||
node->color[3] = alpha.num;
|
||||
}
|
||||
|
||||
foreach (ModuleInstantiation *v, inst->children) {
|
||||
AbstractNode *n = v->evaluate(inst->ctx);
|
||||
if (n != NULL)
|
||||
node->children.push_back(n);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
string ColorNode::toString() const
|
||||
{
|
||||
std::stringstream stream;
|
||||
|
||||
stream << "color([" << this->color[0] << ", " << this->color[1] << ", " << this->color[2] << ", " << this->color[3] << "])";
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
string ColorNode::name() const
|
||||
{
|
||||
return "color";
|
||||
}
|
||||
|
||||
void register_builtin_color()
|
||||
{
|
||||
builtin_modules["color"] = new ColorModule();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef COLORNODE_H_
|
||||
#define COLORNODE_H_
|
||||
|
||||
#include "node.h"
|
||||
#include "visitor.h"
|
||||
|
||||
class ColorNode : public AbstractNode
|
||||
{
|
||||
public:
|
||||
ColorNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }
|
||||
virtual Response accept(class State &state, Visitor &visitor) const {
|
||||
return visitor.visit(state, *this);
|
||||
}
|
||||
virtual std::string toString() const;
|
||||
virtual std::string name() const;
|
||||
|
||||
double color[4];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -46,15 +46,15 @@
|
|||
*/
|
||||
|
||||
|
||||
CSGTerm::CSGTerm(PolySet *polyset, const double m[20], QString label)
|
||||
CSGTerm::CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], QString label)
|
||||
{
|
||||
this->type = TYPE_PRIMITIVE;
|
||||
this->polyset = polyset;
|
||||
this->label = label;
|
||||
this->left = NULL;
|
||||
this->right = NULL;
|
||||
for (int i = 0; i < 20; i++)
|
||||
this->m[i] = m[i];
|
||||
for (int i = 0; i < 16; i++) this->m[i] = matrix[i];
|
||||
for (int i = 0; i < 4; i++) this->color[i] = color[i];
|
||||
refcounter = 1;
|
||||
}
|
||||
|
||||
|
@ -191,10 +191,11 @@ CSGChain::CSGChain()
|
|||
{
|
||||
}
|
||||
|
||||
void CSGChain::add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label)
|
||||
void CSGChain::add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, QString label)
|
||||
{
|
||||
polysets.append(polyset);
|
||||
matrices.append(m);
|
||||
colors.append(color);
|
||||
types.append(type);
|
||||
labels.append(label);
|
||||
}
|
||||
|
@ -202,7 +203,7 @@ void CSGChain::add(PolySet *polyset, double *m, CSGTerm::type_e type, QString la
|
|||
void CSGChain::import(CSGTerm *term, CSGTerm::type_e type)
|
||||
{
|
||||
if (term->type == CSGTerm::TYPE_PRIMITIVE) {
|
||||
add(term->polyset, term->m, type, term->label);
|
||||
add(term->polyset, term->m, term->color, type, term->label);
|
||||
} else {
|
||||
import(term->left, type);
|
||||
import(term->right, term->type);
|
||||
|
|
|
@ -20,10 +20,11 @@ public:
|
|||
QString label;
|
||||
CSGTerm *left;
|
||||
CSGTerm *right;
|
||||
double m[20];
|
||||
double m[16];
|
||||
double color[4];
|
||||
int refcounter;
|
||||
|
||||
CSGTerm(PolySet *polyset, const double m[20], QString label);
|
||||
CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], QString label);
|
||||
CSGTerm(type_e type, CSGTerm *left, CSGTerm *right);
|
||||
|
||||
CSGTerm *normalize();
|
||||
|
@ -39,12 +40,13 @@ class CSGChain
|
|||
public:
|
||||
QVector<PolySet*> polysets;
|
||||
QVector<double*> matrices;
|
||||
QVector<double*> colors;
|
||||
QVector<CSGTerm::type_e> types;
|
||||
QVector<QString> labels;
|
||||
|
||||
CSGChain();
|
||||
|
||||
void add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label);
|
||||
void add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, QString label);
|
||||
void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION);
|
||||
QString dump();
|
||||
|
||||
|
|
|
@ -206,6 +206,7 @@ void initialize_builtin_modules()
|
|||
|
||||
register_builtin_csgops();
|
||||
register_builtin_transform();
|
||||
register_builtin_color();
|
||||
register_builtin_primitives();
|
||||
register_builtin_surface();
|
||||
register_builtin_control();
|
||||
|
|
11
src/state.h
11
src/state.h
|
@ -9,7 +9,7 @@ public:
|
|||
State(const class AbstractNode *parent)
|
||||
: parentnode(parent), isprefix(false), ispostfix(false), numchildren(0) {
|
||||
for (int i=0;i<16;i++) this->m[i] = i % 5 == 0 ? 1.0 : 0.0;
|
||||
for (int i=16;i<20;i++) this->m[i] = -1.0;
|
||||
for (int i=0;i<4;i++) this->c[i] = -1.0;
|
||||
}
|
||||
virtual ~State() {}
|
||||
|
||||
|
@ -17,13 +17,15 @@ public:
|
|||
void setPostfix(bool on) { this->ispostfix = on; }
|
||||
void setNumChildren(unsigned int numc) { this->numchildren = numc; }
|
||||
void setParent(const AbstractNode *parent) { this->parentnode = parent; }
|
||||
void setMatrix(const double m[20]) { memcpy(this->m, m, 20*sizeof(m)); }
|
||||
void setMatrix(const double m[16]) { memcpy(this->m, m, 16*sizeof(double)); }
|
||||
void setColor(const double c[4]) { memcpy(this->c, c, 4*sizeof(double)); }
|
||||
|
||||
bool isPrefix() const { return this->isprefix; }
|
||||
bool isPostfix() const { return this->ispostfix; }
|
||||
unsigned int numChildren() const { return this->numchildren; }
|
||||
const AbstractNode *parent() const { return this->parentnode; }
|
||||
const double *matrix() const { return this->m; }
|
||||
const double *color() const { return this->c; }
|
||||
|
||||
private:
|
||||
const AbstractNode * parentnode;
|
||||
|
@ -31,8 +33,9 @@ private:
|
|||
bool ispostfix;
|
||||
unsigned int numchildren;
|
||||
|
||||
// Transformation matrix incl. color. FIXME: Generalize such state variables?
|
||||
double m[20];
|
||||
// Transformation matrix and color. FIXME: Generalize such state variables?
|
||||
double m[16];
|
||||
double c[4];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,8 +43,7 @@ enum transform_type_e {
|
|||
ROTATE,
|
||||
MIRROR,
|
||||
TRANSLATE,
|
||||
MULTMATRIX,
|
||||
COLOR
|
||||
MULTMATRIX
|
||||
};
|
||||
|
||||
class TransformModule : public AbstractModule
|
||||
|
@ -86,8 +85,6 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
|
|||
|
||||
for (int i = 0; i < 16; i++)
|
||||
node->matrix[i] = i % 5 == 0 ? 1.0 : 0.0;
|
||||
for (int i = 16; i < 20; i++)
|
||||
node->matrix[i] = -1;
|
||||
|
||||
QVector<QString> argnames;
|
||||
QVector<Expression*> argexpr;
|
||||
|
@ -108,9 +105,6 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
|
|||
case MULTMATRIX:
|
||||
argnames = QVector<QString>() << "m";
|
||||
break;
|
||||
case COLOR:
|
||||
argnames = QVector<QString>() << "c" << "alpha";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
@ -242,36 +236,6 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (this->type == COLOR)
|
||||
{
|
||||
Value v = c.lookup_variable("c");
|
||||
if (v.type == Value::VECTOR) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
node->matrix[16+i] = i < v.vec.size() ? v.vec[i]->num : 1.0;
|
||||
// FIXME: Port to non-Qt
|
||||
#if 0
|
||||
} else if (v.type == Value::STRING) {
|
||||
QString colorname = v.text;
|
||||
QColor color;
|
||||
color.setNamedColor(colorname);
|
||||
if (color.isValid()) {
|
||||
node->matrix[16+0] = color.redF();
|
||||
node->matrix[16+1] = color.greenF();
|
||||
node->matrix[16+2] = color.blueF();
|
||||
} else {
|
||||
PRINTF_NOCACHE("WARNING: Color name \"%s\" unknown. Please see",v.text.toUtf8().data());
|
||||
PRINTF_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// FIXME: Only lookup alpha if color was set
|
||||
Value alpha = c.lookup_variable("alpha");
|
||||
if (alpha.type == Value::NUMBER) {
|
||||
node->matrix[16+3] = alpha.num;
|
||||
} else {
|
||||
node->matrix[16+3] = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ModuleInstantiation *v, inst->children) {
|
||||
AbstractNode *n = v->evaluate(inst->ctx);
|
||||
|
@ -286,23 +250,18 @@ string TransformNode::toString() const
|
|||
{
|
||||
std::stringstream stream;
|
||||
|
||||
if (this->matrix[16] >= 0 || this->matrix[17] >= 0 || this->matrix[18] >= 0 || this->matrix[19] >= 0) {
|
||||
stream << "color([" << this->matrix[16] << ", " << this->matrix[17] << ", " << this->matrix[18] << ", " << this->matrix[19] << "])";
|
||||
}
|
||||
else {
|
||||
stream << "multmatrix([";
|
||||
for (int j=0;j<4;j++) {
|
||||
stream << "[";
|
||||
for (int i=0;i<4;i++) {
|
||||
// FIXME: The 0 test is to avoid a leading minus before a single 0 (cosmetics)
|
||||
stream << ((this->matrix[i*4+j]==0)?0:this->matrix[i*4+j]);
|
||||
if (i != 3) stream << ", ";
|
||||
}
|
||||
stream << "]";
|
||||
if (j != 3) stream << ", ";
|
||||
stream << "multmatrix([";
|
||||
for (int j=0;j<4;j++) {
|
||||
stream << "[";
|
||||
for (int i=0;i<4;i++) {
|
||||
// FIXME: The 0 test is to avoid a leading minus before a single 0 (cosmetics)
|
||||
stream << ((this->matrix[i*4+j]==0)?0:this->matrix[i*4+j]);
|
||||
if (i != 3) stream << ", ";
|
||||
}
|
||||
stream << "])";
|
||||
stream << "]";
|
||||
if (j != 3) stream << ", ";
|
||||
}
|
||||
stream << "])";
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
@ -319,5 +278,4 @@ void register_builtin_transform()
|
|||
builtin_modules["mirror"] = new TransformModule(MIRROR);
|
||||
builtin_modules["translate"] = new TransformModule(TRANSLATE);
|
||||
builtin_modules["multmatrix"] = new TransformModule(MULTMATRIX);
|
||||
builtin_modules["color"] = new TransformModule(COLOR);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public:
|
|||
virtual std::string toString() const;
|
||||
virtual std::string name() const;
|
||||
|
||||
double matrix[20];
|
||||
double matrix[16];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,9 @@ public:
|
|||
virtual Response visit(class State &state, const class TransformNode &node) {
|
||||
return visit(state, (const class AbstractNode &)node);
|
||||
}
|
||||
virtual Response visit(class State &state, const class ColorNode &node) {
|
||||
return visit(state, (const class AbstractNode &)node);
|
||||
}
|
||||
// Add visit() methods for new visitable subtypes of AbstractNode here
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue