mirror of https://github.com/vitalif/openscad
Clifford Wolf:
Added support for twisted linear extracion git-svn-id: http://svn.clifford.at/openscad/trunk@72 b57f626f-c46c-0410-a088-ec61d464b74cstl_dim
parent
fcde390416
commit
92debc1139
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
40
dxftess.cc
40
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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue