Add 3d wireframe export, in DXF or STEP format. This uses most of
the same plumbing as the 2d vector output. Also fix piecewise linear tolerance when the export scale factor is not equal to one; have to scale the chord tol along with that. [git-p4: depot-paths = "//depot/solvespace/": change = 2053]
This commit is contained in:
parent
730bb8f73e
commit
83bbc004dc
48
export.cpp
48
export.cpp
@ -107,7 +107,7 @@ void SolveSpace::ExportSectionTo(char *filename) {
|
|||||||
bl.Clear();
|
bl.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpace::ExportViewTo(char *filename) {
|
void SolveSpace::ExportViewOrWireframeTo(char *filename, bool wireframe) {
|
||||||
int i;
|
int i;
|
||||||
SEdgeList edges;
|
SEdgeList edges;
|
||||||
ZERO(&edges);
|
ZERO(&edges);
|
||||||
@ -158,21 +158,42 @@ void SolveSpace::ExportViewTo(char *filename) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector u = SS.GW.projRight,
|
if(wireframe) {
|
||||||
v = SS.GW.projUp,
|
VectorFileWriter *out = VectorFileWriter::ForFile(filename);
|
||||||
n = u.Cross(v),
|
if(out) {
|
||||||
origin = SS.GW.offset.ScaledBy(-1);
|
ExportWireframeCurves(&edges, &beziers, out);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Vector u = SS.GW.projRight,
|
||||||
|
v = SS.GW.projUp,
|
||||||
|
n = u.Cross(v),
|
||||||
|
origin = SS.GW.offset.ScaledBy(-1);
|
||||||
|
|
||||||
VectorFileWriter *out = VectorFileWriter::ForFile(filename);
|
VectorFileWriter *out = VectorFileWriter::ForFile(filename);
|
||||||
if(out) {
|
if(out) {
|
||||||
ExportLinesAndMesh(&edges, &beziers, sm,
|
ExportLinesAndMesh(&edges, &beziers, sm,
|
||||||
u, v, n, origin, SS.CameraTangent()*SS.GW.scale,
|
u, v, n, origin, SS.CameraTangent()*SS.GW.scale,
|
||||||
out);
|
out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
edges.Clear();
|
edges.Clear();
|
||||||
beziers.Clear();
|
beziers.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SolveSpace::ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
||||||
|
VectorFileWriter *out)
|
||||||
|
{
|
||||||
|
sbl->ScaleSelfBy(1.0/SS.exportScale);
|
||||||
|
SEdge *se;
|
||||||
|
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) {
|
||||||
|
se->a = (se->a).ScaledBy(1.0/SS.exportScale);
|
||||||
|
se->b = (se->b).ScaledBy(1.0/SS.exportScale);
|
||||||
|
}
|
||||||
|
out->Output(sel, sbl, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm,
|
void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm,
|
||||||
Vector u, Vector v, Vector n,
|
Vector u, Vector v, Vector n,
|
||||||
Vector origin, double cameraTan,
|
Vector origin, double cameraTan,
|
||||||
@ -465,7 +486,7 @@ void VectorFileWriter::Output(SEdgeList *sel, SBezierList *sbl, SMesh *sm) {
|
|||||||
|
|
||||||
DWORD rgb = Style::Color (e->auxA, true);
|
DWORD rgb = Style::Color (e->auxA, true);
|
||||||
double w = Style::WidthMm(e->auxA)*s;
|
double w = Style::WidthMm(e->auxA)*s;
|
||||||
LineSegment(rgb, w, e->a.x, e->a.y, e->b.x, e->b.y);
|
LineSegment(rgb, w, e->a, e->b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(sbl) {
|
if(sbl) {
|
||||||
@ -483,11 +504,10 @@ void VectorFileWriter::Output(SEdgeList *sel, SBezierList *sbl, SMesh *sm) {
|
|||||||
void VectorFileWriter::BezierAsPwl(DWORD rgb, double width, SBezier *sb) {
|
void VectorFileWriter::BezierAsPwl(DWORD rgb, double width, SBezier *sb) {
|
||||||
List<Vector> lv;
|
List<Vector> lv;
|
||||||
ZERO(&lv);
|
ZERO(&lv);
|
||||||
sb->MakePwlInto(&lv);
|
sb->MakePwlInto(&lv, SS.ChordTolMm() / SS.exportScale);
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < lv.n; i++) {
|
for(i = 1; i < lv.n; i++) {
|
||||||
LineSegment(rgb, width, lv.elem[i-1].x, lv.elem[i-1].y,
|
LineSegment(rgb, width, lv.elem[i-1], lv.elem[i]);
|
||||||
lv.elem[i ].x, lv.elem[i ].y);
|
|
||||||
}
|
}
|
||||||
lv.Clear();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,7 @@ void DxfFileWriter::StartFile(void) {
|
|||||||
"ENTITIES\r\n");
|
"ENTITIES\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DxfFileWriter::LineSegment(DWORD rgb, double w,
|
void DxfFileWriter::LineSegment(DWORD rgb, double w, Vector ptA, Vector ptB) {
|
||||||
double x0, double y0, double x1, double y1)
|
|
||||||
{
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
" 0\r\n"
|
" 0\r\n"
|
||||||
"LINE\r\n"
|
"LINE\r\n"
|
||||||
@ -83,8 +81,8 @@ void DxfFileWriter::LineSegment(DWORD rgb, double w,
|
|||||||
" 31\r\n" // zB
|
" 31\r\n" // zB
|
||||||
"%.6f\r\n",
|
"%.6f\r\n",
|
||||||
0,
|
0,
|
||||||
x0, y0, 0.0,
|
ptA.x, ptA.y, ptA.z,
|
||||||
x1, y1, 0.0);
|
ptB.x, ptB.y, ptB.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DxfFileWriter::Triangle(STriangle *tr) {
|
void DxfFileWriter::Triangle(STriangle *tr) {
|
||||||
@ -93,7 +91,7 @@ void DxfFileWriter::Triangle(STriangle *tr) {
|
|||||||
void DxfFileWriter::Bezier(DWORD rgb, double w, SBezier *sb) {
|
void DxfFileWriter::Bezier(DWORD rgb, double w, SBezier *sb) {
|
||||||
Vector c, n = Vector::From(0, 0, 1);
|
Vector c, n = Vector::From(0, 0, 1);
|
||||||
double r;
|
double r;
|
||||||
if(sb->IsCircle(n, &c, &r)) {
|
if(sb->IsInPlane(n, 0) && sb->IsCircle(n, &c, &r)) {
|
||||||
double theta0 = atan2(sb->ctrl[0].y - c.y, sb->ctrl[0].x - c.x),
|
double theta0 = atan2(sb->ctrl[0].y - c.y, sb->ctrl[0].x - c.x),
|
||||||
theta1 = atan2(sb->ctrl[2].y - c.y, sb->ctrl[2].x - c.x),
|
theta1 = atan2(sb->ctrl[2].y - c.y, sb->ctrl[2].x - c.x),
|
||||||
dtheta = WRAP_SYMMETRIC(theta1 - theta0, 2*PI);
|
dtheta = WRAP_SYMMETRIC(theta1 - theta0, 2*PI);
|
||||||
@ -169,17 +167,15 @@ void EpsFileWriter::StartFile(void) {
|
|||||||
MmToPts(ptMax.y - ptMin.y));
|
MmToPts(ptMax.y - ptMin.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EpsFileWriter::LineSegment(DWORD rgb, double w,
|
void EpsFileWriter::LineSegment(DWORD rgb, double w, Vector ptA, Vector ptB) {
|
||||||
double x0, double y0, double x1, double y1)
|
|
||||||
{
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"newpath\r\n"
|
"newpath\r\n"
|
||||||
" %.3f %.3f moveto\r\n"
|
" %.3f %.3f moveto\r\n"
|
||||||
" %.3f %.3f lineto\r\n"
|
" %.3f %.3f lineto\r\n"
|
||||||
"%s"
|
"%s"
|
||||||
"stroke\r\n",
|
"stroke\r\n",
|
||||||
MmToPts(x0 - ptMin.x), MmToPts(y0 - ptMin.y),
|
MmToPts(ptA.x - ptMin.x), MmToPts(ptA.y - ptMin.y),
|
||||||
MmToPts(x1 - ptMin.x), MmToPts(y1 - ptMin.y),
|
MmToPts(ptB.x - ptMin.x), MmToPts(ptB.y - ptMin.y),
|
||||||
StyleString(rgb, w));
|
StyleString(rgb, w));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,17 +392,15 @@ void PdfFileWriter::FinishAndCloseFile(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdfFileWriter::LineSegment(DWORD rgb, double w,
|
void PdfFileWriter::LineSegment(DWORD rgb, double w, Vector ptA, Vector ptB) {
|
||||||
double x0, double y0, double x1, double y1)
|
|
||||||
{
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"%s"
|
"%s"
|
||||||
"%.3f %.3f m\r\n"
|
"%.3f %.3f m\r\n"
|
||||||
"%.3f %.3f l\r\n"
|
"%.3f %.3f l\r\n"
|
||||||
"S\r\n",
|
"S\r\n",
|
||||||
StyleString(rgb, w),
|
StyleString(rgb, w),
|
||||||
MmToPts(x0 - ptMin.x), MmToPts(y0 - ptMin.y),
|
MmToPts(ptA.x - ptMin.x), MmToPts(ptA.y - ptMin.y),
|
||||||
MmToPts(x1 - ptMin.x), MmToPts(y1 - ptMin.y));
|
MmToPts(ptB.x - ptMin.x), MmToPts(ptB.y - ptMin.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdfFileWriter::Triangle(STriangle *tr) {
|
void PdfFileWriter::Triangle(STriangle *tr) {
|
||||||
@ -473,14 +467,12 @@ void SvgFileWriter::StartFile(void) {
|
|||||||
// A little bit of extra space for the stroke width.
|
// A little bit of extra space for the stroke width.
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgFileWriter::LineSegment(DWORD rgb, double w,
|
void SvgFileWriter::LineSegment(DWORD rgb, double w, Vector ptA, Vector ptB) {
|
||||||
double x0, double y0, double x1, double y1)
|
|
||||||
{
|
|
||||||
// SVG uses a coordinate system with the origin at top left, +y down
|
// SVG uses a coordinate system with the origin at top left, +y down
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"<polyline points='%.3f,%.3f %.3f,%.3f' %s />\r\n",
|
"<polyline points='%.3f,%.3f %.3f,%.3f' %s />\r\n",
|
||||||
(x0 - ptMin.x), (ptMax.y - y0),
|
(ptA.x - ptMin.x), (ptMax.y - ptA.y),
|
||||||
(x1 - ptMin.x), (ptMax.y - y1),
|
(ptB.x - ptMin.x), (ptMax.y - ptB.y),
|
||||||
StyleString(rgb, w));
|
StyleString(rgb, w));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,8 +517,7 @@ void SvgFileWriter::Bezier(DWORD rgb, double w, SBezier *sb) {
|
|||||||
StyleString(rgb, w));
|
StyleString(rgb, w));
|
||||||
} else if(!sb->IsRational()) {
|
} else if(!sb->IsRational()) {
|
||||||
if(sb->deg == 1) {
|
if(sb->deg == 1) {
|
||||||
LineSegment(rgb, w, sb->ctrl[0].x, sb->ctrl[0].y,
|
LineSegment(rgb, w, sb->ctrl[0], sb->ctrl[1]);
|
||||||
sb->ctrl[1].x, sb->ctrl[1].y);
|
|
||||||
} else if(sb->deg == 2) {
|
} else if(sb->deg == 2) {
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"<path d='M%.3f,%.3f "
|
"<path d='M%.3f,%.3f "
|
||||||
@ -567,11 +558,13 @@ void HpglFileWriter::StartFile(void) {
|
|||||||
fprintf(f, "SP1;\r\n");
|
fprintf(f, "SP1;\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HpglFileWriter::LineSegment(DWORD rgb, double w,
|
void HpglFileWriter::LineSegment(DWORD rgb, double w, Vector ptA, Vector ptB) {
|
||||||
double x0, double y0, double x1, double y1)
|
fprintf(f, "PU%d,%d;\r\n",
|
||||||
{
|
(int)MmToHpglUnits(ptA.x),
|
||||||
fprintf(f, "PU%d,%d;\r\n", (int)MmToHpglUnits(x0), (int)MmToHpglUnits(y0));
|
(int)MmToHpglUnits(ptA.y));
|
||||||
fprintf(f, "PD%d,%d;\r\n", (int)MmToHpglUnits(x1), (int)MmToHpglUnits(y1));
|
fprintf(f, "PD%d,%d;\r\n",
|
||||||
|
(int)MmToHpglUnits(ptB.x),
|
||||||
|
(int)MmToHpglUnits(ptB.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HpglFileWriter::Triangle(STriangle *tr) {
|
void HpglFileWriter::Triangle(STriangle *tr) {
|
||||||
@ -598,11 +591,9 @@ void Step2dFileWriter::StartFile(void) {
|
|||||||
void Step2dFileWriter::Triangle(STriangle *tr) {
|
void Step2dFileWriter::Triangle(STriangle *tr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Step2dFileWriter::LineSegment(DWORD rgb, double w,
|
void Step2dFileWriter::LineSegment(DWORD rgb, double w, Vector ptA, Vector ptB)
|
||||||
double x0, double y0, double x1, double y1)
|
|
||||||
{
|
{
|
||||||
SBezier sb = SBezier::From(Vector::From(x0, y0, 0),
|
SBezier sb = SBezier::From(ptA, ptB);
|
||||||
Vector::From(x1, y1, 0));
|
|
||||||
Bezier(rgb, w, &sb);
|
Bezier(rgb, w, &sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +415,14 @@ void SolveSpace::MenuFile(int id) {
|
|||||||
case GraphicsWindow::MNU_EXPORT_VIEW: {
|
case GraphicsWindow::MNU_EXPORT_VIEW: {
|
||||||
char exportFile[MAX_PATH] = "";
|
char exportFile[MAX_PATH] = "";
|
||||||
if(!GetSaveFile(exportFile, VEC_EXT, VEC_PATTERN)) break;
|
if(!GetSaveFile(exportFile, VEC_EXT, VEC_PATTERN)) break;
|
||||||
SS.ExportViewTo(exportFile);
|
SS.ExportViewOrWireframeTo(exportFile, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GraphicsWindow::MNU_EXPORT_WIREFRAME: {
|
||||||
|
char exportFile[MAX_PATH] = "";
|
||||||
|
if(!GetSaveFile(exportFile, V3D_EXT, V3D_PATTERN)) break;
|
||||||
|
SS.ExportViewOrWireframeTo(exportFile, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
41
solvespace.h
41
solvespace.h
@ -75,15 +75,20 @@ extern char RecentFile[MAX_RECENT][MAX_PATH];
|
|||||||
void RefreshRecentMenus(void);
|
void RefreshRecentMenus(void);
|
||||||
|
|
||||||
int SaveFileYesNoCancel(void);
|
int SaveFileYesNoCancel(void);
|
||||||
|
// SolveSpace native file format
|
||||||
#define SLVS_PATTERN "SolveSpace Models (*.slvs)\0*.slvs\0All Files (*)\0*\0\0"
|
#define SLVS_PATTERN "SolveSpace Models (*.slvs)\0*.slvs\0All Files (*)\0*\0\0"
|
||||||
#define SLVS_EXT "slvs"
|
#define SLVS_EXT "slvs"
|
||||||
|
// PNG format bitmap
|
||||||
#define PNG_PATTERN "PNG (*.png)\0*.png\0All Files (*)\0*\0\0"
|
#define PNG_PATTERN "PNG (*.png)\0*.png\0All Files (*)\0*\0\0"
|
||||||
#define PNG_EXT "png"
|
#define PNG_EXT "png"
|
||||||
|
// Triangle mesh
|
||||||
#define STL_PATTERN "STL Mesh (*.stl)\0*.stl\0All Files (*)\0*\0\0"
|
#define STL_PATTERN "STL Mesh (*.stl)\0*.stl\0All Files (*)\0*\0\0"
|
||||||
#define STL_EXT "stl"
|
#define STL_EXT "stl"
|
||||||
|
// NURBS surfaces
|
||||||
#define SRF_PATTERN "STEP File (*.step;*.stp)\0*.step;*.stp\0" \
|
#define SRF_PATTERN "STEP File (*.step;*.stp)\0*.step;*.stp\0" \
|
||||||
"All Files(*)\0*\0\0"
|
"All Files(*)\0*\0\0"
|
||||||
#define SRF_EXT "step"
|
#define SRF_EXT "step"
|
||||||
|
// 2d vector (lines and curves) format
|
||||||
#define VEC_PATTERN "PDF File (*.pdf)\0*.pdf\0" \
|
#define VEC_PATTERN "PDF File (*.pdf)\0*.pdf\0" \
|
||||||
"Encapsulated PostScript (*.eps;*.ps)\0*.eps;*.ps\0" \
|
"Encapsulated PostScript (*.eps;*.ps)\0*.eps;*.ps\0" \
|
||||||
"Scalable Vector Graphics (*.svg)\0*.svg\0" \
|
"Scalable Vector Graphics (*.svg)\0*.svg\0" \
|
||||||
@ -92,8 +97,15 @@ int SaveFileYesNoCancel(void);
|
|||||||
"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"
|
||||||
#define VEC_EXT "pdf"
|
#define VEC_EXT "pdf"
|
||||||
|
// 3d vector (wireframe lines and curves) format
|
||||||
|
#define V3D_PATTERN "STEP File (*.step;*.stp)\0*.step;*.stp\0" \
|
||||||
|
"DXF File (*.dxf)\0*.dxf\0" \
|
||||||
|
"All Files (*)\0*\0\0"
|
||||||
|
#define V3D_EXT "step"
|
||||||
|
// Comma-separated value, like a spreadsheet would use
|
||||||
#define CSV_PATTERN "CSV File (*.csv)\0*.csv\0All Files (*)\0*\0\0"
|
#define CSV_PATTERN "CSV File (*.csv)\0*.csv\0All Files (*)\0*\0\0"
|
||||||
#define CSV_EXT "csv"
|
#define CSV_EXT "csv"
|
||||||
|
// Native license file
|
||||||
#define LICENSE_PATTERN \
|
#define LICENSE_PATTERN \
|
||||||
"License File (*.license)\0*.license\0All Files (*)\0*\0\0"
|
"License File (*.license)\0*.license\0All Files (*)\0*\0\0"
|
||||||
#define LICENSE_EXT "license"
|
#define LICENSE_EXT "license"
|
||||||
@ -393,9 +405,6 @@ public:
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
Vector ptMin, ptMax;
|
Vector ptMin, ptMax;
|
||||||
|
|
||||||
double width;
|
|
||||||
double r, g, b;
|
|
||||||
|
|
||||||
static double MmToPts(double mm);
|
static double MmToPts(double mm);
|
||||||
static bool StringEndsIn(char *str, char *ending);
|
static bool StringEndsIn(char *str, char *ending);
|
||||||
|
|
||||||
@ -408,16 +417,15 @@ public:
|
|||||||
SBezier *sb, int depth=0);
|
SBezier *sb, int depth=0);
|
||||||
|
|
||||||
virtual void Bezier(DWORD rgb, double width, SBezier *sb) = 0;
|
virtual void Bezier(DWORD rgb, double width, SBezier *sb) = 0;
|
||||||
virtual void LineSegment(DWORD rgb, double width,
|
virtual void LineSegment(DWORD rgb, double width, Vector ptA, Vector ptB)
|
||||||
double x0, double y0, double x1, double y1) = 0;
|
= 0;
|
||||||
virtual void Triangle(STriangle *tr) = 0;
|
virtual void Triangle(STriangle *tr) = 0;
|
||||||
virtual void StartFile(void) = 0;
|
virtual void StartFile(void) = 0;
|
||||||
virtual void FinishAndCloseFile(void) = 0;
|
virtual void FinishAndCloseFile(void) = 0;
|
||||||
};
|
};
|
||||||
class DxfFileWriter : public VectorFileWriter {
|
class DxfFileWriter : public VectorFileWriter {
|
||||||
public:
|
public:
|
||||||
void LineSegment(DWORD rgb, double width,
|
void LineSegment(DWORD rgb, double width, Vector ptA, Vector ptB);
|
||||||
double x0, double y0, double x1, double y1);
|
|
||||||
void Triangle(STriangle *tr);
|
void Triangle(STriangle *tr);
|
||||||
void Bezier(DWORD rgb, double width, SBezier *sb);
|
void Bezier(DWORD rgb, double width, SBezier *sb);
|
||||||
void StartFile(void);
|
void StartFile(void);
|
||||||
@ -426,8 +434,7 @@ public:
|
|||||||
class EpsFileWriter : public VectorFileWriter {
|
class EpsFileWriter : public VectorFileWriter {
|
||||||
public:
|
public:
|
||||||
static char *StyleString(DWORD rgb, double width);
|
static char *StyleString(DWORD rgb, double width);
|
||||||
void LineSegment(DWORD rgb, double width,
|
void LineSegment(DWORD rgb, double width, Vector ptA, Vector ptB);
|
||||||
double x0, double y0, double x1, double y1);
|
|
||||||
void Triangle(STriangle *tr);
|
void Triangle(STriangle *tr);
|
||||||
void Bezier(DWORD rgb, double width, SBezier *sb);
|
void Bezier(DWORD rgb, double width, SBezier *sb);
|
||||||
void StartFile(void);
|
void StartFile(void);
|
||||||
@ -439,8 +446,7 @@ public:
|
|||||||
DWORD bodyStart;
|
DWORD bodyStart;
|
||||||
|
|
||||||
static char *StyleString(DWORD rgb, double width);
|
static char *StyleString(DWORD rgb, double width);
|
||||||
void LineSegment(DWORD rgb, double width,
|
void LineSegment(DWORD rgb, double width, Vector ptA, Vector ptB);
|
||||||
double x0, double y0, double x1, double y1);
|
|
||||||
void Triangle(STriangle *tr);
|
void Triangle(STriangle *tr);
|
||||||
void Bezier(DWORD rgb, double width, SBezier *sb);
|
void Bezier(DWORD rgb, double width, SBezier *sb);
|
||||||
void StartFile(void);
|
void StartFile(void);
|
||||||
@ -449,8 +455,7 @@ public:
|
|||||||
class SvgFileWriter : public VectorFileWriter {
|
class SvgFileWriter : public VectorFileWriter {
|
||||||
public:
|
public:
|
||||||
static char *StyleString(DWORD rgb, double width);
|
static char *StyleString(DWORD rgb, double width);
|
||||||
void LineSegment(DWORD rgb, double width,
|
void LineSegment(DWORD rgb, double width, Vector ptA, Vector ptB);
|
||||||
double x0, double y0, double x1, double y1);
|
|
||||||
void Triangle(STriangle *tr);
|
void Triangle(STriangle *tr);
|
||||||
void Bezier(DWORD rgb, double width, SBezier *sb);
|
void Bezier(DWORD rgb, double width, SBezier *sb);
|
||||||
void StartFile(void);
|
void StartFile(void);
|
||||||
@ -459,8 +464,7 @@ public:
|
|||||||
class HpglFileWriter : public VectorFileWriter {
|
class HpglFileWriter : public VectorFileWriter {
|
||||||
public:
|
public:
|
||||||
static double MmToHpglUnits(double mm);
|
static double MmToHpglUnits(double mm);
|
||||||
void LineSegment(DWORD rgb, double width,
|
void LineSegment(DWORD rgb, double width, Vector ptA, Vector ptB);
|
||||||
double x0, double y0, double x1, double y1);
|
|
||||||
void Triangle(STriangle *tr);
|
void Triangle(STriangle *tr);
|
||||||
void Bezier(DWORD rgb, double width, SBezier *sb);
|
void Bezier(DWORD rgb, double width, SBezier *sb);
|
||||||
void StartFile(void);
|
void StartFile(void);
|
||||||
@ -468,8 +472,7 @@ public:
|
|||||||
};
|
};
|
||||||
class Step2dFileWriter : public VectorFileWriter {
|
class Step2dFileWriter : public VectorFileWriter {
|
||||||
StepFileWriter sfw;
|
StepFileWriter sfw;
|
||||||
void LineSegment(DWORD rgb, double width,
|
void LineSegment(DWORD rgb, double width, Vector ptA, Vector ptB);
|
||||||
double x0, double y0, double x1, double y1);
|
|
||||||
void Triangle(STriangle *tr);
|
void Triangle(STriangle *tr);
|
||||||
void Bezier(DWORD rgb, double width, SBezier *sb);
|
void Bezier(DWORD rgb, double width, SBezier *sb);
|
||||||
void StartFile(void);
|
void StartFile(void);
|
||||||
@ -626,8 +629,10 @@ public:
|
|||||||
// And the various export options
|
// And the various export options
|
||||||
void ExportAsPngTo(char *file);
|
void ExportAsPngTo(char *file);
|
||||||
void ExportMeshTo(char *file);
|
void ExportMeshTo(char *file);
|
||||||
void ExportViewTo(char *file);
|
void ExportViewOrWireframeTo(char *file, bool wireframe);
|
||||||
void ExportSectionTo(char *file);
|
void ExportSectionTo(char *file);
|
||||||
|
void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
||||||
|
VectorFileWriter *out);
|
||||||
void ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm,
|
void ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm,
|
||||||
Vector u, Vector v, Vector n, Vector origin,
|
Vector u, Vector v, Vector n, Vector origin,
|
||||||
double cameraTan,
|
double cameraTan,
|
||||||
|
@ -105,6 +105,20 @@ SBezier SBezier::TransformedBy(Vector t, Quaternion q, bool mirror) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Does this curve lie entirely within the specified plane? It does if all
|
||||||
|
// the control points lie in that plane.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool SBezier::IsInPlane(Vector n, double d) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i <= deg; i++) {
|
||||||
|
if(fabs((ctrl[i]).Dot(n) - d) > LENGTH_EPS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Is this Bezier exactly the arc of a circle, projected along the specified
|
// Is this Bezier exactly the arc of a circle, projected along the specified
|
||||||
// axis? If yes, return that circle's center and radius.
|
// axis? If yes, return that circle's center and radius.
|
||||||
|
@ -226,20 +226,20 @@ void SBezier::SplitAt(double t, SBezier *bef, SBezier *aft) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBezier::MakePwlInto(SEdgeList *sel) {
|
void SBezier::MakePwlInto(SEdgeList *sel, double chordTol) {
|
||||||
List<Vector> lv;
|
List<Vector> lv;
|
||||||
ZERO(&lv);
|
ZERO(&lv);
|
||||||
MakePwlInto(&lv);
|
MakePwlInto(&lv, chordTol);
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < lv.n; i++) {
|
for(i = 1; i < lv.n; i++) {
|
||||||
sel->AddEdge(lv.elem[i-1], lv.elem[i]);
|
sel->AddEdge(lv.elem[i-1], lv.elem[i]);
|
||||||
}
|
}
|
||||||
lv.Clear();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
void SBezier::MakePwlInto(List<SCurvePt> *l) {
|
void SBezier::MakePwlInto(List<SCurvePt> *l, double chordTol) {
|
||||||
List<Vector> lv;
|
List<Vector> lv;
|
||||||
ZERO(&lv);
|
ZERO(&lv);
|
||||||
MakePwlInto(&lv);
|
MakePwlInto(&lv, chordTol);
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < lv.n; i++) {
|
for(i = 0; i < lv.n; i++) {
|
||||||
SCurvePt scpt;
|
SCurvePt scpt;
|
||||||
@ -250,11 +250,17 @@ void SBezier::MakePwlInto(List<SCurvePt> *l) {
|
|||||||
}
|
}
|
||||||
lv.Clear();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
void SBezier::MakePwlInto(List<Vector> *l) {
|
void SBezier::MakePwlInto(List<Vector> *l, double chordTol) {
|
||||||
|
if(chordTol == 0) {
|
||||||
|
// Use the default chord tolerance.
|
||||||
|
chordTol = SS.ChordTolMm();
|
||||||
|
}
|
||||||
l->Add(&(ctrl[0]));
|
l->Add(&(ctrl[0]));
|
||||||
MakePwlWorker(l, 0.0, 1.0);
|
MakePwlWorker(l, 0.0, 1.0, chordTol);
|
||||||
}
|
}
|
||||||
void SBezier::MakePwlWorker(List<Vector> *l, double ta, double tb) {
|
void SBezier::MakePwlWorker(List<Vector> *l, double ta, double tb,
|
||||||
|
double chordTol)
|
||||||
|
{
|
||||||
Vector pa = PointAt(ta);
|
Vector pa = PointAt(ta);
|
||||||
Vector pb = PointAt(tb);
|
Vector pb = PointAt(tb);
|
||||||
|
|
||||||
@ -269,13 +275,13 @@ void SBezier::MakePwlWorker(List<Vector> *l, double ta, double tb) {
|
|||||||
pm2.DistanceToLine(pa, pb.Minus(pa)));
|
pm2.DistanceToLine(pa, pb.Minus(pa)));
|
||||||
|
|
||||||
double step = 1.0/SS.maxSegments;
|
double step = 1.0/SS.maxSegments;
|
||||||
if((tb - ta) < step || d < SS.ChordTolMm()) {
|
if((tb - ta) < step || d < chordTol) {
|
||||||
// A previous call has already added the beginning of our interval.
|
// A previous call has already added the beginning of our interval.
|
||||||
l->Add(&pb);
|
l->Add(&pb);
|
||||||
} else {
|
} else {
|
||||||
double tm = (ta + tb) / 2;
|
double tm = (ta + tb) / 2;
|
||||||
MakePwlWorker(l, ta, tm);
|
MakePwlWorker(l, ta, tm, chordTol);
|
||||||
MakePwlWorker(l, tm, tb);
|
MakePwlWorker(l, tm, tb, chordTol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,15 +77,16 @@ public:
|
|||||||
Vector Start(void);
|
Vector Start(void);
|
||||||
Vector Finish(void);
|
Vector Finish(void);
|
||||||
bool Equals(SBezier *b);
|
bool Equals(SBezier *b);
|
||||||
void MakePwlInto(SEdgeList *sel);
|
void MakePwlInto(SEdgeList *sel, double chordTol=0);
|
||||||
void MakePwlInto(List<SCurvePt> *l);
|
void MakePwlInto(List<SCurvePt> *l, double chordTol=0);
|
||||||
void MakePwlInto(List<Vector> *l);
|
void MakePwlInto(List<Vector> *l, double chordTol=0);
|
||||||
void MakePwlWorker(List<Vector> *l, double ta, double tb);
|
void MakePwlWorker(List<Vector> *l, double ta, double tb, double chordTol);
|
||||||
|
|
||||||
void AllIntersectionsWith(SBezier *sbb, SPointList *spl);
|
void AllIntersectionsWith(SBezier *sbb, SPointList *spl);
|
||||||
void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax);
|
void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax);
|
||||||
void Reverse(void);
|
void Reverse(void);
|
||||||
|
|
||||||
|
bool IsInPlane(Vector n, double d);
|
||||||
bool IsCircle(Vector axis, Vector *center, double *r);
|
bool IsCircle(Vector axis, Vector *center, double *r);
|
||||||
bool IsRational(void);
|
bool IsRational(void);
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
multi-drag
|
multi-drag
|
||||||
copy and paste
|
copy and paste
|
||||||
wireframe export
|
|
||||||
interpolating splines
|
interpolating splines
|
||||||
associative entities from solid model, as a special group
|
associative entities from solid model, as a special group
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user