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
parent
e8b0cd1f9d
commit
a0a7feda89
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
19
solvespace.h
19
solvespace.h
|
@ -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
67
ui.h
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
better Error() and Message() dialog boxes
|
||||
lock point where dragged constraint
|
||||
projected and signed distance constraints
|
||||
|
||||
-----
|
||||
better level of detail
|
||||
|
|
Loading…
Reference in New Issue