Add G Code export to SolveSpace, similar to SketchFlat. This

requires user interface to specify the depth, number of passes,
feed, and plunge feed, unfortunately.

[git-p4: depot-paths = "//depot/solvespace/": change = 2106]
solver
Jonathan Westhues 2010-01-13 20:47:17 -08:00
parent e8b0cd1f9d
commit a0a7feda89
7 changed files with 213 additions and 32 deletions

View File

@ -127,6 +127,37 @@ void TextWindow::ScreenChangeCanvasSize(int link, DWORD v) {
SS.TW.edit.i = v;
}
void TextWindow::ScreenChangeGCodeParameter(int link, DWORD v) {
char buf[1024] = "";
int row = 95;
switch(link) {
case 'd':
SS.TW.edit.meaning = EDIT_G_CODE_DEPTH;
strcpy(buf, SS.MmToString(SS.gCode.depth));
row += 0;
break;
case 's':
SS.TW.edit.meaning = EDIT_G_CODE_PASSES;
sprintf(buf, "%d", SS.gCode.passes);
row += 2;
break;
case 'F':
SS.TW.edit.meaning = EDIT_G_CODE_FEED;
strcpy(buf, SS.MmToString(SS.gCode.feed));
row += 4;
break;
case 'P':
SS.TW.edit.meaning = EDIT_G_CODE_PLUNGE_FEED;
strcpy(buf, SS.MmToString(SS.gCode.plungeFeed));
row += 6;
break;
}
ShowTextEditControl(row, 14, buf);
}
void TextWindow::ShowConfiguration(void) {
int i;
Printf(true, "%Ft material color-(r, g, b)");
@ -260,6 +291,17 @@ void TextWindow::ShowConfiguration(void) {
&ScreenChangeCheckClosedContour,
(!ccc ? "" : "no"), (!ccc ? "no" : ""));
Printf(false, "");
Printf(false, "%Ft exported g code parameters");
Printf(false, "%Ba%Ft depth: %Fd%s %Fl%Ld%f[change]%E",
SS.MmToString(SS.gCode.depth), &ScreenChangeGCodeParameter);
Printf(false, "%Bd%Ft passes: %Fd%d %Fl%Ls%f[change]%E",
SS.gCode.passes, &ScreenChangeGCodeParameter);
Printf(false, "%Ba%Ft feed: %Fd%s %Fl%LF%f[change]%E",
SS.MmToString(SS.gCode.feed), &ScreenChangeGCodeParameter);
Printf(false, "%Bd%Ft plunge fd: %Fd%s %Fl%LP%f[change]%E",
SS.MmToString(SS.gCode.plungeFeed), &ScreenChangeGCodeParameter);
Printf(false, "");
Printf(false, " %Ftgl vendor %E%s", glGetString(GL_VENDOR));
Printf(false, " %Ft renderer %E%s", glGetString(GL_RENDERER));
@ -359,6 +401,27 @@ bool TextWindow::EditControlDoneForConfiguration(char *s) {
}
break;
}
case EDIT_G_CODE_DEPTH: {
Expr *e = Expr::From(s, true);
if(e) SS.gCode.depth = (float)SS.ExprToMm(e);
break;
}
case EDIT_G_CODE_PASSES: {
Expr *e = Expr::From(s, true);
if(e) SS.gCode.passes = (int)(e->Eval());
SS.gCode.passes = max(1, min(1000, SS.gCode.passes));
break;
}
case EDIT_G_CODE_FEED: {
Expr *e = Expr::From(s, true);
if(e) SS.gCode.feed = (float)SS.ExprToMm(e);
break;
}
case EDIT_G_CODE_PLUNGE_FEED: {
Expr *e = Expr::From(s, true);
if(e) SS.gCode.plungeFeed = (float)SS.ExprToMm(e);
break;
}
default: return false;
}

View File

@ -410,9 +410,13 @@ VectorFileWriter *VectorFileWriter::ForFile(char *filename) {
} else if(StringEndsIn(filename, ".step")||StringEndsIn(filename, ".stp")) {
static Step2dFileWriter Step2dWriter;
ret = &Step2dWriter;
} else if(StringEndsIn(filename, ".txt")) {
static GCodeFileWriter GCodeWriter;
ret = &GCodeWriter;
} else {
Error("Can't identify output file type from file extension of "
"filename '%s'; try .step, .stp, .dxf, .svg, .plt, .hpgl, .pdf, "
"filename '%s'; try "
".step, .stp, .dxf, .svg, .plt, .hpgl, .pdf, .txt, "
".eps, or .ps.",
filename);
return NULL;

View File

@ -612,6 +612,70 @@ void HpglFileWriter::FinishAndCloseFile(void) {
fclose(f);
}
//-----------------------------------------------------------------------------
// Routines for G Code output. Slightly complicated by our ability to generate
// multiple passes, and to specify the feeds and depth; those parameters get
// set in the configuration screen.
//-----------------------------------------------------------------------------
void GCodeFileWriter::StartFile(void) {
ZERO(&sel);
}
void GCodeFileWriter::StartPath(DWORD strokeRgb, double lineWidth,
bool filled, DWORD fillRgb)
{
}
void GCodeFileWriter::FinishPath(DWORD strokeRgb, double lineWidth,
bool filled, DWORD fillRgb)
{
}
void GCodeFileWriter::Triangle(STriangle *tr) {
}
void GCodeFileWriter::Bezier(SBezier *sb) {
if(sb->deg == 1) {
sel.AddEdge(sb->ctrl[0], sb->ctrl[1]);
} else {
BezierAsPwl(sb);
}
}
void GCodeFileWriter::FinishAndCloseFile(void) {
SPolygon sp;
ZERO(&sp);
sel.AssemblePolygon(&sp, NULL);
int i;
for(i = 0; i < SS.gCode.passes; i++) {
double depth = (SS.gCode.depth / SS.gCode.passes)*(i+1);
SContour *sc;
for(sc = sp.l.First(); sc; sc = sp.l.NextAfter(sc)) {
if(sc->l.n < 2) continue;
SPoint *pt = sc->l.First();
fprintf(f, "G00 X%s Y%s\r\n",
SS.MmToString(pt->p.x), SS.MmToString(pt->p.y));
fprintf(f, "G01 Z%s F%s\r\n",
SS.MmToString(depth), SS.MmToString(SS.gCode.plungeFeed));
pt = sc->l.NextAfter(pt);
for(; pt; pt = sc->l.NextAfter(pt)) {
fprintf(f, "G01 X%s Y%s F%s\r\n",
SS.MmToString(pt->p.x), SS.MmToString(pt->p.y),
SS.MmToString(SS.gCode.feed));
}
// Move up to a clearance plane 5mm above the work.
fprintf(f, "G00 Z%s\r\n",
SS.MmToString(SS.gCode.depth < 0 ? +5 : -5));
}
}
sp.Clear();
sel.Clear();
fclose(f);
}
//-----------------------------------------------------------------------------
// Routine for STEP output; just a wrapper around the general STEP stuff that
// can also be used for surfaces or 3d curves.

View File

@ -94,6 +94,11 @@ void SolveSpace::Init(char *cmdLine) {
exportCanvas.height = CnfThawFloat(100.0f, "ExportCanvas_Height");
exportCanvas.dx = CnfThawFloat( 5.0f, "ExportCanvas_Dx");
exportCanvas.dy = CnfThawFloat( 5.0f, "ExportCanvas_Dy");
// Extra parameters when exporting G code
gCode.depth = CnfThawFloat(10.0f, "GCode_Depth");
gCode.passes = CnfThawDWORD(1, "GCode_Passes");
gCode.feed = CnfThawFloat(10.0f, "GCode_Feed");
gCode.plungeFeed = CnfThawFloat(10.0f, "GCode_PlungeFeed");
// Show toolbar in the graphics window
showToolbar = CnfThawDWORD(1, "ShowToolbar");
// Recent files menus
@ -184,6 +189,11 @@ void SolveSpace::Exit(void) {
CnfFreezeFloat(exportCanvas.height, "ExportCanvas_Height");
CnfFreezeFloat(exportCanvas.dx, "ExportCanvas_Dx");
CnfFreezeFloat(exportCanvas.dy, "ExportCanvas_Dy");
// Extra parameters when exporting G code
CnfFreezeFloat(gCode.depth, "GCode_Depth");
CnfFreezeDWORD(gCode.passes, "GCode_Passes");
CnfFreezeFloat(gCode.feed, "GCode_Feed");
CnfFreezeFloat(gCode.plungeFeed, "GCode_PlungeFeed");
// Show toolbar in the graphics window
CnfFreezeDWORD(showToolbar, "ShowToolbar");
@ -421,6 +431,19 @@ void SolveSpace::MenuFile(int id) {
case GraphicsWindow::MNU_EXPORT_VIEW: {
char exportFile[MAX_PATH] = "";
if(!GetSaveFile(exportFile, VEC_EXT, VEC_PATTERN)) break;
// If the user is exporting something where it would be
// inappropriate to include the constraints, then warn.
if(SS.GW.showConstraints &&
(StringEndsIn(exportFile, ".txt") ||
fabs(SS.exportOffset) > LENGTH_EPS))
{
Message("Constraints are currently shown, and will be exported "
"in the toolpath. This is probably not what you want; "
"hide them by clicking the link at the top of the "
"text window.");
}
SS.ExportViewOrWireframeTo(exportFile, false);
break;
}

View File

@ -100,6 +100,7 @@ int SaveFileYesNoCancel(void);
"STEP File (*.step;*.stp)\0*.step;*.stp\0" \
"DXF File (*.dxf)\0*.dxf\0" \
"HPGL File (*.plt;*.hpgl)\0*.plt;*.hpgl\0" \
"G Code (*.txt)\0*.txt\0" \
"All Files (*)\0*\0\0"
#define VEC_EXT "pdf"
// 3d vector (wireframe lines and curves) format
@ -506,6 +507,18 @@ class Step2dFileWriter : public VectorFileWriter {
void StartFile(void);
void FinishAndCloseFile(void);
};
class GCodeFileWriter : public VectorFileWriter {
public:
SEdgeList sel;
void StartPath( DWORD strokeRgb, double lineWidth,
bool filled, DWORD fillRgb);
void FinishPath(DWORD strokeRgb, double lineWidth,
bool filled, DWORD fillRgb);
void Triangle(STriangle *tr);
void Bezier(SBezier *sb);
void StartFile(void);
void FinishAndCloseFile(void);
};
#ifdef LIBRARY
# define ENTITY EntityBase
@ -600,6 +613,12 @@ public:
float dx;
float dy;
} exportCanvas;
struct {
float depth;
int passes;
float feed;
float plungeFeed;
} gCode;
typedef enum {
UNIT_MM = 0,

67
ui.h
View File

@ -85,43 +85,47 @@ public:
static const int EDIT_GROUP_NAME = 2;
static const int EDIT_GROUP_SCALE = 3;
// For the configuraiton screen
static const int EDIT_LIGHT_DIRECTION = 10;
static const int EDIT_LIGHT_INTENSITY = 11;
static const int EDIT_COLOR = 12;
static const int EDIT_CHORD_TOLERANCE = 13;
static const int EDIT_MAX_SEGMENTS = 14;
static const int EDIT_CAMERA_TANGENT = 15;
static const int EDIT_GRID_SPACING = 16;
static const int EDIT_EXPORT_SCALE = 17;
static const int EDIT_EXPORT_OFFSET = 18;
static const int EDIT_CANVAS_SIZE = 19;
static const int EDIT_LIGHT_DIRECTION = 100;
static const int EDIT_LIGHT_INTENSITY = 101;
static const int EDIT_COLOR = 102;
static const int EDIT_CHORD_TOLERANCE = 103;
static const int EDIT_MAX_SEGMENTS = 104;
static const int EDIT_CAMERA_TANGENT = 105;
static const int EDIT_GRID_SPACING = 106;
static const int EDIT_EXPORT_SCALE = 107;
static const int EDIT_EXPORT_OFFSET = 108;
static const int EDIT_CANVAS_SIZE = 109;
static const int EDIT_G_CODE_DEPTH = 110;
static const int EDIT_G_CODE_PASSES = 111;
static const int EDIT_G_CODE_FEED = 112;
static const int EDIT_G_CODE_PLUNGE_FEED = 113;
// For the helical sweep
static const int EDIT_HELIX_TURNS = 20;
static const int EDIT_HELIX_PITCH = 21;
static const int EDIT_HELIX_DRADIUS = 22;
static const int EDIT_HELIX_TURNS = 200;
static const int EDIT_HELIX_PITCH = 201;
static const int EDIT_HELIX_DRADIUS = 202;
// For TTF text
static const int EDIT_TTF_TEXT = 30;
static const int EDIT_TTF_TEXT = 300;
// For the step dimension screen
static const int EDIT_STEP_DIM_FINISH = 40;
static const int EDIT_STEP_DIM_STEPS = 41;
static const int EDIT_STEP_DIM_FINISH = 400;
static const int EDIT_STEP_DIM_STEPS = 401;
// For the styles stuff
static const int EDIT_STYLE_WIDTH = 50;
static const int EDIT_STYLE_TEXT_HEIGHT = 51;
static const int EDIT_STYLE_TEXT_ANGLE = 52;
static const int EDIT_STYLE_COLOR = 53;
static const int EDIT_STYLE_FILL_COLOR = 54;
static const int EDIT_STYLE_NAME = 55;
static const int EDIT_BACKGROUND_COLOR = 56;
static const int EDIT_BACKGROUND_IMG_SCALE = 57;
static const int EDIT_STYLE_WIDTH = 500;
static const int EDIT_STYLE_TEXT_HEIGHT = 501;
static const int EDIT_STYLE_TEXT_ANGLE = 502;
static const int EDIT_STYLE_COLOR = 503;
static const int EDIT_STYLE_FILL_COLOR = 504;
static const int EDIT_STYLE_NAME = 505;
static const int EDIT_BACKGROUND_COLOR = 506;
static const int EDIT_BACKGROUND_IMG_SCALE = 507;
// For paste transforming
static const int EDIT_PASTE_TIMES_REPEATED = 60;
static const int EDIT_PASTE_ANGLE = 61;
static const int EDIT_PASTE_SCALE = 62;
static const int EDIT_PASTE_TIMES_REPEATED = 600;
static const int EDIT_PASTE_ANGLE = 601;
static const int EDIT_PASTE_SCALE = 602;
// For view
static const int EDIT_VIEW_SCALE = 70;
static const int EDIT_VIEW_ORIGIN = 71;
static const int EDIT_VIEW_PROJ_RIGHT = 72;
static const int EDIT_VIEW_PROJ_UP = 73;
static const int EDIT_VIEW_SCALE = 700;
static const int EDIT_VIEW_ORIGIN = 701;
static const int EDIT_VIEW_PROJ_RIGHT = 702;
static const int EDIT_VIEW_PROJ_UP = 703;
struct {
bool showAgain;
int meaning;
@ -219,6 +223,7 @@ public:
static void ScreenChangeGridSpacing(int link, DWORD v);
static void ScreenChangeExportScale(int link, DWORD v);
static void ScreenChangeExportOffset(int link, DWORD v);
static void ScreenChangeGCodeParameter(int link, DWORD v);
static void ScreenChangeStyleName(int link, DWORD v);
static void ScreenChangeStyleWidthOrTextHeight(int link, DWORD v);
static void ScreenChangeStyleTextAngle(int link, DWORD v);

View File

@ -1,3 +1,6 @@
better Error() and Message() dialog boxes
lock point where dragged constraint
projected and signed distance constraints
-----
better level of detail