Clifford Wolf:

Transforms (scale, rotate, translate, multmatrix)
	Various matrix related fixes



git-svn-id: http://svn.clifford.at/openscad/trunk@29 b57f626f-c46c-0410-a088-ec61d464b74c
stl_dim
clifford 2009-06-26 23:36:23 +00:00
parent 221ae18327
commit 9479f8e77b
7 changed files with 170 additions and 28 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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();

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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)