Clifford Wolf:

Added support for twisted linear extracion



git-svn-id: http://svn.clifford.at/openscad/trunk@72 b57f626f-c46c-0410-a088-ec61d464b74c
stl_dim
clifford 2009-07-24 18:18:56 +00:00
parent fcde390416
commit 92debc1139
5 changed files with 104 additions and 39 deletions

View File

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

View File

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

View File

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

View File

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

View File

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