Assemble the group polygon ourselves when exporting a DXF; that

lets us export open curves, if the user drew them that way.

Also increase the limits on how many pwls we will generate for a
single curve.

[git-p4: depot-paths = "//depot/solvespace/": change = 1854]
This commit is contained in:
Jonathan Westhues 2008-02-10 04:43:48 -08:00
parent 0c10efdab6
commit 22b78e4427
6 changed files with 36 additions and 30 deletions

View File

@ -155,9 +155,9 @@ void Entity::BezierPwl(double ta, double tb,
double d = max(pm1.DistanceToLine(pa, pb.Minus(pa)),
pm2.DistanceToLine(pa, pb.Minus(pa)));
double tol = 0.5*SS.chordTol/SS.GW.scale;
double tol = SS.chordTol/SS.GW.scale;
if((tb - ta) < 0.05 || d < tol) {
if((tb - ta) < 0.01 || d < tol) {
LineDrawOrGetDistanceOrEdge(pa, pb);
} else {
double tm = (ta + tb) / 2;

View File

@ -2,9 +2,8 @@
#include <png.h>
void SolveSpace::ExportDxfTo(char *filename) {
SPolygon *sp;
SPolygon spa;
ZERO(&spa);
SPolygon sp;
ZERO(&sp);
Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp);
gn = gn.WithMagnitude(1);
@ -19,17 +18,21 @@ void SolveSpace::ExportDxfTo(char *filename) {
Vector p, u, v, n;
double d;
if(gs.n == 0 && !(g->poly.IsEmpty())) {
// Don't use the assembled polygon from the group data structure; that
// one gets cleared if the curves aren't all closed.
g->AssemblePolygon(&sp, NULL);
if(gs.n == 0 && !(sp.IsEmpty())) {
// Easiest case--export the polygon drawn in this group
sp = &(g->poly);
p = sp->AnyPoint();
n = (sp->ComputeNormal()).WithMagnitude(1);
p = sp.AnyPoint();
n = (sp.ComputeNormal()).WithMagnitude(1);
if(n.Dot(gn) < 0) n = n.ScaledBy(-1);
u = n.Normal(0);
v = n.Normal(1);
d = p.Dot(n);
goto havepoly;
}
sp.Clear();
if(g->runningMesh.l.n > 0 &&
((gs.n == 0 && g->activeWorkplane.v != Entity::FREE_IN_3D.v) ||
@ -93,8 +96,7 @@ void SolveSpace::ExportDxfTo(char *filename) {
SEdgeList el;
ZERO(&el);
root->MakeCertainEdgesInto(&el, false);
el.AssemblePolygon(&spa, NULL);
sp = &spa;
el.AssemblePolygon(&sp, NULL);
el.Clear();
m.Clear();
@ -111,7 +113,7 @@ havepoly:
FILE *f = fopen(filename, "wb");
if(!f) {
Error("Couldn't write to '%s'", filename);
spa.Clear();
sp.Clear();
return;
}
@ -159,8 +161,8 @@ havepoly:
"ENTITIES\r\n");
int i, j;
for(i = 0; i < sp->l.n; i++) {
SContour *sc = &(sp->l.elem[i]);
for(i = 0; i < sp.l.n; i++) {
SContour *sc = &(sp.l.elem[i]);
for(j = 1; j < sc->l.n; j++) {
Vector p0 = sc->l.elem[j-1].p,
@ -200,7 +202,7 @@ havepoly:
" 0\r\n"
"EOF\r\n" );
spa.Clear();
sp.Clear();
fclose(f);
}

View File

@ -2,22 +2,27 @@
#define gs (SS.GW.gs)
bool Group::AssemblePolygon(SPolygon *p, SEdge *error) {
SEdgeList edges; ZERO(&edges);
int i;
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
if(e->group.v != h.v) continue;
e->GenerateEdges(&edges);
}
bool ret = edges.AssemblePolygon(p, error);
edges.Clear();
return ret;
}
void Group::GeneratePolygon(void) {
poly.Clear();
if(type == DRAWING_3D || type == DRAWING_WORKPLANE ||
type == ROTATE || type == TRANSLATE)
{
SEdgeList edges; ZERO(&edges);
int i;
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
if(e->group.v != h.v) continue;
e->GenerateEdges(&edges);
}
SEdge error;
if(edges.AssemblePolygon(&poly, &error)) {
if(AssemblePolygon(&poly, &(polyError.notClosedAt))) {
polyError.how = POLY_GOOD;
poly.normal = poly.ComputeNormal();
poly.FixContourDirections();
@ -29,10 +34,8 @@ void Group::GeneratePolygon(void) {
}
} else {
polyError.how = POLY_NOT_CLOSED;
polyError.notClosedAt = error;
poly.Clear();
}
edges.Clear();
}
}

View File

@ -197,6 +197,7 @@ public:
void GenerateEquations(IdList<Equation,hEquation> *l);
// Assembling piecewise linear sections into polygons
bool AssemblePolygon(SPolygon *p, SEdge *error);
void GeneratePolygon(void);
// And the mesh stuff
SMesh *PreviousGroupMesh(void);

View File

@ -129,7 +129,7 @@ int SolveSpace::CircleSides(double r) {
double tol = chordTol/GW.scale;
int n = 3 + (int)(PI/sqrt(2*tol/r));
return max(7, min(n, 40));
return max(7, min(n, 200));
}
char *SolveSpace::MmToString(double v) {

View File

@ -704,9 +704,9 @@ void TtfFont::BezierPwl(double ta, double tb, Vector p0, Vector p1, Vector p2) {
Vector pm = BezierEval(tm, p0, p1, p2);
double tol = 0.5*SS.chordTol/SS.GW.scale;
double tol = SS.chordTol/SS.GW.scale;
if((tb - ta) < 0.05 || pm.DistanceToLine(pa, pb.Minus(pa)) < tol) {
if((tb - ta) < 0.01 || pm.DistanceToLine(pa, pb.Minus(pa)) < tol) {
Entity *e = SS.GetEntity(entity);
e->LineDrawOrGetDistanceOrEdge(pa, pb);
} else {