initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
1) /* drawing (DXF) to G-code (NGC) converter
2) * Copyright 2013 Stefan Schuermans <stefan@schuermans.info>
3) * Copyleft: CC-BY-SA http://creativecommons.org/licenses/by-sa/3.0/
4) */
5)
6) #include <fstream>
7) #include <iostream>
|
configuration of precision
Stefan Schuermans authored 11 years ago
|
8) #include <math.h>
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
9) #include <sstream>
10) #include <string>
11)
12) #include "cmdparser.h"
13) #include "drawing.h"
14) #include "filename.h"
15) #include "gcode.h"
|
implement converting paths...
Stefan Schuermans authored 11 years ago
|
16) #include "polygons.h"
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
17) #include "settings.h"
18)
|
implement converting paths...
Stefan Schuermans authored 11 years ago
|
19) /**
20) * @brief get layer by name from stream
21) * @param[in] strm stream to read layer name from
22) * @param[out] name layer name from stream
23) * @param[out] layer layer indicated by name from stream
24) * @return if layer could be found
25) */
26) bool CmdParser::getLayer(std::istream &strm, std::string &name,
27) const Layer *&layer) const
28) {
29) // get layer name argument
30) strm >> name;
31) if (strm.fail()) {
32) std::cerr << "missing layer name" << std::endl;
33) return false;
34) }
35)
36) // get layer
37) Drawing::Layers::const_iterator itLayer = mDrawing.mLayers.find(name);
38) if (itLayer == mDrawing.mLayers.end()) {
39) std::cerr << "layer \"" << name << "\" not found" << std::endl;
40) return false;
41) }
42) layer = &itLayer->second;
43)
44) return true;
45) }
46)
47) /**
48) * @brief get layer by name from stream and convert to polygons
49) * @param[in] strm stream to read layer name from
50) * @param[out] name layer name from stream
51) * @param[out] layer layer indicated by name from stream
52) * @param[in,out] polys polygons created from layer
53) * @return if layer could be found and converted to polygons
54) */
55) bool CmdParser::getLayerPolys(std::istream &strm, std::string &name,
56) const Layer *&layer, Polygons &polys) const
57) {
58) // get layer
59) if (!getLayer(strm, name, layer))
60) return false;
61)
62) // convert layer to polygons
63) if (!polys.loadLayer(*layer, mSettings.precision)) {
64) std::cerr << "cannot convert layer \"" << name << "\" to polygons"
65) << std::endl;
66) return false;
67) }
68)
69) return true;
70) }
71)
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
72) /**
73) * @brief process cmd command
74) * @param[in] strm stream to read command arguments from
75) * @return if processing command was successful
76) */
77) bool CmdParser::procCmd_cmd(std::istream &strm)
78) {
79) // skip whitespace and use rest of line as custom command
80) strm >> std::ws;
81) std::string cmd;
82) getline(strm, cmd);
83)
84) // add custom command to G-code
85) mGCode.appendCustom(cmd);
86)
87) return true;
88) }
89)
90) /**
91) * @brief process cut command
92) * @param[in] strm stream to read command arguments from
93) * @return if processing command was successful
94) */
95) bool CmdParser::procCmd_cut(std::istream &strm)
96) {
|
implement converting paths...
Stefan Schuermans authored 11 years ago
|
97) // get layer from arguments
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
98) std::string layerName;
|
implement converting paths...
Stefan Schuermans authored 11 years ago
|
99) const Layer *layer;
100) if (!getLayer(strm, layerName, layer))
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
101) return false;
102)
|
implement converting paths...
Stefan Schuermans authored 11 years ago
|
103) // convert layer to G-code
104) layer->toGCode(mSettings, mGCode);
105)
106) return true;
107) }
108)
109) /**
110) * @brief process cut_inside command
111) * @param[in] strm stream to read command arguments from
112) * @return if processing command was successful
113) */
114) bool CmdParser::procCmd_cut_inside(std::istream &strm)
115) {
116) // get layer from arguments and convert to polygons
117) std::string layerName;
118) const Layer *layer;
119) Polygons polys;
120) if (!getLayerPolys(strm, layerName, layer, polys))
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
121) return false;
122)
|
implement converting paths...
Stefan Schuermans authored 11 years ago
|
123) // TODO
124) std::cerr << "TODO: cut_inside" << std::endl;
125) return false;
126)
127) return true;
128) }
129)
130) /**
131) * @brief process cut_outside command
132) * @param[in] strm stream to read command arguments from
133) * @return if processing command was successful
134) */
135) bool CmdParser::procCmd_cut_outside(std::istream &strm)
136) {
137) // get layer from arguments and convert to polygons
138) std::string layerName;
139) const Layer *layer;
140) Polygons polys;
141) if (!getLayerPolys(strm, layerName, layer, polys))
142) return false;
143)
144) // TODO
145) std::cerr << "TODO: cut_outside" << std::endl;
146) return false;
147)
148) return true;
149) }
150)
151) /**
152) * @brief process cut_pocket command
153) * @param[in] strm stream to read command arguments from
154) * @return if processing command was successful
155) */
156) bool CmdParser::procCmd_cut_pocket(std::istream &strm)
157) {
158) // get layer from arguments and convert to polygons
159) std::string layerName;
160) const Layer *layer;
161) Polygons polys;
162) if (!getLayerPolys(strm, layerName, layer, polys))
163) return false;
164)
165) // TODO
166) std::cerr << "TODO: cut_pocket" << std::endl;
167) return false;
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
168)
169) return true;
170) }
171)
172) /**
173) * @brief process read_dxf command
174) * @param[in] strm stream to read command arguments from
175) * @return if processing command was successful
176) */
177) bool CmdParser::procCmd_read_dxf(std::istream &strm)
178) {
179) // get arguments
180) std::string fileName;
181) strm >> fileName;
182) if (strm.fail()) {
183) std::cerr << "missing DXF file name" << std::endl;
184) return false;
185) }
186)
187) // re-base DXF file name
188) fileName = filename_rebase(fileName, mBaseDir);
189)
190) // read DXF file
191) if (!mDrawing.loadDxf(fileName)) {
192) std::cerr << "could not read DXF file \"" << fileName << "\""
193) << std::endl;
194) return false;
195) }
196)
|
implement joining and impro...
Stefan Schuermans authored 11 years ago
|
197) // improve paths in layers
198) mDrawing.improvePaths(mSettings.precision);
199)
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
200) return true;
201) }
202)
203) /**
204) * @brief process set_base_z command
205) * @param[in] strm stream to read command arguments from
206) * @return if processing command was successful
207) */
208) bool CmdParser::procCmd_set_base_z(std::istream &strm)
209) {
210) // get arguments
211) double z;
212) strm >> z;
213) if (strm.fail()) {
214) std::cerr << "missing z coordinate" << std::endl;
215) return false;
216) }
217)
218) // update settings
219) mSettings.base_z = z;
220) return true;
221) }
222)
223) /**
224) * @brief process set_cut_z command
225) * @param[in] strm stream to read command arguments from
226) * @return if processing command was successful
227) */
228) bool CmdParser::procCmd_set_cut_z(std::istream &strm)
229) {
230) // get arguments
231) double z;
232) strm >> z;
233) if (strm.fail()) {
234) std::cerr << "missing z coordinate" << std::endl;
235) return false;
236) }
237)
238) // update settings
239) mSettings.cut_z = z;
240) return true;
241) }
242)
243) /**
244) * @brief process set_cut_z_step command
245) * @param[in] strm stream to read command arguments from
246) * @return if processing command was successful
247) */
248) bool CmdParser::procCmd_set_cut_z_step(std::istream &strm)
249) {
250) // get arguments and check them
251) double z;
252) strm >> z;
253) if (strm.fail()) {
254) std::cerr << "missing z value" << std::endl;
255) return false;
256) }
257) if (z <= 0.0) {
258) std::cerr << "invalid z cut step value (" << z << ")" << std::endl;
259) return false;
260) }
261)
262) // update settings
263) mSettings.cut_z_step = z;
264) return true;
265) }
266)
267) /**
268) * @brief process set_feed_drill command
269) * @param[in] strm stream to read command arguments from
270) * @return if processing command was successful
271) */
272) bool CmdParser::procCmd_set_feed_drill(std::istream &strm)
273) {
274) // get arguments and check them
275) double feed;
276) strm >> feed;
277) if (strm.fail()) {
278) std::cerr << "missing feed rate" << std::endl;
279) return false;
280) }
281) if (feed <= 0.0) {
282) std::cerr << "invalid feed rate (" << feed << ")" << std::endl;
283) return false;
284) }
285)
286) // update settings
287) mSettings.feed_drill = feed;
288) return true;
289) }
290)
291) /**
292) * @brief process set_feed_mill command
293) * @param[in] strm stream to read command arguments from
294) * @return if processing command was successful
295) */
296) bool CmdParser::procCmd_set_feed_mill(std::istream &strm)
297) {
298) // get arguments and check them
299) double feed;
300) strm >> feed;
301) if (strm.fail()) {
302) std::cerr << "missing feed rate" << std::endl;
303) return false;
304) }
305) if (feed <= 0.0) {
306) std::cerr << "invalid feed rate (" << feed << ")" << std::endl;
307) return false;
308) }
309)
310) // update settings
311) mSettings.feed_mill = feed;
312) return true;
313) }
314)
315) /**
316) * @brief process set_move_z command
317) * @param[in] strm stream to read command arguments from
318) * @return if processing command was successful
319) */
320) bool CmdParser::procCmd_set_move_z(std::istream &strm)
321) {
322) // get arguments
323) double z;
324) strm >> z;
325) if (strm.fail()) {
326) std::cerr << "missing z coordinate" << std::endl;
327) return false;
328) }
329)
330) // update settings
331) mSettings.move_z = z;
332) return true;
333) }
334)
|
configuration of precision
Stefan Schuermans authored 11 years ago
|
335) /**
336) * @brief process set_precision command
337) * @param[in] strm stream to read command arguments from
338) * @return if processing command was successful
339) */
340) bool CmdParser::procCmd_set_precision(std::istream &strm)
341) {
342) // get arguments and check them
343) double precision;
344) strm >> precision;
345) if (strm.fail()) {
346) std::cerr << "missing precision" << std::endl;
347) return false;
348) }
349) if (precision < 1.0e-8 || precision > 1.0) {
350) std::cerr << "invalid precision (" << precision << ")" << std::endl;
351) return false;
352) }
353)
354) // update settings
355) mSettings.precision = precision;
356) return true;
357) }
358)
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
359) /**
360) * @brief process set_tool_diameter command
361) * @param[in] strm stream to read command arguments from
362) * @return if processing command was successful
363) */
364) bool CmdParser::procCmd_set_tool_diameter(std::istream &strm)
365) {
366) // get arguments and check them
367) double diameter;
368) strm >> diameter;
369) if (strm.fail()) {
370) std::cerr << "missing tool diameter" << std::endl;
371) return false;
372) }
373) if (diameter < 0.0) {
374) std::cerr << "invalid tool diameter (" << diameter << ")" << std::endl;
375) return false;
376) }
377)
378) // update settings
379) mSettings.tool_diameter = diameter;
380) return true;
381) }
382)
383) /**
384) * @brief process write_ngc command
385) * @param[in] strm stream to read command arguments from
386) * @return if processing command was successful
387) */
388) bool CmdParser::procCmd_write_ngc(std::istream &strm)
389) {
390) // get arguments
391) std::string fileName;
392) strm >> fileName;
393) if (strm.fail()) {
394) std::cerr << "missing NGC file name" << std::endl;
395) return false;
396) }
397)
398) // re-base NGC file name
399) fileName = filename_rebase(fileName, mBaseDir);
400)
|
configuration of precision
Stefan Schuermans authored 11 years ago
|
401) // calculate number of digits after decimal point
402) unsigned int digits = (unsigned int)ceil(-log10(mSettings.precision));
403)
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
404) // write NGC file
|
configuration of precision
Stefan Schuermans authored 11 years ago
|
405) if (!mGCode.toFile(fileName, digits)) {
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
406) std::cerr << "could not write NGC file \"" << fileName << "\""
407) << std::endl;
408) return false;
409) }
410)
411) return true;
412) }
413)
414) /**
415) * @brief process command from line of text
416) * @param[in] strLine line containing command to process
417) * @return if processing command was successful
418) */
419) bool CmdParser::procLine(const std::string &strLine)
420) {
421) std::stringstream strm(strLine);
422)
423) // read command
424) std::string cmd;
425) strm >> cmd;
426) if (strm.fail())
427) return true; // ignore empty lines
428)
429) // commands
430) if (cmd == "cmd")
431) return procCmd_cmd(strm);
432) else if (cmd == "cut")
433) return procCmd_cut(strm);
|
implement converting paths...
Stefan Schuermans authored 11 years ago
|
434) else if (cmd == "cut_inside")
435) return procCmd_cut_inside(strm);
436) else if (cmd == "cut_outside")
437) return procCmd_cut_outside(strm);
438) else if (cmd == "cut_pocket")
439) return procCmd_cut_pocket(strm);
|
initial version, DXFs can b...
Stefan Schuermans authored 11 years ago
|
440) else if (cmd == "read_dxf")
441) return procCmd_read_dxf(strm);
442) else if (cmd == "set_base_z")
443) return procCmd_set_base_z(strm);
444) else if (cmd == "set_cut_z")
445) return procCmd_set_cut_z(strm);
446) else if (cmd == "set_cut_z_step")
447) return procCmd_set_cut_z_step(strm);
448) else if (cmd == "set_feed_drill")
449) return procCmd_set_feed_drill(strm);
450) else if (cmd == "set_feed_mill")
451) return procCmd_set_feed_mill(strm);
452) else if (cmd == "set_move_z")
453) return procCmd_set_move_z(strm);
|
configuration of precision
Stefan Schuermans authored 11 years ago
|
454) else if (cmd == "set_precision")
455) return procCmd_set_precision(strm);
|