BlinkenArea - GitList
Repositories
Blog
Wiki
dxfngc
Code
Commits
Branches
Tags
Search
Tree:
3f2ac59
Branches
Tags
master
dxfngc
src
layer.cpp
add support for cutting a layer path-by-path (i.e. each path all the way down, then next path)
Stefan Schuermans
commited
3f2ac59
at 2013-04-22 20:33:49
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; // remove empty paths path = mPaths.begin(); while (path != mPaths.end()) if (path->mPoints.empty()) path = mPaths.erase(path); else ++path; // 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 { double z; Paths::const_iterator path; switch (settings.layer_mode) { case Settings::LevelByLevel: // cut step-wise z = settings.base_z; do { z -= settings.cut_z_step; if (z < settings.cut_z) z = settings.cut_z; // cut all paths at current z for (path = mPaths.begin(); path != mPaths.end(); ++path) path->toGCode(settings, z, gcode); } while (z > settings.cut_z); break; case Settings::PathByPath: // cut each path for (path = mPaths.begin(); path != mPaths.end(); ++path) { // cut current path step-wise z = settings.base_z; do { z -= settings.cut_z_step; if (z < settings.cut_z) z = settings.cut_z; path->toGCode(settings, z, gcode); } while (z > settings.cut_z); } // for path break; } // switch (settings.layer_mode) }