summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2010-01-09 17:15:56 (GMT)
committerclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2010-01-09 17:15:56 (GMT)
commitdd817ad903b1c32f594482b8b2ae16ca30f86ef9 (patch)
tree59fe5bf96f276aec9d7b425fbe5d36b3a72ca0a9
parent3b7ba5c69c1a42c3e23de2180b7ec3726daa040b (diff)
Clifford Wolf:
Added mirror statement git-svn-id: http://svn.clifford.at/openscad/trunk@250 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r--mainwin.cc28
-rw-r--r--openscad.h2
-rw-r--r--polyset.cc61
-rw-r--r--transform.cc59
4 files changed, 100 insertions, 50 deletions
diff --git a/mainwin.cc b/mainwin.cc
index f27c225..7433def 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -1160,7 +1160,7 @@ public:
virtual void render() {
glPushMatrix();
glMultMatrixd(m);
- p->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode));
+ p->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
glPopMatrix();
}
};
@@ -1187,20 +1187,20 @@ static void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool hi
glMultMatrixd(m);
int csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
if (highlight) {
- chain->polysets[j]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), 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), shaderinfo);
+ 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) {
glColor4d(m[16], m[17], m[18], m[19]);
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);
}
- chain->polysets[j]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), shaderinfo);
+ chain->polysets[j]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m, shaderinfo);
} else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) {
- chain->polysets[j]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), shaderinfo);
+ chain->polysets[j]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m, shaderinfo);
} else {
- chain->polysets[j]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), shaderinfo);
+ chain->polysets[j]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m, shaderinfo);
}
glPopMatrix();
}
@@ -1414,14 +1414,14 @@ static void renderGLThrownTogetherChain(MainWindow *m, CSGChain *chain, bool hig
glMultMatrixd(m);
int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
if (highlight) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20));
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m);
if (showEdges) {
glDisable(GL_LIGHTING);
chain->polysets[i]->render_edges(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20));
glEnable(GL_LIGHTING);
}
} else if (background) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10));
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m);
if (showEdges) {
glDisable(GL_LIGHTING);
chain->polysets[i]->render_edges(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10));
@@ -1429,15 +1429,15 @@ static void renderGLThrownTogetherChain(MainWindow *m, CSGChain *chain, bool hig
}
} else if (fberror) {
if (highlight) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 20));
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 20), m);
} else if (background) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 10));
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 10), m);
} else {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode));
+ 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]);
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode));
+ 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);
@@ -1445,14 +1445,14 @@ static void renderGLThrownTogetherChain(MainWindow *m, CSGChain *chain, bool hig
glEnable(GL_LIGHTING);
}
} else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode));
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m);
if (showEdges) {
glDisable(GL_LIGHTING);
chain->polysets[i]->render_edges(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode));
glEnable(GL_LIGHTING);
}
} else {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode));
+ chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m);
if (showEdges) {
glDisable(GL_LIGHTING);
chain->polysets[i]->render_edges(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode));
diff --git a/openscad.h b/openscad.h
index 2bfa15e..71dbc02 100644
--- a/openscad.h
+++ b/openscad.h
@@ -571,7 +571,7 @@ public:
static QCache<QString,ps_cache_entry> ps_cache;
- void render_surface(colormode_e colormode, csgmode_e csgmode, GLint *shaderinfo = NULL) const;
+ void render_surface(colormode_e colormode, csgmode_e csgmode, double *m, GLint *shaderinfo = NULL) const;
void render_edges(colormode_e colormode, csgmode_e csgmode) const;
#ifdef ENABLE_CGAL
diff --git a/polyset.cc b/polyset.cc
index a4275fa..31087a1 100644
--- a/polyset.cc
+++ b/polyset.cc
@@ -73,7 +73,7 @@ void PolySet::insert_vertex(double x, double y, double z)
polygons.last().insert(0, Point(x, y, z));
}
-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, double z)
+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, double z, bool mirrored)
{
double ax = p1->x - p0->x, bx = p1->x - p2->x;
double ay = p1->y - p0->y, by = p1->y - p2->y;
@@ -93,28 +93,45 @@ static void gl_draw_triangle(GLint *shaderinfo, const PolySet::Point *p0, const
glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z);
glVertexAttrib3d(shaderinfo[6], 0.0, 1.0, 0.0);
glVertex3d(p0->x, p0->y, p0->z + z);
- glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f);
- glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z);
- glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z);
- glVertexAttrib3d(shaderinfo[6], 0.0, 0.0, 1.0);
- glVertex3d(p1->x, p1->y, p1->z + z);
+ if (!mirrored) {
+ glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f);
+ glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z);
+ glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z);
+ glVertexAttrib3d(shaderinfo[6], 0.0, 0.0, 1.0);
+ glVertex3d(p1->x, p1->y, p1->z + z);
+ }
glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f);
glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z);
glVertexAttrib3d(shaderinfo[5], p1->x, p1->y, p1->z + z);
glVertexAttrib3d(shaderinfo[6], 1.0, 0.0, 0.0);
glVertex3d(p2->x, p2->y, p2->z + z);
+ if (mirrored) {
+ glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f);
+ glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z);
+ glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z);
+ glVertexAttrib3d(shaderinfo[6], 0.0, 0.0, 1.0);
+ glVertex3d(p1->x, p1->y, p1->z + z);
+ }
}
else
#endif
{
glVertex3d(p0->x, p0->y, p0->z + z);
- glVertex3d(p1->x, p1->y, p1->z + z);
+ if (!mirrored)
+ glVertex3d(p1->x, p1->y, p1->z + z);
glVertex3d(p2->x, p2->y, p2->z + z);
+ if (mirrored)
+ glVertex3d(p1->x, p1->y, p1->z + z);
}
}
-void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, GLint *shaderinfo) const
+void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m, GLint *shaderinfo) const
{
+ double m_scale_rotate_det =
+ m[0]*m[5]*m[10] + m[4]*m[9]*m[2] + m[8]*m[1]*m[6] -
+ (m[8]*m[5]*m[2] + m[4]*m[1]*m[10] + m[0]*m[9]*m[6]);
+ bool mirrored = m_scale_rotate_det < 0;
+
if (colormode == COLORMODE_MATERIAL) {
glColor3ub(249, 215, 44);
#ifdef ENABLE_OPENCSG
@@ -166,18 +183,18 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, GLint *sh
const Polygon *poly = &polygons[i];
if (poly->size() == 3) {
if (z < 0) {
- gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(2), &poly->at(1), true, true, true, z);
+ gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(2), &poly->at(1), true, true, true, z, mirrored);
} else {
- gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true, z);
+ gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true, z, mirrored);
}
}
else if (poly->size() == 4) {
if (z < 0) {
- gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(3), &poly->at(1), true, false, true, z);
- gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(1), &poly->at(3), true, false, true, z);
+ gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(3), &poly->at(1), true, false, true, z, mirrored);
+ gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(1), &poly->at(3), true, false, true, z, mirrored);
} else {
- gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true, z);
- gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true, z);
+ gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true, z, mirrored);
+ gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true, z, mirrored);
}
}
else {
@@ -191,10 +208,10 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, GLint *sh
for (int j = 1; j <= poly->size(); j++) {
if (z < 0) {
gl_draw_triangle(shaderinfo, &center, &poly->at(j % poly->size()), &poly->at(j - 1),
- false, true, false, z);
+ false, true, false, z, mirrored);
} else {
gl_draw_triangle(shaderinfo, &center, &poly->at(j - 1), &poly->at(j % poly->size()),
- false, true, false, z);
+ false, true, false, z, mirrored);
}
}
}
@@ -210,8 +227,8 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, GLint *sh
Point p3 = poly->at(j % poly->size()), p4 = poly->at(j % poly->size());
p1.z -= zbase/2, p2.z += zbase/2;
p3.z -= zbase/2, p4.z += zbase/2;
- gl_draw_triangle(shaderinfo, &p2, &p1, &p3, true, true, false, 0);
- gl_draw_triangle(shaderinfo, &p2, &p3, &p4, false, true, true, 0);
+ gl_draw_triangle(shaderinfo, &p2, &p1, &p3, true, true, false, 0, mirrored);
+ gl_draw_triangle(shaderinfo, &p2, &p3, &p4, false, true, true, 0, mirrored);
}
}
glEnd();
@@ -220,11 +237,11 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, GLint *sh
const Polygon *poly = &polygons[i];
glBegin(GL_TRIANGLES);
if (poly->size() == 3) {
- gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true, 0);
+ gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true, 0, mirrored);
}
else if (poly->size() == 4) {
- gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true, 0);
- gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true, 0);
+ gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true, 0, mirrored);
+ gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true, 0, mirrored);
}
else {
Point center;
@@ -237,7 +254,7 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, GLint *sh
center.y /= poly->size();
center.z /= poly->size();
for (int j = 1; j <= poly->size(); j++) {
- gl_draw_triangle(shaderinfo, &center, &poly->at(j - 1), &poly->at(j % poly->size()), false, true, false, 0);
+ gl_draw_triangle(shaderinfo, &center, &poly->at(j - 1), &poly->at(j % poly->size()), false, true, false, 0, mirrored);
}
}
glEnd();
diff --git a/transform.cc b/transform.cc
index a920dd5..3c09c14 100644
--- a/transform.cc
+++ b/transform.cc
@@ -26,6 +26,7 @@
enum transform_type_e {
SCALE,
ROTATE,
+ MIRROR,
TRANSLATE,
MULTMATRIX,
COLOR
@@ -69,6 +70,9 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
if (type == ROTATE) {
argnames = QVector<QString>() << "a" << "v";
}
+ if (type == MIRROR) {
+ argnames = QVector<QString>() << "v";
+ }
if (type == TRANSLATE) {
argnames = QVector<QString>() << "v";
}
@@ -141,25 +145,53 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
if (x != 0.0 || y != 0.0 || z != 0.0) {
double sn = 1.0 / sqrt(x*x + y*y + z*z);
x *= sn, y *= sn, z *= sn;
- } else {
- x = 0, y = 0, z = 1;
}
}
- double c = cos(a*M_PI/180.0);
- double s = sin(a*M_PI/180.0);
+ if (x != 0.0 || y != 0.0 || z != 0.0)
+ {
+ 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 == MIRROR)
+ {
+ Value val_v = c.lookup_variable("v");
+ double x = 1, y = 0, z = 0;
+
+ if (val_v.getv3(x, y, z)) {
+ if (x != 0.0 || y != 0.0 || z != 0.0) {
+ double sn = 1.0 / sqrt(x*x + y*y + z*z);
+ x *= sn, y *= sn, z *= sn;
+ }
+ }
- 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;
+ if (x != 0.0 || y != 0.0 || z != 0.0)
+ {
+ node->m[ 0] = 1-2*x*x;
+ node->m[ 1] = -2*y*x;
+ node->m[ 2] = -2*z*x;
- 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[ 4] = -2*x*y;
+ node->m[ 5] = 1-2*y*y;
+ node->m[ 6] = -2*z*y;
- 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;
+ node->m[ 8] = -2*x*z;
+ node->m[ 9] = -2*y*z;
+ node->m[10] = 1-2*z*z;
}
}
if (type == TRANSLATE)
@@ -329,6 +361,7 @@ void register_builtin_transform()
{
builtin_modules["scale"] = new TransformModule(SCALE);
builtin_modules["rotate"] = new TransformModule(ROTATE);
+ builtin_modules["mirror"] = new TransformModule(MIRROR);
builtin_modules["translate"] = new TransformModule(TRANSLATE);
builtin_modules["multmatrix"] = new TransformModule(MULTMATRIX);
builtin_modules["color"] = new TransformModule(COLOR);
contact: Jan Huwald // Impressum