BlinkenArea - GitList
Repositories
Blog
Wiki
dxfngc
Code
Commits
Branches
Tags
Search
Tree:
d7d942d
Branches
Tags
master
dxfngc
src
layer.cpp
sort paths in order to shorten unproductive move distance
Stefan Schuermans
commited
d7d942d
at 2013-01-26 23:31:12
layer.cpp
Blame
History
Raw
/* drawing (DXF) to G-code (NGC) converter * Copyright 2013 Stefan Schuermans <stefan@schuermans.info> * Copyleft: CC-BY-SA http://creativecommons.org/licenses/by-sa/3.0/ */ #include <list> #include "gcode.h" #include "layer.h" #include "path.h" #include "settings.h" /** * @brief add a new empty path to the layer * @return reference to new empty path */ Path & Layer::addPath() { mPaths.push_back(Path()); return mPaths.back(); } /** * @brief improve paths * @param[in] eqDist maximum distance of two points to be considered equal */ void Layer::improvePaths(double eqDist) { Paths::iterator path, other, best; bool change; double smallest, dist; // join paths with equal begin/end points do { change = false; // process all paths for (path = mPaths.begin(); path != mPaths.end(); ++path) { // check all paths following aftet the current one other = path; ++other; while (other != mPaths.end()) { // paths can be joined if (other->mPoints.front().equals(path->mPoints.back(), eqDist)) { path->appendPath(*other); other = mPaths.erase(other); change = true; } else if (other->mPoints.back().equals(path->mPoints.back(), eqDist)) { path->appendReversedPath(*other); other = mPaths.erase(other); change = true; } else if (other->mPoints.back().equals(path->mPoints.front(), eqDist)) { path->prependPath(*other); other = mPaths.erase(other); change = true; } else if (other->mPoints.front().equals(path->mPoints.front(), eqDist)) { path->prependReversedPath(*other); other = mPaths.erase(other); change = true; } // paths cannot be joined -> move to next one else ++other; } // while other } // for path } while (change); // remove nearby points in paths for (path = mPaths.begin(); path != mPaths.end(); ++path) path->removeEqPoints(eqDist); // remove empty paths path = mPaths.begin(); while (path != mPaths.end()) if (path->mPoints.empty()) path = mPaths.erase(path); else ++path; // sort paths to minimize unproductive move distance for (path = mPaths.begin(); path != mPaths.end(); ++path) { // find path starting at closest distance from current paths end other = path; ++other; best = mPaths.end(); while (other != mPaths.end()) { // calculate (squared) distance from path.end to other.begin // path and other are never empty here // empty paths have been removed before dist = (path->mPoints.back() - other->mPoints.front()).abs_sq(); // keep path with smallest (squared) distance if (best == mPaths.end() || dist < smallest) { best = other; smallest = dist; } ++other; } // while other // use best path as next one, i.e. swap best path with next one other = path; other++; if (other != mPaths.end() && best != mPaths.end()) mPaths.splice(other, mPaths, best); } // for path } /** * @brief convert layer to G-code * @param[in] settings G-code creation settings * @param[in,out] gcode new G-code is appended to existing G-code */ void Layer::toGCode(const Settings &settings, GCode &gcode) const { Paths::const_iterator path; for (path = mPaths.begin(); path != mPaths.end(); ++path) path->toGCode(settings, gcode); }