summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--csgterm.cc6
-rw-r--r--expr.cc2
-rw-r--r--mainwin.cc4
-rw-r--r--openscad.h6
-rw-r--r--polyset.cc17
-rw-r--r--transform.cc161
-rw-r--r--value.cc2
7 files changed, 170 insertions, 28 deletions
diff --git a/csgterm.cc b/csgterm.cc
index c1c6e14..6835f40 100644
--- a/csgterm.cc
+++ b/csgterm.cc
@@ -22,15 +22,13 @@
#include "openscad.h"
-CSGTerm::CSGTerm(PolySet *polyset, QString label, double m[16])
+CSGTerm::CSGTerm(PolySet *polyset, 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;
}
@@ -40,8 +38,6 @@ CSGTerm::CSGTerm(type_e type, CSGTerm *left, CSGTerm *right)
this->polyset = NULL;
this->left = left;
this->right = right;
- for (int i=0; i<16; i++)
- this->m[i] = 0;
refcounter = 1;
}
diff --git a/expr.cc b/expr.cc
index 759cc96..0706d33 100644
--- a/expr.cc
+++ b/expr.cc
@@ -87,7 +87,7 @@ Value Expression::evaluate(const Context *context) const
Value v = children[i]->evaluate(context);
if (v.type != Value::NUMBER)
return Value();
- m[i] = v.num;
+ m[i == 15 ? 15 : (i*4) % 15] = v.num;
}
return Value(m);
}
diff --git a/mainwin.cc b/mainwin.cc
index 2d482a0..32650f3 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -255,6 +255,10 @@ void MainWindow::actionCompile()
}
double m[16];
+
+ for (int i = 0; i < 16; i++)
+ m[i] = i % 5 == 0 ? 1.0 : 0.0;
+
root_raw_term = root_node->render_csg_term(m);
if (!root_raw_term) {
diff --git a/openscad.h b/openscad.h
index 67e079e..f775235 100644
--- a/openscad.h
+++ b/openscad.h
@@ -301,6 +301,7 @@ public:
};
typedef QList<Point> Polygon;
QVector<Polygon> polygons;
+ double m[16];
PolySet();
@@ -308,6 +309,8 @@ public:
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,
@@ -338,9 +341,8 @@ public:
CSGTerm *left;
CSGTerm *right;
int refcounter;
- double m[16];
- CSGTerm(PolySet *polyset, QString label, double m[16]);
+ CSGTerm(PolySet *polyset, QString label);
CSGTerm(type_e type, CSGTerm *left, CSGTerm *right);
CSGTerm *normalize();
diff --git a/polyset.cc b/polyset.cc
index 23c890c..f811fa3 100644
--- a/polyset.cc
+++ b/polyset.cc
@@ -24,6 +24,8 @@
PolySet::PolySet()
{
+ for (int i = 0; i < 16; i++)
+ m[i] = i % 5 == 0 ? 1.0 : 0.0;
}
void PolySet::append_poly()
@@ -41,6 +43,12 @@ 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)
{
#ifdef ENABLE_OPENCSG
@@ -75,6 +83,8 @@ 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
@@ -125,10 +135,13 @@ 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)
@@ -142,6 +155,7 @@ void PolySet::render_edges(colormode_e colormode) const
}
glEnd();
}
+ glPopMatrix();
}
#ifdef ENABLE_CGAL
@@ -235,6 +249,7 @@ CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
CSGTerm *AbstractPolyNode::render_csg_term(double m[16]) const
{
PolySet *ps = render_polyset(RENDER_OPENCSG);
- return new CSGTerm(ps, QString("n%1").arg(idx), m);
+ ps->setmatrix(m);
+ return new CSGTerm(ps, QString("n%1").arg(idx));
}
diff --git a/transform.cc b/transform.cc
index 978de53..7ebce98 100644
--- a/transform.cc
+++ b/transform.cc
@@ -22,47 +22,139 @@
#include "openscad.h"
-class TransModule : public AbstractModule
+enum transform_type_e {
+ SCALE,
+ ROTATE,
+ TRANSLATE,
+ MULTMATRIX
+};
+
+class TransformModule : public AbstractModule
{
public:
+ transform_type_e type;
+ TransformModule(transform_type_e type) : type(type) { }
virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const;
};
-class TransNode : public AbstractNode
+class TransformNode : public AbstractNode
{
public:
- double x, y, z;
+ double m[16];
#ifdef ENABLE_CGAL
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
+ virtual CSGTerm *render_csg_term(double m[16]) const;
virtual QString dump(QString indent) const;
};
-AbstractNode *TransModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const
+AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const
{
- TransNode *node = new TransNode();
- if (call_argvalues.size() == 1 && call_argvalues[0].type == Value::VECTOR) {
- node->x = call_argvalues[0].x;
- node->y = call_argvalues[0].y;
- node->z = call_argvalues[0].z;
- } else {
- node->x = 0;
- node->y = 0;
- node->z = 0;
+ TransformNode *node = new TransformNode();
+
+ for (int i = 0; i < 16; i++) {
+ node->m[i] = i % 5 == 0 ? 1.0 : 0.0;
+ }
+
+ QVector<QString> argnames;
+ QVector<Expression*> argexpr;
+
+ if (type == SCALE) {
+ argnames = QVector<QString>() << "v";
+ }
+ if (type == ROTATE) {
+ argnames = QVector<QString>() << "a" << "v";
+ }
+ if (type == TRANSLATE) {
+ argnames = QVector<QString>() << "v";
+ }
+ if (type == MULTMATRIX) {
+ argnames = QVector<QString>() << "m";
+ }
+
+ Context c(ctx);
+ c.args(argnames, argexpr, call_argnames, call_argvalues);
+
+ if (type == SCALE)
+ {
+ Value v = c.lookup_variable("v");
+ if (v.type == Value::NUMBER) {
+ node->m[0] = v.num;
+ node->m[5] = v.num;
+ node->m[10] = v.num;
+ }
+ if (v.type == Value::VECTOR) {
+ node->m[0] = v.x;
+ node->m[5] = v.y;
+ node->m[10] = v.z;
+ }
+ }
+ if (type == ROTATE)
+ {
+ Value val_a = c.lookup_variable("a");
+ Value val_v = c.lookup_variable("v");
+ double a = 0, x = 0, y = 0, z = 1;
+
+ if (val_a.type == Value::NUMBER) {
+ a = val_a.num;
+ }
+
+ if (val_v.type == Value::VECTOR) {
+ x = val_v.x; y = val_v.y; z = val_v.z;
+ double sn = 1.0 / sqrt(x*x + y*y + z*z);
+ x *= sn; y *= sn; z *= sn;
+ }
+
+ double c = cos(a*M_PI/180.0);
+ double s = sin(a*M_PI/180.0);
+
+ node->m[ 0] = x*x*(1-c)+c;
+ node->m[ 1] = y*x*(1-c)+z*s;
+ node->m[ 2] = z*x*(1-c)-y*s;
+
+ node->m[ 4] = x*y*(1-c)-z*s;
+ node->m[ 5] = y*y*(1-c)+c;
+ node->m[ 6] = z*y*(1-c)+x*s;
+
+ node->m[ 8] = x*z*(1-c)+y*s;
+ node->m[ 9] = y*z*(1-c)-x*s;
+ node->m[10] = z*z*(1-c)+c;
}
+ if (type == TRANSLATE)
+ {
+ Value v = c.lookup_variable("v");
+ if (v.type == Value::VECTOR) {
+ node->m[12] = v.x;
+ node->m[13] = v.y;
+ node->m[14] = v.z;
+ }
+ }
+ if (type == MULTMATRIX)
+ {
+ Value v = c.lookup_variable("m");
+ if (v.type == Value::MATRIX) {
+ for (int i = 0; i < 16; i++)
+ node->m[i] = v.m[i];
+ }
+ }
+
foreach (AbstractNode *v, child_nodes)
node->children.append(v);
+
return node;
}
#ifdef ENABLE_CGAL
-CGAL_Nef_polyhedron TransNode::render_cgal_nef_polyhedron() const
+CGAL_Nef_polyhedron TransformNode::render_cgal_nef_polyhedron() const
{
CGAL_Nef_polyhedron N;
foreach (AbstractNode *v, children)
N += v->render_cgal_nef_polyhedron();
- CGAL_Aff_transformation t(CGAL::TRANSLATION, CGAL_Vector(x, y, z));
+ CGAL_Aff_transformation t(
+ 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[15]);
N.transform(t);
progress_report();
return N;
@@ -70,10 +162,40 @@ CGAL_Nef_polyhedron TransNode::render_cgal_nef_polyhedron() const
#endif /* ENABLE_CGAL */
-QString TransNode::dump(QString indent) const
+CSGTerm *TransformNode::render_csg_term(double c[16]) const
+{
+ double x[16];
+
+ 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];
+ }
+
+ CSGTerm *t1 = NULL;
+ foreach(AbstractNode *v, children)
+ {
+ CSGTerm *t2 = v->render_csg_term(x);
+ if (t2 && !t1) {
+ t1 = t2;
+ } else if (t2 && t1) {
+ t1 = new CSGTerm(CSGTerm::UNION, t1, t2);
+ }
+ }
+ return t1;
+}
+
+QString TransformNode::dump(QString indent) const
{
QString text;
- text.sprintf("n%d: trans([%f %f %f])", idx, x, y, z);
+ 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"));
@@ -82,6 +204,9 @@ QString TransNode::dump(QString indent) const
void register_builtin_trans()
{
- builtin_modules["trans"] = new TransModule();
+ builtin_modules["scale"] = new TransformModule(SCALE);
+ builtin_modules["rotate"] = new TransformModule(ROTATE);
+ builtin_modules["translate"] = new TransformModule(TRANSLATE);
+ builtin_modules["multmatrix"] = new TransformModule(MULTMATRIX);
}
diff --git a/value.cc b/value.cc
index e669ef3..4adff51 100644
--- a/value.cc
+++ b/value.cc
@@ -186,7 +186,7 @@ QString Value::dump() const
QString text = "[";
for (int i=0; i<16; i++) {
QString t;
- t.sprintf("%f", m[i]);
+ t.sprintf("%f", m[i == 15 ? 15 : (i*4) % 15]);
if (i % 4 == 0 && i > 0)
text += ";";
if (i > 0)
contact: Jan Huwald // Impressum