summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-07-24 18:18:56 (GMT)
committerclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-07-24 18:18:56 (GMT)
commit92debc11399fd8cf856913508edaa8154d495ca4 (patch)
tree1489b14916cb487a6c456a1757044c632bbfea25
parentfcde390416e9c3e44e1d60bf8aeeb4add62f828b (diff)
Clifford Wolf:
Added support for twisted linear extracion git-svn-id: http://svn.clifford.at/openscad/trunk@72 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r--context.cc2
-rw-r--r--dxfdata.cc2
-rw-r--r--dxflinextrude.cc97
-rw-r--r--dxftess.cc40
-rw-r--r--openscad.h2
5 files changed, 104 insertions, 39 deletions
diff --git a/context.cc b/context.cc
index 7f96f53..fb2afcf 100644
--- a/context.cc
+++ b/context.cc
@@ -72,7 +72,7 @@ Value Context::lookup_variable(QString name, bool silent) const
if (variables.contains(name))
return variables[name];
if (parent)
- return parent->lookup_variable(name);
+ return parent->lookup_variable(name, silent);
if (!silent)
PRINTA("WARNING: Ignoring unkown variable '%1'.", name);
return Value();
diff --git a/dxfdata.cc b/dxfdata.cc
index 157efa3..750f879 100644
--- a/dxfdata.cc
+++ b/dxfdata.cc
@@ -83,7 +83,7 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
int n = get_fragments_from_r(radius, fn, fs, fa);
while (start_angle > stop_angle)
stop_angle += 360.0;
- n = ceil(n * 360 / (stop_angle-start_angle));
+ n = ceil(n * (stop_angle-start_angle) / 360);
for (int i = 0; i < n; i++) {
double a1 = ((stop_angle-start_angle)*i)/n;
double a2 = ((stop_angle-start_angle)*(i+1))/n;
diff --git a/dxflinextrude.cc b/dxflinextrude.cc
index 09d98d1..0bb771f 100644
--- a/dxflinextrude.cc
+++ b/dxflinextrude.cc
@@ -36,16 +36,16 @@ public:
class DxfLinearExtrudeNode : public AbstractPolyNode
{
public:
- int convexity;
- double fn, fs, fa, height;
+ int convexity, slices;
+ double fn, fs, fa, height, twist;
double origin_x, origin_y, scale;
- bool center;
+ bool center, has_twist;
QString filename, layername;
DxfLinearExtrudeNode(const ModuleInstanciation *mi) : AbstractPolyNode(mi) {
- convexity = 0;
- fn = fs = fa = height = 0;
+ convexity = slices = 0;
+ fn = fs = fa = height = twist = 0;
origin_x = origin_y = scale = 0;
- center = false;
+ center = has_twist = false;
}
virtual PolySet *render_polyset(render_mode_e mode) const;
virtual QString dump(QString indent) const;
@@ -72,6 +72,8 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI
Value origin = c.lookup_variable("origin", true);
Value scale = c.lookup_variable("scale", true);
Value center = c.lookup_variable("center", true);
+ Value twist = c.lookup_variable("twist", true);
+ Value slices = c.lookup_variable("slices", true);
node->filename = file.text;
node->layername = layer.text;
@@ -92,6 +94,17 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI
if (node->scale <= 0)
node->scale = 1;
+ if (twist.type == Value::NUMBER) {
+ node->twist = twist.num;
+ if (slices.type == Value::NUMBER) {
+ node->slices = slices.num;
+ } else {
+ node->slices = fmax(2, fabs(get_fragments_from_r(node->height,
+ node->fn, node->fs, node->fa) * node->twist / 360));
+ }
+ node->has_twist = true;
+ }
+
return node;
}
@@ -100,31 +113,44 @@ void register_builtin_dxf_linear_extrude()
builtin_modules["dxf_linear_extrude"] = new DxfLinearExtrudeModule();
}
-static void add_slice(PolySet *ps, DxfData::Path *pt, double h1, double h2)
+static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2, double h1, double h2)
{
for (int j = 1; j < pt->points.count(); j++)
{
int k = j - 1;
+
+ double jx1 = pt->points[j]->x * cos(rot1*M_PI/180) + pt->points[j]->y * sin(rot1*M_PI/180);
+ double jy1 = pt->points[j]->x * -sin(rot1*M_PI/180) + pt->points[j]->y * cos(rot1*M_PI/180);
+
+ double jx2 = pt->points[j]->x * cos(rot2*M_PI/180) + pt->points[j]->y * sin(rot2*M_PI/180);
+ double jy2 = pt->points[j]->x * -sin(rot2*M_PI/180) + pt->points[j]->y * cos(rot2*M_PI/180);
+
+ double kx1 = pt->points[k]->x * cos(rot1*M_PI/180) + pt->points[k]->y * sin(rot1*M_PI/180);
+ double ky1 = pt->points[k]->x * -sin(rot1*M_PI/180) + pt->points[k]->y * cos(rot1*M_PI/180);
+
+ double kx2 = pt->points[k]->x * cos(rot2*M_PI/180) + pt->points[k]->y * sin(rot2*M_PI/180);
+ double ky2 = pt->points[k]->x * -sin(rot2*M_PI/180) + pt->points[k]->y * cos(rot2*M_PI/180);
+
ps->append_poly();
if (pt->is_inner) {
- ps->append_vertex(pt->points[k]->x, pt->points[k]->y, h1);
- ps->append_vertex(pt->points[j]->x, pt->points[j]->y, h1);
- ps->append_vertex(pt->points[j]->x, pt->points[j]->y, h2);
+ ps->append_vertex(kx1, ky1, h1);
+ ps->append_vertex(jx1, jy1, h1);
+ ps->append_vertex(jx2, jy2, h2);
} else {
- ps->insert_vertex(pt->points[k]->x, pt->points[k]->y, h1);
- ps->insert_vertex(pt->points[j]->x, pt->points[j]->y, h1);
- ps->insert_vertex(pt->points[j]->x, pt->points[j]->y, h2);
+ ps->insert_vertex(kx1, ky1, h1);
+ ps->insert_vertex(jx1, jy1, h1);
+ ps->insert_vertex(jx2, jy2, h2);
}
ps->append_poly();
if (pt->is_inner) {
- ps->append_vertex(pt->points[k]->x, pt->points[k]->y, h2);
- ps->append_vertex(pt->points[k]->x, pt->points[k]->y, h1);
- ps->append_vertex(pt->points[j]->x, pt->points[j]->y, h2);
+ ps->append_vertex(kx2, ky2, h2);
+ ps->append_vertex(kx1, ky1, h1);
+ ps->append_vertex(jx2, jy2, h2);
} else {
- ps->insert_vertex(pt->points[k]->x, pt->points[k]->y, h2);
- ps->insert_vertex(pt->points[k]->x, pt->points[k]->y, h1);
- ps->insert_vertex(pt->points[j]->x, pt->points[j]->y, h2);
+ ps->insert_vertex(kx2, ky2, h2);
+ ps->insert_vertex(kx1, ky1, h1);
+ ps->insert_vertex(jx2, jy2, h2);
}
}
}
@@ -163,14 +189,35 @@ PolySet *DxfLinearExtrudeNode::render_polyset(render_mode_e) const
dxf.paths[i].points.last()->y / scale + origin_y);
}
- dxf_tesselate(ps, &dxf, false, h1);
- dxf_tesselate(ps, &dxf, true, h2);
- for (int i = 0; i < dxf.paths.count(); i++)
+ if (has_twist)
{
- if (!dxf.paths[i].is_closed)
- continue;
- add_slice(ps, &dxf.paths[i], h1, h2);
+ dxf_tesselate(ps, &dxf, 0, false, h1);
+ dxf_tesselate(ps, &dxf, twist, true, h2);
+ for (int j = 0; j < slices; j++)
+ {
+ double t1 = twist*j / slices;
+ double t2 = twist*(j+1) / slices;
+ double g1 = h1 + (h2-h1)*j / slices;
+ double g2 = h1 + (h2-h1)*(j+1) / slices;
+ for (int i = 0; i < dxf.paths.count(); i++)
+ {
+ if (!dxf.paths[i].is_closed)
+ continue;
+ add_slice(ps, &dxf.paths[i], t1, t2, g1, g2);
+ }
+ }
+ }
+ else
+ {
+ dxf_tesselate(ps, &dxf, 0, false, h1);
+ dxf_tesselate(ps, &dxf, 0, true, h2);
+ for (int i = 0; i < dxf.paths.count(); i++)
+ {
+ if (!dxf.paths[i].is_closed)
+ continue;
+ add_slice(ps, &dxf.paths[i], 0, 0, h1, h2);
+ }
}
return ps;
diff --git a/dxftess.cc b/dxftess.cc
index 4bfb96a..8aab35e 100644
--- a/dxftess.cc
+++ b/dxftess.cc
@@ -22,6 +22,8 @@
#include "openscad.h"
+#undef DEBUG_TRIANGLE_SPLITTING
+
struct tess_vdata {
GLdouble v[3];
};
@@ -152,7 +154,7 @@ static bool point_on_line(double *p1, double *p2, double *p3)
return true;
}
-void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h)
+void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, double h)
{
GLUtesselator *tobj = gluNewTess();
@@ -233,7 +235,9 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h)
while (added_triangles)
{
added_triangles = false;
- // printf("*** Triangle splitting (%d) ***\n", tess_tri.count()+1);
+#ifdef DEBUG_TRIANGLE_SPLITTING
+ printf("*** Triangle splitting (%d) ***\n", tess_tri.count()+1);
+#endif
for (int i = 0; i < tess_tri.count(); i++)
for (int k = 0; k < 3; k++)
{
@@ -245,16 +249,20 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h)
if (i != jl.first)
possible_neigh[jl] = jl;
}
- // printf("%d/%d: %d\n", i, k, possible_neigh.count());
+#ifdef DEBUG_TRIANGLE_SPLITTING
+ printf("%d/%d: %d\n", i, k, possible_neigh.count());
+#endif
foreach (QPair_ii jl, possible_neigh) {
int j = jl.first;
for (int l = jl.second; l != (jl.second + 2) % 3; l = (l + 1) % 3)
if (point_on_line(tess_tri[i].p[k], tess_tri[j].p[l], tess_tri[i].p[(k+1)%3])) {
- // printf("%% %f %f %f %f %f %f [%d %d]\n",
- // tess_tri[i].p[k][0], tess_tri[i].p[k][1],
- // tess_tri[j].p[l][0], tess_tri[j].p[l][1],
- // tess_tri[i].p[(k+1)%3][0], tess_tri[i].p[(k+1)%3][1],
- // i, j);
+#ifdef DEBUG_TRIANGLE_SPLITTING
+ printf("%% %f %f %f %f %f %f [%d %d]\n",
+ tess_tri[i].p[k][0], tess_tri[i].p[k][1],
+ tess_tri[j].p[l][0], tess_tri[j].p[l][1],
+ tess_tri[i].p[(k+1)%3][0], tess_tri[i].p[(k+1)%3][1],
+ i, j);
+#endif
tess_tri.append(tess_triangle(tess_tri[j].p[l],
tess_tri[i].p[(k+1)%3], tess_tri[i].p[(k+2)%3]));
for (int m = 0; m < 2; m++) {
@@ -283,10 +291,20 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h)
printf(" %f %f %f\n", tess_tri[i].p[1][0], tess_tri[i].p[1][1], tess_tri[i].p[1][2]);
printf(" %f %f %f\n", tess_tri[i].p[2][0], tess_tri[i].p[2][1], tess_tri[i].p[2][2]);
#endif
+ double x, y;
ps->append_poly();
- ps->insert_vertex(tess_tri[i].p[0][0], tess_tri[i].p[0][1], tess_tri[i].p[0][2]);
- ps->insert_vertex(tess_tri[i].p[1][0], tess_tri[i].p[1][1], tess_tri[i].p[1][2]);
- ps->insert_vertex(tess_tri[i].p[2][0], tess_tri[i].p[2][1], tess_tri[i].p[2][2]);
+
+ x = tess_tri[i].p[0][0] * cos(rot*M_PI/180) + tess_tri[i].p[0][1] * sin(rot*M_PI/180);
+ y = tess_tri[i].p[0][0] * -sin(rot*M_PI/180) + tess_tri[i].p[0][1] * cos(rot*M_PI/180);
+ ps->insert_vertex(x, y, tess_tri[i].p[0][2]);
+
+ x = tess_tri[i].p[1][0] * cos(rot*M_PI/180) + tess_tri[i].p[1][1] * sin(rot*M_PI/180);
+ y = tess_tri[i].p[1][0] * -sin(rot*M_PI/180) + tess_tri[i].p[1][1] * cos(rot*M_PI/180);
+ ps->insert_vertex(x, y, tess_tri[i].p[1][2]);
+
+ x = tess_tri[i].p[2][0] * cos(rot*M_PI/180) + tess_tri[i].p[2][1] * sin(rot*M_PI/180);
+ y = tess_tri[i].p[2][0] * -sin(rot*M_PI/180) + tess_tri[i].p[2][1] * cos(rot*M_PI/180);
+ ps->insert_vertex(x, y, tess_tri[i].p[2][2]);
int i0 = point_to_path.data(tess_tri[i].p[0][0], tess_tri[i].p[0][1], tess_tri[i].p[0][2]).first;
int j0 = point_to_path.data(tess_tri[i].p[0][0], tess_tri[i].p[0][1], tess_tri[i].p[0][2]).second;
diff --git a/openscad.h b/openscad.h
index 9257a76..5e56618 100644
--- a/openscad.h
+++ b/openscad.h
@@ -583,7 +583,7 @@ extern void *progress_report_vp;
void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp);
void progress_report_fin();
-void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h);
+void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, double h);
#else
contact: Jan Huwald // Impressum