34a8b9d0a1cdf10ac03e7ac0e9018567722ee9ad
Stefan Schuermans 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) 
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

6) #include <list>
Stefan Schuermans initial version, DXFs can b...

Stefan Schuermans authored 11 years ago

7) 
8) #include "gcode.h"
9) #include "layer.h"
10) #include "path.h"
11) #include "settings.h"
12) 
13) /**
14)  * @brief add a new empty path to the layer
15)  * @return reference to new empty path
16)  */
17) Path & Layer::addPath()
18) {
19)   mPaths.push_back(Path());
20)   return mPaths.back();
21) }
22) 
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

23) /**
24)  * @brief improve paths
25)  * @param[in] eqDist maximum distance of two points to be considered equal
26)  */
27) void Layer::improvePaths(double eqDist)
28) {
Stefan Schuermans sort paths in order to shor...

Stefan Schuermans authored 11 years ago

29)   Paths::iterator path, other, best;
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

30)   bool change;
Stefan Schuermans sort paths in order to shor...

Stefan Schuermans authored 11 years ago

31)   double smallest, dist;
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

32) 
33)   // join paths with equal begin/end points
34)   do {
35)     change = false;
Stefan Schuermans sort paths in order to shor...

Stefan Schuermans authored 11 years ago

36)     // process all paths
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

37)     for (path = mPaths.begin(); path != mPaths.end(); ++path) {
Stefan Schuermans sort paths in order to shor...

Stefan Schuermans authored 11 years ago

38)       // check all paths following aftet the current one
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

39)       other = path;
40)       ++other;
41)       while (other != mPaths.end()) {
Stefan Schuermans sort paths in order to shor...

Stefan Schuermans authored 11 years ago

42)         // paths can be joined
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

43)         if (other->mPoints.front().equals(path->mPoints.back(),
44)                                           eqDist)) {
45)           path->appendPath(*other);
46)           other = mPaths.erase(other);
47)           change = true;
48)         }
49)         else if (other->mPoints.back().equals(path->mPoints.back(),
50)                                               eqDist)) {
51)           path->appendReversedPath(*other);
52)           other = mPaths.erase(other);
53)           change = true;
54)         }
55)         else if (other->mPoints.back().equals(path->mPoints.front(),
56)                                               eqDist)) {
57)           path->prependPath(*other);
58)           other = mPaths.erase(other);
59)           change = true;
60)         }
61)         else if (other->mPoints.front().equals(path->mPoints.front(),
62)                                                eqDist)) {
63)           path->prependReversedPath(*other);
64)           other = mPaths.erase(other);
65)           change = true;
66)         }
Stefan Schuermans sort paths in order to shor...

Stefan Schuermans authored 11 years ago

67)         // paths cannot be joined -> move to next one
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

68)         else
69)           ++other;
Stefan Schuermans sort paths in order to shor...

Stefan Schuermans authored 11 years ago

70)       } // while other
71)     } // for path
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

72)   } while (change);
73) 
74)   // remove nearby points in paths
75)   for (path = mPaths.begin(); path != mPaths.end(); ++path)
76)     path->removeEqPoints(eqDist);
77) 
78)   // remove empty paths
79)   path = mPaths.begin();
80)   while (path != mPaths.end())
81)     if (path->mPoints.empty())
82)       path = mPaths.erase(path);
83)     else
84)       ++path;
Stefan Schuermans sort paths in order to shor...

Stefan Schuermans authored 11 years ago

85) 
86)   // sort paths to minimize unproductive move distance
87)   for (path = mPaths.begin(); path != mPaths.end(); ++path) {
88)     // find path starting at closest distance from current paths end
89)     other = path;
90)     ++other;
91)     best = mPaths.end();
92)     while (other != mPaths.end()) {
93)       // calculate (squared) distance from path.end to other.begin
94)       //   path and other are never empty here
95)       //   empty paths have been removed before
96)       dist = (path->mPoints.back() - other->mPoints.front()).abs_sq();
97)       // keep path with smallest (squared) distance
98)       if (best == mPaths.end() || dist < smallest) {
99)         best = other;
100)         smallest = dist;
101)       }
102)       ++other;
103)     } // while other
104)     // use best path as next one, i.e. swap best path with next one
105)     other = path;
106)     other++;
107)     if (other != mPaths.end() && best != mPaths.end())
108)       mPaths.splice(other, mPaths, best);
109)   } // for path
Stefan Schuermans implement joining and impro...

Stefan Schuermans authored 11 years ago

110) }
111) 
Stefan Schuermans initial version, DXFs can b...

Stefan Schuermans authored 11 years ago

112) /**
113)  * @brief convert layer to G-code
114)  * @param[in] settings G-code creation settings
115)  * @param[in,out] gcode new G-code is appended to existing G-code
116)  */
117) void Layer::toGCode(const Settings &settings, GCode &gcode) const
118) {
Stefan Schuermans process each layer z step b...

Stefan Schuermans authored 11 years ago

119)   // cut step-wise
120)   double z = settings.base_z;
121)   do {
122)     z -= settings.cut_z_step;
123)     if (z < settings.cut_z)
124)       z = settings.cut_z;
125) 
126)     // cut path at current z
127)     Paths::const_iterator path;
128)     for (path = mPaths.begin(); path != mPaths.end(); ++path)
129)       path->toGCode(settings, z, gcode);
130) 
131)   } while (z > settings.cut_z);