Add direct PDF export. The only curves in PDF are nonrational
cubics, so add routines to approximate a rational Bezier of any degree in that form. And use those for EPS and SVG when applicable, so now even stuff like ellipses gets exported smooth. [git-p4: depot-paths = "//depot/solvespace/": change = 1938]solver
parent
b5c8aade21
commit
3ca2a6b80b
271
export.cpp
271
export.cpp
|
@ -269,6 +269,11 @@ void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm,
|
||||||
hlrd.Clear();
|
hlrd.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double VectorFileWriter::MmToPts(double mm) {
|
||||||
|
// 72 points in an inch
|
||||||
|
return (mm/25.4)*72;
|
||||||
|
}
|
||||||
|
|
||||||
bool VectorFileWriter::StringEndsIn(char *str, char *ending) {
|
bool VectorFileWriter::StringEndsIn(char *str, char *ending) {
|
||||||
int i, ls = strlen(str), le = strlen(ending);
|
int i, ls = strlen(str), le = strlen(ending);
|
||||||
|
|
||||||
|
@ -290,6 +295,9 @@ VectorFileWriter *VectorFileWriter::ForFile(char *filename) {
|
||||||
} else if(StringEndsIn(filename, ".ps") || StringEndsIn(filename, ".eps")) {
|
} else if(StringEndsIn(filename, ".ps") || StringEndsIn(filename, ".eps")) {
|
||||||
static EpsFileWriter EpsWriter;
|
static EpsFileWriter EpsWriter;
|
||||||
ret = &EpsWriter;
|
ret = &EpsWriter;
|
||||||
|
} else if(StringEndsIn(filename, ".pdf")) {
|
||||||
|
static PdfFileWriter PdfWriter;
|
||||||
|
ret = &PdfWriter;
|
||||||
} else if(StringEndsIn(filename, ".svg")) {
|
} else if(StringEndsIn(filename, ".svg")) {
|
||||||
static SvgFileWriter SvgWriter;
|
static SvgFileWriter SvgWriter;
|
||||||
ret = &SvgWriter;
|
ret = &SvgWriter;
|
||||||
|
@ -298,7 +306,8 @@ VectorFileWriter *VectorFileWriter::ForFile(char *filename) {
|
||||||
ret = &HpglWriter;
|
ret = &HpglWriter;
|
||||||
} else {
|
} else {
|
||||||
Error("Can't identify output file type from file extension of "
|
Error("Can't identify output file type from file extension of "
|
||||||
"filename '%s'; try .dxf, .svg, .plt, .hpgl, .eps, or .ps.", filename);
|
"filename '%s'; try .dxf, .svg, .plt, .hpgl, .pdf, .eps, or .ps.",
|
||||||
|
filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +381,43 @@ void VectorFileWriter::BezierAsPwl(SBezier *sb) {
|
||||||
lv.Clear();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VectorFileWriter::BezierAsNonrationalCubic(SBezier *sb, int depth) {
|
||||||
|
Vector t0 = sb->TangentAt(0), t1 = sb->TangentAt(1);
|
||||||
|
// The curve is correct, and the first derivatives are correct, at the
|
||||||
|
// endpoints.
|
||||||
|
SBezier bnr = SBezier::From(
|
||||||
|
sb->Start(),
|
||||||
|
sb->Start().Plus(t0.ScaledBy(1.0/3)),
|
||||||
|
sb->Finish().Minus(t1.ScaledBy(1.0/3)),
|
||||||
|
sb->Finish());
|
||||||
|
|
||||||
|
double tol = SS.ChordTolMm() / SS.exportScale;
|
||||||
|
// Arbitrary choice, but make it a little finer than pwl tolerance since
|
||||||
|
// it should be easier to achieve that with the smooth curves.
|
||||||
|
tol /= 2;
|
||||||
|
|
||||||
|
bool closeEnough = true;
|
||||||
|
int i;
|
||||||
|
for(i = 1; i <= 3; i++) {
|
||||||
|
double t = i/4.0;
|
||||||
|
Vector p0 = sb->PointAt(t),
|
||||||
|
pn = bnr.PointAt(t);
|
||||||
|
double d = (p0.Minus(pn)).Magnitude();
|
||||||
|
if(d > tol) {
|
||||||
|
closeEnough = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(closeEnough || depth > 3) {
|
||||||
|
Bezier(&bnr);
|
||||||
|
} else {
|
||||||
|
SBezier bef, aft;
|
||||||
|
sb->SplitAt(0.5, &bef, &aft);
|
||||||
|
BezierAsNonrationalCubic(&bef, depth+1);
|
||||||
|
BezierAsNonrationalCubic(&aft, depth+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Routines for DXF export
|
// Routines for DXF export
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -506,11 +552,6 @@ void DxfFileWriter::FinishAndCloseFile(void) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Routines for EPS output
|
// Routines for EPS output
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
double EpsFileWriter::MmToPoints(double mm) {
|
|
||||||
// 72 points in an inch
|
|
||||||
return (mm/25.4)*72;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EpsFileWriter::StartFile(void) {
|
void EpsFileWriter::StartFile(void) {
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"%%!PS-Adobe-2.0\r\n"
|
"%%!PS-Adobe-2.0\r\n"
|
||||||
|
@ -524,10 +565,10 @@ void EpsFileWriter::StartFile(void) {
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"gsave\r\n"
|
"gsave\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
(int)ceil(MmToPoints(ptMax.x - ptMin.x)),
|
(int)ceil(MmToPts(ptMax.x - ptMin.x)),
|
||||||
(int)ceil(MmToPoints(ptMax.y - ptMin.y)),
|
(int)ceil(MmToPts(ptMax.y - ptMin.y)),
|
||||||
MmToPoints(ptMax.x - ptMin.x),
|
MmToPts(ptMax.x - ptMin.x),
|
||||||
MmToPoints(ptMax.y - ptMin.y));
|
MmToPts(ptMax.y - ptMin.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EpsFileWriter::LineSegment(double x0, double y0, double x1, double y1) {
|
void EpsFileWriter::LineSegment(double x0, double y0, double x1, double y1) {
|
||||||
|
@ -538,8 +579,8 @@ void EpsFileWriter::LineSegment(double x0, double y0, double x1, double y1) {
|
||||||
" 1 setlinewidth\r\n"
|
" 1 setlinewidth\r\n"
|
||||||
" 0 setgray\r\n"
|
" 0 setgray\r\n"
|
||||||
"stroke\r\n",
|
"stroke\r\n",
|
||||||
MmToPoints(x0 - ptMin.x), MmToPoints(y0 - ptMin.y),
|
MmToPts(x0 - ptMin.x), MmToPts(y0 - ptMin.y),
|
||||||
MmToPoints(x1 - ptMin.x), MmToPoints(y1 - ptMin.y));
|
MmToPts(x1 - ptMin.x), MmToPts(y1 - ptMin.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EpsFileWriter::Triangle(STriangle *tr) {
|
void EpsFileWriter::Triangle(STriangle *tr) {
|
||||||
|
@ -552,9 +593,9 @@ void EpsFileWriter::Triangle(STriangle *tr) {
|
||||||
" closepath\r\n"
|
" closepath\r\n"
|
||||||
"fill\r\n",
|
"fill\r\n",
|
||||||
REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
|
REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
|
||||||
MmToPoints(tr->a.x - ptMin.x), MmToPoints(tr->a.y - ptMin.y),
|
MmToPts(tr->a.x - ptMin.x), MmToPts(tr->a.y - ptMin.y),
|
||||||
MmToPoints(tr->b.x - ptMin.x), MmToPoints(tr->b.y - ptMin.y),
|
MmToPts(tr->b.x - ptMin.x), MmToPts(tr->b.y - ptMin.y),
|
||||||
MmToPoints(tr->c.x - ptMin.x), MmToPoints(tr->c.y - ptMin.y));
|
MmToPts(tr->c.x - ptMin.x), MmToPts(tr->c.y - ptMin.y));
|
||||||
|
|
||||||
// same issue with cracks, stroke it to avoid them
|
// same issue with cracks, stroke it to avoid them
|
||||||
double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000;
|
double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000;
|
||||||
|
@ -568,10 +609,10 @@ void EpsFileWriter::Triangle(STriangle *tr) {
|
||||||
" closepath\r\n"
|
" closepath\r\n"
|
||||||
"stroke\r\n",
|
"stroke\r\n",
|
||||||
REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
|
REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
|
||||||
MmToPoints(sw),
|
MmToPts(sw),
|
||||||
MmToPoints(tr->a.x - ptMin.x), MmToPoints(tr->a.y - ptMin.y),
|
MmToPts(tr->a.x - ptMin.x), MmToPts(tr->a.y - ptMin.y),
|
||||||
MmToPoints(tr->b.x - ptMin.x), MmToPoints(tr->b.y - ptMin.y),
|
MmToPts(tr->b.x - ptMin.x), MmToPts(tr->b.y - ptMin.y),
|
||||||
MmToPoints(tr->c.x - ptMin.x), MmToPoints(tr->c.y - ptMin.y));
|
MmToPts(tr->c.x - ptMin.x), MmToPts(tr->c.y - ptMin.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EpsFileWriter::Bezier(SBezier *sb) {
|
void EpsFileWriter::Bezier(SBezier *sb) {
|
||||||
|
@ -593,12 +634,24 @@ void EpsFileWriter::Bezier(SBezier *sb) {
|
||||||
" 1 setlinewidth\r\n"
|
" 1 setlinewidth\r\n"
|
||||||
" 0 setgray\r\n"
|
" 0 setgray\r\n"
|
||||||
"stroke\r\n",
|
"stroke\r\n",
|
||||||
MmToPoints(p0.x - ptMin.x), MmToPoints(p0.y - ptMin.y),
|
MmToPts(p0.x - ptMin.x), MmToPts(p0.y - ptMin.y),
|
||||||
MmToPoints(c.x - ptMin.x), MmToPoints(c.y - ptMin.y),
|
MmToPts(c.x - ptMin.x), MmToPts(c.y - ptMin.y),
|
||||||
MmToPoints(r),
|
MmToPts(r),
|
||||||
theta0*180/PI, theta1*180/PI);
|
theta0*180/PI, theta1*180/PI);
|
||||||
|
} else if(sb->deg == 3 && !sb->IsRational()) {
|
||||||
|
fprintf(f,
|
||||||
|
"newpath\r\n"
|
||||||
|
" %.3f %.3f moveto\r\n"
|
||||||
|
" %.3f %.3f %.3f %.3f %.3f %.3f curveto\r\n"
|
||||||
|
" 1 setlinewidth\r\n"
|
||||||
|
" 0 setgray\r\n"
|
||||||
|
"stroke\r\n",
|
||||||
|
MmToPts(sb->ctrl[0].x - ptMin.x), MmToPts(sb->ctrl[0].y - ptMin.y),
|
||||||
|
MmToPts(sb->ctrl[1].x - ptMin.x), MmToPts(sb->ctrl[1].y - ptMin.y),
|
||||||
|
MmToPts(sb->ctrl[2].x - ptMin.x), MmToPts(sb->ctrl[2].y - ptMin.y),
|
||||||
|
MmToPts(sb->ctrl[3].x - ptMin.x), MmToPts(sb->ctrl[3].y - ptMin.y));
|
||||||
} else {
|
} else {
|
||||||
BezierAsPwl(sb);
|
BezierAsNonrationalCubic(sb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,6 +663,175 @@ void EpsFileWriter::FinishAndCloseFile(void) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Routines for PDF output, some extra complexity because we have to generate
|
||||||
|
// a correct xref table.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void PdfFileWriter::StartFile(void) {
|
||||||
|
fprintf(f,
|
||||||
|
"%%PDF-1.1\r\n"
|
||||||
|
"%%%c%c%c%c\r\n",
|
||||||
|
0xe2, 0xe3, 0xcf, 0xd3);
|
||||||
|
|
||||||
|
xref[1] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"1 0 obj\r\n"
|
||||||
|
" << /Type /Catalog\r\n"
|
||||||
|
" /Outlines 2 0 R\r\n"
|
||||||
|
" /Pages 3 0 R\r\n"
|
||||||
|
" >>\r\n"
|
||||||
|
"endobj\r\n");
|
||||||
|
|
||||||
|
xref[2] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"2 0 obj\r\n"
|
||||||
|
" << /Type /Outlines\r\n"
|
||||||
|
" /Count 0\r\n"
|
||||||
|
" >>\r\n"
|
||||||
|
"endobj\r\n");
|
||||||
|
|
||||||
|
xref[3] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"3 0 obj\r\n"
|
||||||
|
" << /Type /Pages\r\n"
|
||||||
|
" /Kids [4 0 R]\r\n"
|
||||||
|
" /Count 1\r\n"
|
||||||
|
" >>\r\n"
|
||||||
|
"endobj\r\n");
|
||||||
|
|
||||||
|
xref[4] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"4 0 obj\r\n"
|
||||||
|
" << /Type /Page\r\n"
|
||||||
|
" /Parent 3 0 R\r\n"
|
||||||
|
" /MediaBox [0 0 %.3f %.3f]\r\n"
|
||||||
|
" /Contents 5 0 R\r\n"
|
||||||
|
" /Resources << /ProcSet 7 0 R\r\n"
|
||||||
|
" /Font << /F1 8 0 R >>\r\n"
|
||||||
|
" >>\r\n"
|
||||||
|
" >>\r\n"
|
||||||
|
"endobj\r\n",
|
||||||
|
MmToPts(ptMax.x - ptMin.x),
|
||||||
|
MmToPts(ptMax.y - ptMin.y));
|
||||||
|
|
||||||
|
xref[5] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"5 0 obj\r\n"
|
||||||
|
" << /Length 6 0 R >>\r\n"
|
||||||
|
"stream\r\n");
|
||||||
|
bodyStart = ftell(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdfFileWriter::FinishAndCloseFile(void) {
|
||||||
|
DWORD bodyEnd = ftell(f);
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"endstream\r\n"
|
||||||
|
"endobj\r\n");
|
||||||
|
|
||||||
|
xref[6] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"6 0 obj\r\n"
|
||||||
|
" %d\r\n"
|
||||||
|
"endobj\r\n",
|
||||||
|
bodyEnd - bodyStart);
|
||||||
|
|
||||||
|
xref[7] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"7 0 obj\r\n"
|
||||||
|
" [/PDF /Text]\r\n"
|
||||||
|
"endobj\r\n");
|
||||||
|
|
||||||
|
xref[8] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"8 0 obj\r\n"
|
||||||
|
" << /Type /Font\r\n"
|
||||||
|
" /Subtype /Type1\r\n"
|
||||||
|
" /Name /F1\r\n"
|
||||||
|
" /BaseFont /Helvetica\r\n"
|
||||||
|
" /Encoding /WinAnsiEncoding\r\n"
|
||||||
|
" >>\r\n"
|
||||||
|
"endobj\r\n");
|
||||||
|
|
||||||
|
xref[9] = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"9 0 obj\r\n"
|
||||||
|
" << /Creator (SolveSpace)\r\n"
|
||||||
|
" >>\r\n");
|
||||||
|
|
||||||
|
DWORD xrefStart = ftell(f);
|
||||||
|
fprintf(f,
|
||||||
|
"xref\r\n"
|
||||||
|
"0 10\r\n"
|
||||||
|
"0000000000 65535 f\r\n");
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i = 1; i <= 9; i++) {
|
||||||
|
fprintf(f, "%010d %05d n\r\n", xref[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"\r\n"
|
||||||
|
"trailer\r\n"
|
||||||
|
" << /Size 10\r\n"
|
||||||
|
" /Root 1 0 R\r\n"
|
||||||
|
" /Info 9 0 R\r\n"
|
||||||
|
" >>\r\n"
|
||||||
|
"startxref\r\n"
|
||||||
|
"%d\r\n"
|
||||||
|
"%%%%EOF\r\n",
|
||||||
|
xrefStart);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdfFileWriter::LineSegment(double x0, double y0, double x1, double y1) {
|
||||||
|
fprintf(f,
|
||||||
|
"1 w 0 0 0 RG\r\n"
|
||||||
|
"%.3f %.3f m\r\n"
|
||||||
|
"%.3f %.3f l\r\n"
|
||||||
|
"S\r\n",
|
||||||
|
MmToPts(x0 - ptMin.x), MmToPts(y0 - ptMin.y),
|
||||||
|
MmToPts(x1 - ptMin.x), MmToPts(y1 - ptMin.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdfFileWriter::Triangle(STriangle *tr) {
|
||||||
|
double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000;
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"%.3f %.3f %.3f RG\r\n"
|
||||||
|
"%.3f %.3f %.3f rg\r\n"
|
||||||
|
"%.3f w\r\n"
|
||||||
|
"%.3f %.3f m\r\n"
|
||||||
|
"%.3f %.3f l\r\n"
|
||||||
|
"%.3f %.3f l\r\n"
|
||||||
|
"b\r\n",
|
||||||
|
REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
|
||||||
|
REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
|
||||||
|
MmToPts(sw),
|
||||||
|
MmToPts(tr->a.x - ptMin.x), MmToPts(tr->a.y - ptMin.y),
|
||||||
|
MmToPts(tr->b.x - ptMin.x), MmToPts(tr->b.y - ptMin.y),
|
||||||
|
MmToPts(tr->c.x - ptMin.x), MmToPts(tr->c.y - ptMin.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdfFileWriter::Bezier(SBezier *sb) {
|
||||||
|
if(sb->deg == 3 && !sb->IsRational()) {
|
||||||
|
fprintf(f,
|
||||||
|
"1 w 0 0 0 RG\r\n"
|
||||||
|
"%.3f %.3f m\r\n"
|
||||||
|
"%.3f %.3f %.3f %.3f %.3f %.3f c\r\n"
|
||||||
|
"S\r\n",
|
||||||
|
MmToPts(sb->ctrl[0].x - ptMin.x), MmToPts(sb->ctrl[0].y - ptMin.y),
|
||||||
|
MmToPts(sb->ctrl[1].x - ptMin.x), MmToPts(sb->ctrl[1].y - ptMin.y),
|
||||||
|
MmToPts(sb->ctrl[2].x - ptMin.x), MmToPts(sb->ctrl[2].y - ptMin.y),
|
||||||
|
MmToPts(sb->ctrl[3].x - ptMin.x), MmToPts(sb->ctrl[3].y - ptMin.y));
|
||||||
|
} else {
|
||||||
|
BezierAsNonrationalCubic(sb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Routines for SVG output
|
// Routines for SVG output
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -703,7 +925,8 @@ void SvgFileWriter::Bezier(SBezier *sb) {
|
||||||
SVG_STYLE);
|
SVG_STYLE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BezierAsPwl(sb);
|
BezierAsNonrationalCubic(sb);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
solvespace.h
16
solvespace.h
|
@ -81,6 +81,7 @@ int SaveFileYesNoCancel(void);
|
||||||
#define STL_EXT "stl"
|
#define STL_EXT "stl"
|
||||||
#define VEC_PATTERN "DXF File (*.dxf)\0*.dxf\0" \
|
#define VEC_PATTERN "DXF File (*.dxf)\0*.dxf\0" \
|
||||||
"Encapsulated PostScript (*.eps;*.ps)\0*.eps;*.ps\0" \
|
"Encapsulated PostScript (*.eps;*.ps)\0*.eps;*.ps\0" \
|
||||||
|
"PDF File (*.pdf)\0*.pdf\0" \
|
||||||
"Scalable Vector Graphics (*.svg)\0*.svg\0" \
|
"Scalable Vector Graphics (*.svg)\0*.svg\0" \
|
||||||
"HPGL File (*.plt;*.hpgl)\0*.plt;*.hpgl\0" \
|
"HPGL File (*.plt;*.hpgl)\0*.plt;*.hpgl\0" \
|
||||||
"All Files (*)\0*\0\0"
|
"All Files (*)\0*\0\0"
|
||||||
|
@ -347,11 +348,14 @@ public:
|
||||||
FILE *f;
|
FILE *f;
|
||||||
Vector ptMin, ptMax;
|
Vector ptMin, ptMax;
|
||||||
|
|
||||||
|
static double MmToPts(double mm);
|
||||||
static bool StringEndsIn(char *str, char *ending);
|
static bool StringEndsIn(char *str, char *ending);
|
||||||
|
|
||||||
static VectorFileWriter *ForFile(char *file);
|
static VectorFileWriter *ForFile(char *file);
|
||||||
|
|
||||||
void Output(SEdgeList *sel, SBezierList *sbl, SMesh *sm);
|
void Output(SEdgeList *sel, SBezierList *sbl, SMesh *sm);
|
||||||
void BezierAsPwl(SBezier *sb);
|
void BezierAsPwl(SBezier *sb);
|
||||||
|
void BezierAsNonrationalCubic(SBezier *sb, int depth=0);
|
||||||
|
|
||||||
virtual void Bezier(SBezier *sb) = 0;
|
virtual void Bezier(SBezier *sb) = 0;
|
||||||
virtual void LineSegment(double x0, double y0, double x1, double y1) = 0;
|
virtual void LineSegment(double x0, double y0, double x1, double y1) = 0;
|
||||||
|
@ -369,7 +373,17 @@ public:
|
||||||
};
|
};
|
||||||
class EpsFileWriter : public VectorFileWriter {
|
class EpsFileWriter : public VectorFileWriter {
|
||||||
public:
|
public:
|
||||||
static double MmToPoints(double mm);
|
void LineSegment(double x0, double y0, double x1, double y1);
|
||||||
|
void Triangle(STriangle *tr);
|
||||||
|
void Bezier(SBezier *sb);
|
||||||
|
void StartFile(void);
|
||||||
|
void FinishAndCloseFile(void);
|
||||||
|
};
|
||||||
|
class PdfFileWriter : public VectorFileWriter {
|
||||||
|
public:
|
||||||
|
DWORD xref[10];
|
||||||
|
DWORD bodyStart;
|
||||||
|
|
||||||
void LineSegment(double x0, double y0, double x1, double y1);
|
void LineSegment(double x0, double y0, double x1, double y1);
|
||||||
void Triangle(STriangle *tr);
|
void Triangle(STriangle *tr);
|
||||||
void Bezier(SBezier *sb);
|
void Bezier(SBezier *sb);
|
||||||
|
|
|
@ -4,7 +4,6 @@ surfaces of revolution (lathed)
|
||||||
boundary avoidance when casting ray for point-in-shell
|
boundary avoidance when casting ray for point-in-shell
|
||||||
tangent intersections
|
tangent intersections
|
||||||
short pwl edge avoidance
|
short pwl edge avoidance
|
||||||
direct PDF export
|
|
||||||
assembly
|
assembly
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
Loading…
Reference in New Issue