mirror of https://github.com/vitalif/openscad
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-ec61d464b74cstl_dim
parent
221ae18327
commit
9479f8e77b
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
2
expr.cc
2
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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
17
polyset.cc
17
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));
|
||||
}
|
||||
|
||||
|
|
161
transform.cc
161
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue