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; 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) { void TextWindow::ShowConfiguration(void) {
int i; int i;
Printf(true, "%Ft material color-(r, g, b)"); Printf(true, "%Ft material color-(r, g, b)");
@ -259,6 +290,17 @@ void TextWindow::ShowConfiguration(void) {
(ccc ? "" : "yes"), (ccc ? "yes" : ""), (ccc ? "" : "yes"), (ccc ? "yes" : ""),
&ScreenChangeCheckClosedContour, &ScreenChangeCheckClosedContour,
(!ccc ? "" : "no"), (!ccc ? "no" : "")); (!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, "");
Printf(false, " %Ftgl vendor %E%s", glGetString(GL_VENDOR)); Printf(false, " %Ftgl vendor %E%s", glGetString(GL_VENDOR));
@ -359,6 +401,27 @@ bool TextWindow::EditControlDoneForConfiguration(char *s) {
} }
break; 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; default: return false;
} }

View File

@ -410,9 +410,13 @@ VectorFileWriter *VectorFileWriter::ForFile(char *filename) {
} else if(StringEndsIn(filename, ".step")||StringEndsIn(filename, ".stp")) { } else if(StringEndsIn(filename, ".step")||StringEndsIn(filename, ".stp")) {
static Step2dFileWriter Step2dWriter; static Step2dFileWriter Step2dWriter;
ret = &Step2dWriter; ret = &Step2dWriter;
} else if(StringEndsIn(filename, ".txt")) {
static GCodeFileWriter GCodeWriter;
ret = &GCodeWriter;
} 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 .step, .stp, .dxf, .svg, .plt, .hpgl, .pdf, " "filename '%s'; try "
".step, .stp, .dxf, .svg, .plt, .hpgl, .pdf, .txt, "
".eps, or .ps.", ".eps, or .ps.",
filename); filename);
return NULL; return NULL;

View File

@ -612,6 +612,70 @@ void HpglFileWriter::FinishAndCloseFile(void) {
fclose(f); 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 // Routine for STEP output; just a wrapper around the general STEP stuff that
// can also be used for surfaces or 3d curves. // 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.height = CnfThawFloat(100.0f, "ExportCanvas_Height");
exportCanvas.dx = CnfThawFloat( 5.0f, "ExportCanvas_Dx"); exportCanvas.dx = CnfThawFloat( 5.0f, "ExportCanvas_Dx");
exportCanvas.dy = CnfThawFloat( 5.0f, "ExportCanvas_Dy"); 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 // Show toolbar in the graphics window
showToolbar = CnfThawDWORD(1, "ShowToolbar"); showToolbar = CnfThawDWORD(1, "ShowToolbar");
// Recent files menus // Recent files menus
@ -184,6 +189,11 @@ void SolveSpace::Exit(void) {
CnfFreezeFloat(exportCanvas.height, "ExportCanvas_Height"); CnfFreezeFloat(exportCanvas.height, "ExportCanvas_Height");
CnfFreezeFloat(exportCanvas.dx, "ExportCanvas_Dx"); CnfFreezeFloat(exportCanvas.dx, "ExportCanvas_Dx");
CnfFreezeFloat(exportCanvas.dy, "ExportCanvas_Dy"); 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 // Show toolbar in the graphics window
CnfFreezeDWORD(showToolbar, "ShowToolbar"); CnfFreezeDWORD(showToolbar, "ShowToolbar");
@ -421,6 +431,19 @@ 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;
// 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); SS.ExportViewOrWireframeTo(exportFile, false);
break; break;
} }

View File

@ -100,6 +100,7 @@ int SaveFileYesNoCancel(void);
"STEP File (*.step;*.stp)\0*.step;*.stp\0" \ "STEP File (*.step;*.stp)\0*.step;*.stp\0" \
"DXF File (*.dxf)\0*.dxf\0" \ "DXF File (*.dxf)\0*.dxf\0" \
"HPGL File (*.plt;*.hpgl)\0*.plt;*.hpgl\0" \ "HPGL File (*.plt;*.hpgl)\0*.plt;*.hpgl\0" \
"G Code (*.txt)\0*.txt\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 // 3d vector (wireframe lines and curves) format
@ -506,6 +507,18 @@ class Step2dFileWriter : public VectorFileWriter {
void StartFile(void); void StartFile(void);
void FinishAndCloseFile(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 #ifdef LIBRARY
# define ENTITY EntityBase # define ENTITY EntityBase
@ -600,6 +613,12 @@ public:
float dx; float dx;
float dy; float dy;
} exportCanvas; } exportCanvas;
struct {
float depth;
int passes;
float feed;
float plungeFeed;
} gCode;
typedef enum { typedef enum {
UNIT_MM = 0, 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_NAME = 2;
static const int EDIT_GROUP_SCALE = 3; static const int EDIT_GROUP_SCALE = 3;
// For the configuraiton screen // For the configuraiton screen
static const int EDIT_LIGHT_DIRECTION = 10; static const int EDIT_LIGHT_DIRECTION = 100;
static const int EDIT_LIGHT_INTENSITY = 11; static const int EDIT_LIGHT_INTENSITY = 101;
static const int EDIT_COLOR = 12; static const int EDIT_COLOR = 102;
static const int EDIT_CHORD_TOLERANCE = 13; static const int EDIT_CHORD_TOLERANCE = 103;
static const int EDIT_MAX_SEGMENTS = 14; static const int EDIT_MAX_SEGMENTS = 104;
static const int EDIT_CAMERA_TANGENT = 15; static const int EDIT_CAMERA_TANGENT = 105;
static const int EDIT_GRID_SPACING = 16; static const int EDIT_GRID_SPACING = 106;
static const int EDIT_EXPORT_SCALE = 17; static const int EDIT_EXPORT_SCALE = 107;
static const int EDIT_EXPORT_OFFSET = 18; static const int EDIT_EXPORT_OFFSET = 108;
static const int EDIT_CANVAS_SIZE = 19; 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 // For the helical sweep
static const int EDIT_HELIX_TURNS = 20; static const int EDIT_HELIX_TURNS = 200;
static const int EDIT_HELIX_PITCH = 21; static const int EDIT_HELIX_PITCH = 201;
static const int EDIT_HELIX_DRADIUS = 22; static const int EDIT_HELIX_DRADIUS = 202;
// For TTF text // For TTF text
static const int EDIT_TTF_TEXT = 30; static const int EDIT_TTF_TEXT = 300;
// For the step dimension screen // For the step dimension screen
static const int EDIT_STEP_DIM_FINISH = 40; static const int EDIT_STEP_DIM_FINISH = 400;
static const int EDIT_STEP_DIM_STEPS = 41; static const int EDIT_STEP_DIM_STEPS = 401;
// For the styles stuff // For the styles stuff
static const int EDIT_STYLE_WIDTH = 50; static const int EDIT_STYLE_WIDTH = 500;
static const int EDIT_STYLE_TEXT_HEIGHT = 51; static const int EDIT_STYLE_TEXT_HEIGHT = 501;
static const int EDIT_STYLE_TEXT_ANGLE = 52; static const int EDIT_STYLE_TEXT_ANGLE = 502;
static const int EDIT_STYLE_COLOR = 53; static const int EDIT_STYLE_COLOR = 503;
static const int EDIT_STYLE_FILL_COLOR = 54; static const int EDIT_STYLE_FILL_COLOR = 504;
static const int EDIT_STYLE_NAME = 55; static const int EDIT_STYLE_NAME = 505;
static const int EDIT_BACKGROUND_COLOR = 56; static const int EDIT_BACKGROUND_COLOR = 506;
static const int EDIT_BACKGROUND_IMG_SCALE = 57; static const int EDIT_BACKGROUND_IMG_SCALE = 507;
// For paste transforming // For paste transforming
static const int EDIT_PASTE_TIMES_REPEATED = 60; static const int EDIT_PASTE_TIMES_REPEATED = 600;
static const int EDIT_PASTE_ANGLE = 61; static const int EDIT_PASTE_ANGLE = 601;
static const int EDIT_PASTE_SCALE = 62; static const int EDIT_PASTE_SCALE = 602;
// For view // For view
static const int EDIT_VIEW_SCALE = 70; static const int EDIT_VIEW_SCALE = 700;
static const int EDIT_VIEW_ORIGIN = 71; static const int EDIT_VIEW_ORIGIN = 701;
static const int EDIT_VIEW_PROJ_RIGHT = 72; static const int EDIT_VIEW_PROJ_RIGHT = 702;
static const int EDIT_VIEW_PROJ_UP = 73; static const int EDIT_VIEW_PROJ_UP = 703;
struct { struct {
bool showAgain; bool showAgain;
int meaning; int meaning;
@ -219,6 +223,7 @@ public:
static void ScreenChangeGridSpacing(int link, DWORD v); static void ScreenChangeGridSpacing(int link, DWORD v);
static void ScreenChangeExportScale(int link, DWORD v); static void ScreenChangeExportScale(int link, DWORD v);
static void ScreenChangeExportOffset(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 ScreenChangeStyleName(int link, DWORD v);
static void ScreenChangeStyleWidthOrTextHeight(int link, DWORD v); static void ScreenChangeStyleWidthOrTextHeight(int link, DWORD v);
static void ScreenChangeStyleTextAngle(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 better level of detail