Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 3 commits
  • 17 files changed
  • 0 commit comments
  • 1 contributor
Commits on Apr 15, 2012
hurzl make layer know about previous 95a5fd4
Commits on Apr 16, 2012
hurzl fix autoplace (mostly) 1cb4efa
hurzl overhang detection basics
printlines know about layer and area (shell, infill etc.)
can show overhangs on layer display (debug setting)
de4daaa
View
2  configure.ac
@@ -50,6 +50,8 @@ PKG_CHECK_MODULES(XMLPP, libxml++-2.6 >= 2.10.0)
# AC_SUBST(XMLPP_CFLAGS)
# AC_SUBST(XMLPP_LIBS)
+# PKG_CHECK_MODULES(GTS, gts >= 0.7.6)
+
AC_OPENMP()
dnl ------------------------------------------------------------------
View
2  doc/manual.asciidoc
@@ -30,7 +30,7 @@ There are currently no Repsnapper binaries pre-built for Linux. However, instal
=== Windows ===
-There are beta versions for Windows, see the "Downloads" on github. The Windows version cannot communicate with a printer and can only calculate on a single CPU.
+There are beta versions for Windows, see the https://github.com/timschmidt/repsnapper/downloads[Downloads section on github]. The Windows version cannot communicate with a printer and can only calculate on a single CPU.
Historians only: the v1 of Repsnapper for Windows is here: http://www.kulitorum.com/RepSnapperBeta.rar (Kulitorums version).
This is even older, but should work with tonokip and FiveD: http://svn.kulitorum.com/RepSnapper/MSVC9/Release/RepSnapper.exe[here].
View
58 src/model.cpp
@@ -329,33 +329,30 @@ bool Model::FindEmptyLocation(Vector3d &result, const Shape *shape)
std::vector<Vector3d> maxpos;
std::vector<Vector3d> minpos;
- for(uint o=0;o<objtree.Objects.size();o++)
- {
- for(uint f=0;f<objtree.Objects[o]->shapes.size();f++)
- {
- Shape *selectedShape = objtree.Objects[o]->shapes[f];
- Vector3d p ;
- selectedShape->transform3D.transform.get_translation(p);
- Vector3d size = selectedShape->Max - selectedShape->Min;
-
- minpos.push_back(p);
- maxpos.push_back(p + Vector3d(size.x(), size.y(), 0));
- }
+ vector<Shape*> allshapes;
+ vector<Matrix4d> transforms;
+ objtree.get_all_shapes(allshapes, transforms);
+ for(uint s=0; s<allshapes.size(); s++) {
+ Vector3d p;
+ //Matrix4d strans = (transforms[s] * allshapes[s]->transform3D.transform);
+ Vector3d min = transforms[s] * allshapes[s]->Min;
+ Vector3d max = transforms[s] * allshapes[s]->Max;
+ minpos.push_back(Vector3d(min.x(), min.y(), 0));
+ maxpos.push_back(Vector3d(max.x(), max.y(), 0));
}
// Get all possible object positions
double d = 5.0; // 5mm spacing between objects
Vector3d StlDelta = (shape->Max - shape->Min);
- //cerr << shape->Max << shape->Min << StlDelta << endl;
vector<Vector3d> candidates;
- candidates.push_back(-shape->Min);//Vector3d(0.0, 0.0, 0.0));
+ candidates.push_back(Vector3d(0.0, 0.0, 0.0));
for (uint j=0; j<maxpos.size(); j++)
{
- candidates.push_back(maxpos[j] + Vector3d(d,0,0));
- candidates.push_back(minpos[j] + Vector3d(0,d,0));
+ candidates.push_back(Vector3d(maxpos[j].x() + d, minpos[j].y(), 0));
+ candidates.push_back(Vector3d(minpos[j].x(), maxpos[j].y() + d, 0));
candidates.push_back(maxpos[j] + Vector3d(d,d,0));
}
@@ -371,8 +368,10 @@ bool Model::FindEmptyLocation(Vector3d &result, const Shape *shape)
{
if (
// check x
- ( ( ( minpos[k].x() <= candidates[c].x() && candidates[c].x() <= maxpos[k].x() ) ||
- ( candidates[c].x() <= minpos[k].x() && maxpos[k].x() <= candidates[c].x()+StlDelta.x()+d ) ) ||
+ ( ( ( minpos[k].x() <= candidates[c].x() &&
+ candidates[c].x() <= maxpos[k].x() ) ||
+ ( candidates[c].x() <= minpos[k].x()
+ && maxpos[k].x() <= candidates[c].x()+StlDelta.x()+d ) ) ||
( ( minpos[k].x() <= candidates[c].x()+StlDelta.x()+d && candidates[c].x()+StlDelta.x()+d <= maxpos[k].x() ) ) )
&&
// check y
@@ -386,18 +385,19 @@ bool Model::FindEmptyLocation(Vector3d &result, const Shape *shape)
}
// volume boundary
- if (candidates[c].x()+StlDelta.x() > (settings.Hardware.Volume.x() - 2*settings.Hardware.PrintMargin.x()) ||
- candidates[c].y()+StlDelta.y() > (settings.Hardware.Volume.y() - 2*settings.Hardware.PrintMargin.y()))
- {
- ok = false;
- break;
- }
+ // if (candidates[c].x()+StlDelta.x() > (settings.Hardware.Volume.x() - 2*settings.Hardware.PrintMargin.x()) ||
+ // candidates[c].y()+StlDelta.y() > (settings.Hardware.Volume.y() - 2*settings.Hardware.PrintMargin.y()))
+ // {
+ // ok = false;
+ // break;
+ // }
}
if (ok)
{
result.x() = candidates[c].x();
result.y() = candidates[c].y();
result.z() = candidates[c].z();
+ result -= shape->Min;
return true;
}
}
@@ -886,6 +886,11 @@ int Model::drawLayers(double height, const Vector3d &offset, bool calconly)
settings.Hardware.LayerThickness,
settings.Display.DisplayinFill, false);
layer = m_previewLayer;
+ Layer * previous = calcSingleLayer(z-settings.Hardware.LayerThickness,
+ LayerNr-1,
+ settings.Hardware.LayerThickness,
+ false, false);
+ layer->setPrevious(previous);
}
if (!calconly) {
@@ -895,7 +900,8 @@ int Model::drawLayers(double height, const Vector3d &offset, bool calconly)
settings.Display.DrawCPLineNumbers,
settings.Display.DrawCPVertexNumbers,
settings.Display.DisplayinFill,
- settings.Display.DisplayDebuginFill);
+ settings.Display.DisplayDebuginFill,
+ settings.Display.ShowLayerOverhang);
if (settings.Display.DrawMeasures)
layer->DrawMeasures(measuresPoint);
@@ -929,7 +935,7 @@ Layer * Model::calcSingleLayer(double z, uint LayerNr, double thickness,
// else
objtree.get_all_shapes(shapes, transforms);
- Layer * layer = new Layer(LayerNr, thickness);
+ Layer * layer = new Layer(NULL, LayerNr, thickness);
layer->setZ(z);
for(size_t f=0;f < shapes.size();f++)
{
View
1  src/model.h
@@ -184,6 +184,7 @@ class Model
bool is_calculating;
bool is_printing;
//GCodeIter *m_iter;
+ Layer * lastlayer;
};
#endif // MODEL_H
View
48 src/model2.cpp
@@ -78,24 +78,27 @@ void Model::MakeRaft(GCodeState &state, double &z)
double raft_z = -totalthickness + basethickness * settings.Slicing.FirstLayerHeight;
for (uint i = 0; i < basesettings.LayerCount; i++) {
- Layer * layer = new Layer(-interfacesettings.LayerCount-basesettings.LayerCount + i,
- basethickness, 1);
+ Layer * layer = new Layer(lastlayer,
+ -interfacesettings.LayerCount-basesettings.LayerCount + i,
+ basethickness, 1);
layer->setZ(raft_z);
layer->CalcRaftInfill(raftpolys,basesettings.MaterialDistanceRatio,
basesettings.Distance, rotation);
raft_layers.push_back(layer);
+ lastlayer = layer;
rotation += basesettings.RotationPrLayer*M_PI/180;
raft_z += basethickness;
}
rotation = interfacesettings.Rotation;
for (uint i = 0; i < interfacesettings.LayerCount; i++) {
- Layer * layer = new Layer(-basesettings.LayerCount + i,
+ Layer * layer = new Layer(lastlayer, -basesettings.LayerCount + i,
interthickness, 1);
layer->setZ(raft_z);
layer->CalcRaftInfill(raftpolys,interfacesettings.MaterialDistanceRatio,
interfacesettings.Distance, rotation);
raft_layers.push_back(layer);
+ lastlayer = layer;
rotation += interfacesettings.RotationPrLayer*M_PI/180;
raft_z += interthickness;
}
@@ -327,7 +330,8 @@ void Model::Slice(vector<Shape*> shapes,
bool flatshapes = shapes.front()->dimensions() == 2;
if (flatshapes) {
layers.resize(1);
- layers[0] = new Layer(0, thickness , 1);
+ layers[0] = new Layer(lastlayer, 0, thickness , 1);
+ lastlayer = layers[0];
layers[0]->setZ(0); // set to real z
for (uint nshape= 0; nshape < shapes.size(); nshape++) {
layers[0]->addShape(transforms[nshape], *shapes[nshape], 0, max_gradient);
@@ -364,14 +368,15 @@ void Model::Slice(vector<Shape*> shapes,
#endif
}
if (!cont) continue;
- Layer * layer = new Layer(nlayer, thickness, skins);
+ Layer * layer = new Layer(NULL, nlayer, thickness, skins);
layer->setZ(z); // set to real z
int new_polys=0;
for (uint nshape= 0; nshape < shapes.size(); nshape++) {
new_polys += layer->addShape(transforms[nshape], *shapes[nshape],
z, max_gradient);
}
- if (cont) layers[nlayer] = layer;
+ if (cont)
+ layers[nlayer] = layer;
}
#ifdef _OPENMP
if (cont)
@@ -379,6 +384,11 @@ void Model::Slice(vector<Shape*> shapes,
else layers.clear();
omp_destroy_lock(&progress_lock);
#endif
+ for (uint nlayer = 1; nlayer < layers.size(); nlayer++) {
+ layers[nlayer]->setPrevious(layers[nlayer-1]);
+ }
+ if (layers.size()>0)
+ lastlayer = layers.back();
}
else
{ // have skins and/or serial build
@@ -387,7 +397,7 @@ void Model::Slice(vector<Shape*> shapes,
double z = minZ;
double shape_z = z;
double max_shape_z = z + serialheight;
- Layer * layer = new Layer(LayerNr, thickness, skins);
+ Layer * layer = new Layer(lastlayer, LayerNr, thickness, skins);
layer->setZ(shape_z);
LayerNr = 1;
int new_polys=0;
@@ -420,7 +430,8 @@ void Model::Slice(vector<Shape*> shapes,
max_gradient = 0;
if (new_polys > -1){
layers.push_back(layer);
- layer = new Layer(LayerNr++, thickness, skins);
+ lastlayer = layer;
+ layer = new Layer(lastlayer, LayerNr++, thickness, skins);
}
}
}
@@ -434,7 +445,8 @@ void Model::Slice(vector<Shape*> shapes,
thickness = skin_thickness*skins;
}
layers.push_back(layer);
- layer = new Layer(LayerNr++, thickness, skins);
+ lastlayer = layer;
+ layer = new Layer(lastlayer, LayerNr++, thickness, skins);
}
z = max_shape_z + thickness;
currentshape = 0; // all shapes again
@@ -784,6 +796,14 @@ void Model::ConvertToGCode(vector<Shape*> shapes,
double printOffsetZ = settings.Hardware.PrintMargin.z();
// Make Layers
+ lastlayer = NULL;
+
+ if (settings.RaftEnable)
+ {
+ printOffset += Vector3d (settings.Raft.Size, settings.Raft.Size, 0);
+ MakeRaft (state, printOffsetZ); // printOffsetZ will have height of raft added
+ }
+
is_calculating=false;
Slice(shapes, transforms);
@@ -809,11 +829,6 @@ void Model::ConvertToGCode(vector<Shape*> shapes,
CalcInfill();
- if (settings.RaftEnable)
- {
- printOffset += Vector3d (settings.Raft.Size, settings.Raft.Size, 0);
- MakeRaft (state, printOffsetZ); // printOffsetZ will have height of raft added
- }
if (settings.Slicing.Skirt)
MakeSkirt();
@@ -844,6 +859,9 @@ void Model::ConvertToGCode(vector<Shape*> shapes,
} catch (Glib::Error e) {
error("GCode Error:", (e.what()).c_str());
}
+ // if (layers[p]->getPrevious() != NULL)
+ // cerr << p << ": " <<layers[p]->LayerNo << " prev: "
+ // << layers[p]->getPrevious()->LayerNo << endl;
}
state.AppendCommands(commands, settings.Slicing.RelativeEcode);
@@ -924,6 +942,7 @@ string Model::getSVG() const
void Model::SliceToSVG(Glib::RefPtr<Gio::File> file)
{
if (is_calculating) return;
+ lastlayer = NULL;
Slice();
m_progress->stop (_("Done"));
Glib::file_set_contents (file->get_path(), getSVG());
@@ -934,6 +953,7 @@ void Model::SliceToSVG(Glib::RefPtr<Gio::File> file,
vector<Matrix4d> &transforms)
{
if (is_calculating) return;
+ lastlayer = NULL;
Slice(shapes,transforms);
m_progress->stop (_("Done"));
Glib::file_set_contents (file->get_path(), getSVG());
View
69 src/repsnapper.ui
@@ -13,33 +13,6 @@
<property name="short_label">Calibrate</property>
<property name="tooltip">An interactive calibration routine</property>
</object>
- <object class="GtkAdjustment" id="Display.HighlightAdjustment">
- <property name="upper">1</property>
- <property name="step_increment">0.10000000000000001</property>
- <property name="page_increment">0.25</property>
- </object>
- <object class="GtkAdjustment" id="Display.NormalsLengthAdjustment">
- <property name="upper">30</property>
- <property name="value">10</property>
- <property name="step_increment">0.10000000000000001</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkAdjustment" id="Display.PolygonOpacityAdjustment">
- <property name="upper">1</property>
- <property name="step_increment">0.10000000000000001</property>
- <property name="page_increment">0.25</property>
- </object>
- <object class="GtkAdjustment" id="DisplayEndPointSizeAdjustment">
- <property name="upper">20</property>
- <property name="value">8</property>
- <property name="step_increment">0.10000000000000001</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkAction" id="Fullscreen">
- <property name="label">Fullscreen</property>
- <property name="short_label" translatable="yes">Fullscreen</property>
- <property name="tooltip">Toggle Fullscreen</property>
- </object>
<object class="GtkAction" id="LoadSettings">
<property name="label" translatable="yes">Load Settings</property>
<property name="short_label" translatable="yes">Load Settings</property>
@@ -79,6 +52,33 @@
<property name="short_label" translatable="yes">Save Settings As</property>
<property name="tooltip" translatable="yes">Save settings in a custom file</property>
</object>
+ <object class="GtkAdjustment" id="Display.HighlightAdjustment">
+ <property name="upper">1</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">0.25</property>
+ </object>
+ <object class="GtkAdjustment" id="Display.NormalsLengthAdjustment">
+ <property name="upper">30</property>
+ <property name="value">10</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="Display.PolygonOpacityAdjustment">
+ <property name="upper">1</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">0.25</property>
+ </object>
+ <object class="GtkAdjustment" id="DisplayEndPointSizeAdjustment">
+ <property name="upper">20</property>
+ <property name="value">8</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAction" id="Fullscreen">
+ <property name="label">Fullscreen</property>
+ <property name="short_label" translatable="yes">Fullscreen</property>
+ <property name="tooltip">Toggle Fullscreen</property>
+ </object>
<object class="GtkWindow" id="PrinterControlWindowTest">
<property name="can_focus">False</property>
<property name="default_width">200</property>
@@ -7282,6 +7282,21 @@ The head will be going down between them</property>
<property name="position">2</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="Display.ShowLayerOverhang">
+ <property name="label" translatable="yes">Show Layer Overhang Areas</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
</object>
</child>
</object>
View
1  src/settings.cpp
@@ -235,6 +235,7 @@ static struct {
BOOL_MEMBER (Display.DisplayDebuginFill, "DisplayDebuginFill", false, true),
BOOL_MEMBER (Display.DisplayDebug, "DisplayDebug", false, true),
BOOL_MEMBER (Display.DisplayDebugArcs, "DisplayDebugArcs", true, true),
+ BOOL_MEMBER (Display.ShowLayerOverhang, "ShowLayerOverhang", true, true),
BOOL_MEMBER (Display.CommsDebug, "CommsDebug", false, true),
BOOL_MEMBER (Display.TerminalProgress, "TerminalProgress", false, true),
BOOL_MEMBER (Display.DisplayLayer, "DisplayLayer", false, true),
View
1  src/settings.h
@@ -220,6 +220,7 @@ class Settings {
bool DisplayGCodeBorders;
bool DisplayGCodeArrows;
bool DisplayDebugArcs;
+ bool ShowLayerOverhang;
bool DrawVertexNumbers;
bool DrawLineNumbers;
bool DrawOutlineNumbers;
View
8 src/shape.cpp
@@ -1691,8 +1691,12 @@ void FlatShape::clear()
void FlatShape::draw_geometry() {
for (uint i = 0; i < polygons.size(); i++) {
- polygons[i].draw_as_surface();
- //polygons[i].draw(GL_LINE_LOOP,false);
+ polygons[i].draw(GL_LINE_LOOP,false);
+ Poly p;
+ p.vertices = simplified(polygons[i].vertices, 0.2);
+ cleandist(p.vertices, 0.2);
+ p.draw_as_surface();
+ //polygons[i].draw_as_surface();
}
}
View
319 src/slicer/geometry.cpp
@@ -22,10 +22,12 @@
#include "geometry.h"
#include "poly.h"
#include "clipping.h"
+#include "triangle.h"
// limfit library for arc fitting
#include <lmmin.h>
+
///////// Transform3D ////////////////////////////////////
Transform3D::Transform3D()
{
@@ -977,3 +979,320 @@ Poly convexHull2D(const vector<Poly> &polygons)
hullPolygon.reverse();
return hullPolygon;
}
+
+///////////////////// CLEANUP/SIMPILFY //////////////////////
+
+// make vertices at least epsilon apart
+int cleandist(vector<Vector2d> &vert, double epsilon)
+{
+ uint n_vert = vert.size();
+ double sqeps = epsilon * epsilon;
+ uint n_moved = 0;
+ if (vert[0].squared_distance(vert[n_vert-1]) < sqeps){
+ const Vector2d center = (vert[0]+vert[n_vert-1])/2;
+ Vector2d dir = vert[0]-center;
+ dir.normalize();
+ vert[0] = center + dir*epsilon;
+ n_moved++;
+ }
+ for (uint i = 1; i < n_vert ; i++) {
+ if (vert[i].squared_distance(vert[i-1]) < sqeps){
+ const Vector2d center = (vert[i]+vert[i-1])/2;
+ Vector2d dir = vert[i]-center;
+ dir.normalize();
+ vert[i] = center + dir*epsilon;
+ n_moved++;
+ }
+ }
+ return n_moved;
+}
+
+
+// Douglas-Peucker algorithm
+vector<Vector2d> simplified(const vector<Vector2d> &vert, double epsilon)
+{
+ if (epsilon == 0) return vert;
+ uint n_vert = vert.size();
+ if (n_vert<3) return vert;
+ double dmax = 0;
+ //Find the point with the maximum distance from line start-end
+ uint index = 0;
+ Vector2d normal = normalV(vert.back()-vert.front());
+ normal.normalize();
+ if( (normal.length()==0) || ((abs(normal.length())-1)>epsilon) ) return vert;
+ for (uint i = 1; i < n_vert-1 ; i++)
+ {
+ double dist = abs((vert[i]-vert.front()).dot(normal));
+ if (dist >= epsilon && dist > dmax) {
+ index = i;
+ dmax = dist;
+ }
+ }
+ vector<Vector2d> newvert;
+ if (index > 0) // there is a point > epsilon
+ {
+ // divide at max dist point and cleanup both parts recursively
+ vector<Vector2d> part1;
+ part1.insert(part1.end(), vert.begin(), vert.begin()+index+1);
+ vector<Vector2d> c1 = simplified(part1, epsilon);
+ vector<Vector2d> part2;
+ part2.insert(part2.end(), vert.begin()+index, vert.end());
+ vector<Vector2d> c2 = simplified(part2, epsilon);
+ newvert.insert(newvert.end(), c1.begin(), c1.end()-1);
+ newvert.insert(newvert.end(), c2.begin(), c2.end());
+ }
+ else
+ { // all points are nearer than espilon
+ newvert.push_back(vert.front());
+ newvert.push_back(vert.back());
+ }
+ return newvert;
+}
+
+
+
+///////////////////// DELAUNAY TRIANG ////////////////////
+
+#define REAL double
+//#include "triangle/triangle/triangle.h"
+
+#include "triangle/PolygonTriangulator.h"
+
+int delaunayTriang(const vector<Vector2d> &points,
+ vector<Triangle> &triangles,
+ double z)
+{
+#define PTRIANGULATOR 0
+#if PTRIANGULATOR
+ vector<Vector2d> spoints = simplified(points, 1);
+ uint npoints = spoints.size();
+ vector<double> xpoints(npoints);
+ vector<double> ypoints(npoints);
+ for (uint i = 0; i < npoints; i++) {
+ xpoints[i] = spoints[npoints-i-1].x();
+ ypoints[i] = spoints[npoints-i-1].y();
+ }
+
+ polytri::PolygonTriangulator pt(xpoints, ypoints);
+
+ const polytri::PolygonTriangulator::Triangles * tr = pt.triangles();
+
+ uint ntr = tr->size();
+
+ cerr << npoints << " -> " << ntr << endl;
+
+ triangles.resize(ntr);
+
+ uint itri=0;
+ for (polytri::PolygonTriangulator::Triangles::const_iterator itr = tr->begin();
+ itr != tr->end(); ++itr) {
+
+ const polytri::PolygonTriangulator::Triangle t = *itr;
+
+ triangles[itri] = Triangle(Vector3d(xpoints[t[0]], ypoints[t[0]], z),
+ Vector3d(xpoints[t[1]], ypoints[t[1]], z),
+ Vector3d(xpoints[t[2]], ypoints[t[2]], z));
+ itri++;
+ }
+
+ return ntr;
+#endif
+
+ // struct triangulateio in;
+
+ // in.numberofpoints = npoints;
+ // in.numberofpointattributes = (int)0;
+ // in.pointlist =
+ // in.pointattributelist = NULL;
+ // in.pointmarkerlist = (int *) NULL;
+ // in.numberofsegments = 0;
+ // in.numberofholes = 0;
+ // in.numberofregions = 0;
+ // in.regionlist = (REAL *) NULL;
+
+ // delclass = new piyush;
+ // piyush *pdelclass = (piyush *)delclass;
+ // triswitches.push_back('\0');
+ // char *ptris = &triswitches[0];
+
+
+ // pmesh = new piyush::__pmesh;
+ // pbehavior = new piyush::__pbehavior;
+
+ // piyush::__pmesh * tpmesh = (piyush::__pmesh *) pmesh;
+ // piyush::__pbehavior * tpbehavior = (piyush::__pbehavior *) pbehavior;
+
+ // pdelclass->triangleinit(tpmesh);
+ // pdelclass->parsecommandline(1, &ptris, tpbehavior);
+
+ // pdelclass->transfernodes(tpmesh, tpbehavior, in.pointlist,
+ // in.pointattributelist,
+ // in.pointmarkerlist, in.numberofpoints,
+ // in.numberofpointattributes);
+ // tpmesh->hullsize = pdelclass->delaunay(tpmesh, tpbehavior);
+
+ // /* Ensure that no vertex can be mistaken for a triangular bounding */
+ // /* box vertex in insertvertex(). */
+ // tpmesh->infvertex1 = (piyush::vertex) NULL;
+ // tpmesh->infvertex2 = (piyush::vertex) NULL;
+ // tpmesh->infvertex3 = (piyush::vertex) NULL;
+
+ // /* Calculate the number of edges. */
+ // tpmesh->edges = (3l * tpmesh->triangles.items + tpmesh->hullsize) / 2l;
+ // pdelclass->numbernodes(tpmesh, tpbehavior);
+
+
+
+ /////////////////////////////////////////////// triangle++ crap
+
+
+ // typedef reviver::dpoint <double, 2> Point;
+ // vector<Point> p(points.size());
+ // for (uint i = 0; i < p.size(); i++) {
+ // p[i] = Point(points[i].x(),points[i].y());
+ // }
+ // tpp::Delaunay del(p);
+ // /*
+ // -p Triangulates a Planar Straight Line Graph (.poly file).
+ // -r Refines a previously generated mesh.
+ // -q Quality mesh generation. A minimum angle may be specified.
+ // -a Applies a maximum triangle area constraint.
+ // -u Applies a user-defined triangle constraint.
+ // -A Applies attributes to identify triangles in certain regions.
+ // -c Encloses the convex hull with segments.
+ // -D Conforming Delaunay: all triangles are truly Delaunay.
+ // -j Jettison unused vertices from output .node file.
+ // -e Generates an edge list.
+ // -v Generates a Voronoi diagram.
+ // -n Generates a list of triangle neighbors.
+ // -g Generates an .off file for Geomview.
+ // -B Suppresses output of boundary information.
+ // -P Suppresses output of .poly file.
+ // -N Suppresses output of .node file.
+ // -E Suppresses output of .ele file.
+ // -I Suppresses mesh iteration numbers.
+ // -O Ignores holes in .poly file.
+ // -X Suppresses use of exact arithmetic.
+ // -z Numbers all items starting from zero (rather than one).
+ // -o2 Generates second-order subparametric elements.
+ // -Y Suppresses boundary segment splitting.
+ // -S Specifies maximum number of added Steiner points.
+ // -i Uses incremental method, rather than divide-and-conquer.
+ // -F Uses Fortune's sweepline algorithm, rather than d-and-c.
+ // -l Uses vertical cuts only, rather than alternating cuts.
+ // -s Force segments into mesh by splitting (instead of using CDT).
+ // -C Check consistency of final mesh.
+ // -Q Quiet: No terminal output except errors.
+ // */
+ // string switches = "pq0DzQ";
+ // del.Triangulate(switches);
+ // int ntri = del.ntriangles();
+ // if (ntri>0) {
+ // triangles.resize(ntri);
+ // uint itri=0;
+ // for (tpp::Delaunay::fIterator dit = del.fbegin(); dit != del.fend(); ++dit) {
+ // Point pA = del.point_at_vertex_id(del.Org (dit));
+ // Point pB = del.point_at_vertex_id(del.Dest(dit));
+ // Point pC = del.point_at_vertex_id(del.Apex(dit));
+ // triangles[itri] = Triangle(Vector3d(pA[0],pA[1],z),
+ // Vector3d(pB[0],pB[1],z),
+ // Vector3d(pC[0],pC[1],z));
+ // // Vector2d vA = points[del.Org (dit)];
+ // // Vector2d vB = points[del.Dest(dit)];
+ // // Vector2d vC = points[del.Apex(dit)];
+ // // triangles[itri] = Triangle(Vector3d(vA.x(),vA.y(),z),
+ // // Vector3d(vB.x(),vB.y(),z),
+ // // Vector3d(vC.x(),vC.y(),z));
+ // itri++;
+ // }
+ // }
+
+ // return ntri;
+ return 0;
+}
+
+
+// typedef struct {
+// Vector2d a,b,c;
+// } triangle2;
+
+
+// bool pointInCircumcircle(const triangle2 &t, const Vector2d &p)
+// {
+// Vector2d l1p1,l1p2;
+// center_perpendicular(t.a, t.b, l1p1, l1p2);
+// Vector2d l2p1,l2p2;
+// center_perpendicular(t.a, t.c, l2p1, l2p2);
+// Vector2d center, ip;
+// double t0, t1;
+// int is = intersect2D_Segments(l1p1, l1p2, l2p1, l2p2,
+// center, ip, t0,t1);
+
+// if (is > 0) {
+// if (t.a.squared_distance(center) > p.squared_distance(center))
+// return true;
+// }
+// return false;
+// }
+
+// int delaunayTriang(const vector<Vector2d> &points, vector<Triangle> &triangles,
+// double z)
+// {
+// if (points.size() < 3) return 0;
+
+// triangles.clear();
+
+// uint nump = points.size();
+
+// vector<int> seq(nump,1); // 1,1,1...
+// partial_sum(seq.begin(), seq.end(), seq.begin()); // 1,2,3,...,20
+// srand(time(NULL));
+// random_shuffle(seq.begin(), seq.end()); // shuffle
+
+// vector<triangle2> d_triangles;
+
+// triangle2 t = { points[seq[0]-1], points[seq[1]-1], points[seq[2]-1] };
+// d_triangles.push_back(t);
+
+// for (uint i = 3; i < nump; i+=3) {
+// //triangle2 t = { points[seq[i]-1], points[seq[i+1]-1], points[seq[i+2]-1] };
+// bool deleted = false;
+// for (int ti = d_triangles.size()-1; ti >= 0 ; ti--) {
+// if (pointInCircumcircle( d_triangles[ti], points[seq[i]-1] )) {
+// d_triangles.erase(d_triangles.begin()+ti);
+// deleted = true;
+// }
+// }
+// if (deleted) {
+// // make new triangles in hole
+// }
+// else {
+// // make new triangle from next points and new point
+// }
+
+// }
+
+// return triangles.size();
+// // double xy[point_num*2];
+
+// // for (uint i=0; i < point_num; i+=2) {
+// // xy[i] = poly.vertices[i].x();
+// // xy[i+1] = poly.vertices[i].y();
+// // }
+// // int tri_num;
+// // int tri_vert[2*point_num*3];
+// // int tri_nabe[2*point_num*3];
+
+// // int result = dtris2(point_num, xy, &tri_num, tri_vert, tri_nabe);
+
+// // if (result != 0)
+// // return triangles;
+
+// // double z = poly.getZ();
+// // for (int i=0; i<tri_num; i+=3) {
+// // Vector3d A(poly[tri_vert[i]].x(), poly[tri_vert[i]].y(), z);
+// // Vector3d B(poly[tri_vert[i+1]].x(), poly[tri_vert[i+1]].y(), z);
+// // Vector3d C(poly[tri_vert[i+2]].x(), poly[tri_vert[i+2]].y(), z);
+// // triangles.push_back(Triangle(A, B, C));
+// // }
+// }
View
5 src/slicer/geometry.h
@@ -101,8 +101,13 @@ bool IntersectXY(const Vector2d &p1, const Vector2d &p2,
double dist3D_Segment_to_Segment(const Vector3d &S1P0, const Vector3d &S1P1,
const Vector3d &S2P0, const Vector3d &S2P1, double SMALL_NUM);
+vector<Vector2d> simplified(const vector<Vector2d> &vert, double epsilon);
+int cleandist(vector<Vector2d> &vert, double epsilon);
+
Poly convexHull2D(const vector<Poly> &polygons);
+int delaunayTriang(const vector<Vector2d> &points, vector<Triangle> &triangles,
+ double z);
void testangles();
View
68 src/slicer/layer.cpp
@@ -27,8 +27,8 @@
// polygons will be simplified to thickness/CLEANFACTOR
#define CLEANFACTOR 5
-Layer::Layer(int layerno, double thick, uint skins)
- : LayerNo(layerno), thickness(thick), skins(skins)
+Layer::Layer(Layer * prevlayer, int layerno, double thick, uint skins)
+ : LayerNo(layerno), thickness(thick), previous(prevlayer), skins(skins)
{
normalInfill = NULL;
fullInfill = NULL;
@@ -38,7 +38,6 @@ Layer::Layer(int layerno, double thick, uint skins)
Max = Vector2d(G_MINDOUBLE, G_MINDOUBLE);
}
-
Layer::~Layer()
{
Clear();
@@ -129,6 +128,15 @@ void Layer::SetPolygons(const Matrix4d &T, const Shape &shape,
}
}
+
+bool Layer::pointInPolygons(const Vector2d &p) const
+{
+ for (uint i = 0; i<polygons.size(); i++)
+ if (!polygons[i].hole && polygons[i].vertexInside(p)) return true;
+ return false;
+}
+
+
int Layer::addShape(const Matrix4d &T, const Shape &shape, double z,
double &max_gradient)
{
@@ -329,14 +337,6 @@ void Layer::makeSkinPolygons()
if (skins<2) return;
skinFullFillPolygons = fullFillPolygons;
fullFillPolygons.clear();
- // vector<Poly> fp = fullFillPolygons;
- // //double dist = thickness/skins;
- // for (uint i=0; i<fullFillPolygons.size(); i++){
- // // skinFullFillPolygons.push_back(fp[i]);
- // fullFillPolygons[i].clear();
- // // //fp.erase(fp.begin()+i);
- // // //i--;
- // }
}
// add bridge polys and subtract them from normal and full fill polys
@@ -659,7 +659,7 @@ void Layer::MakeGcode(Vector3d &lastPos, //GCodeState &state,
const double extrf = settings.Hardware.GetExtrudeFactor(thickness);
vector<PLine3> lines3;
- Printlines printlines(&settings, offsetZ);
+ Printlines printlines(this, &settings, offsetZ);
vector<PLine> lines;
@@ -687,7 +687,7 @@ void Layer::MakeGcode(Vector3d &lastPos, //GCodeState &state,
skinFullInfills[s-1]->infillpolys.begin(),
skinFullInfills[s-1]->infillpolys.end());
// add all of this skin layer to lines
- printlines.makeLines(polys, (s==1), //displace at first skin
+ printlines.makeLines(SKIN, polys, (s==1), //displace at first skin
startPoint, lines, settings.Hardware.MaxShellSpeed);
if (s < skins) { // not on the last layer, this handle with all other lines
// have to get all these separately because z changes
@@ -704,12 +704,12 @@ void Layer::MakeGcode(Vector3d &lastPos, //GCodeState &state,
// 2. Skirt
vector <Poly> skirts(1); skirts[0] = skirtPolygon;
- printlines.makeLines(skirts, false,
+ printlines.makeLines(SKIRT, skirts, false,
startPoint, lines, settings.Hardware.MaxShellSpeed);
// 3. Support
if (supportInfill)
- printlines.makeLines(supportInfill->infillpolys, false,
+ printlines.makeLines(SUPPORT, supportInfill->infillpolys, false,
startPoint, lines);
// 4. all other polygons:
@@ -718,7 +718,7 @@ void Layer::MakeGcode(Vector3d &lastPos, //GCodeState &state,
for(int p=shellPolygons.size()-1; p>=0; p--) // inner to outer
polys.insert(polys.end(), shellPolygons[p].begin(),shellPolygons[p].end());
// printlines.makeLines(shellPolygons[p], (p==(int)(shellPolygons.size())-1),
- printlines.makeLines(polys, true, //displace at beginning
+ printlines.makeLines(SHELL, polys, true, //displace at beginning
startPoint, lines, settings.Hardware.MaxShellSpeed);
// TODO: sort inner to outer in printlines
polys.clear();
@@ -739,7 +739,7 @@ void Layer::MakeGcode(Vector3d &lastPos, //GCodeState &state,
bridgeInfills[b]->infillpolys.begin(),
bridgeInfills[b]->infillpolys.end());
- printlines.makeLines(polys, true, //displace at beginning
+ printlines.makeLines(INFILL, polys, true, //displace at beginning
startPoint, lines);
polys.clear();
@@ -817,10 +817,9 @@ string Layer::info() const
ostr<<", support "<<supportInfill->size() ;
ostr <<", skinfills "<<skinFullInfills.size() ;
- // if (next)
- // cout <<", next: "<<next->LayerNo;
- // if (previous)
- // cout <<", previous: "<<previous->LayerNo;
+ if (previous != NULL)
+ ostr << " prev.No=" << previous->LayerNo;
+
return ostr.str();
}
@@ -857,6 +856,16 @@ void draw_polys(const vector <Poly> &polys, int gl_type, int linewidth, int poin
polys[p].draw(gl_type);
}
}
+void draw_polys_surface(vector <Poly> &polys, double cleandist,
+ const float *rgb, float a)
+{
+ glColor4f(rgb[0],rgb[1],rgb[2], a);
+ for(size_t p=0; p<polys.size();p++) {
+ polys[p].cleanup(cleandist);
+ ::cleandist(polys[p].vertices, cleandist);
+ polys[p].draw_as_surface();
+ }
+}
void draw_polys(const vector< vector <Poly> > &polys, int gl_type, int linewidth, int pointsize,
const float *rgb, float a)
{
@@ -878,16 +887,17 @@ float const BLUE2[] = {0.5,0.5,1.0};
float const RED[] = {1, 0, 0};
float const RED2[] = {0.8,0.5,0.5};
float const RED3[] = {0.8,0.3,0.1};
-float const ORANGE[] = {1, 0, 0};
+float const ORANGE[] = {1, 0.5, 0};
float const YELLOW[] = {1, 1, 0};
float const YELLOW2[] = {1, 1, 0.2};
float const WHITE[] = {1, 1, 1};
float const GREY[] = {0.5,0.5,0.5};
+float const VIOLET[] = {0.8,0.0,0.8};
void Layer::Draw(bool DrawVertexNumbers, bool DrawLineNumbers,
bool DrawOutlineNumbers, bool DrawCPLineNumbers,
bool DrawCPVertexNumbers, bool DisplayInfill,
- bool DebugInfill)
+ bool DebugInfill, bool showOverhang)
{
draw_polys(polygons, GL_LINE_LOOP, 1, 3, RED, 1);
draw_polys(polygons, GL_POINTS, 1, 3, RED, 1);
@@ -979,6 +989,18 @@ void Layer::Draw(bool DrawVertexNumbers, bool DrawLineNumbers,
for(size_t q=0; q<shellPolygons[p].size();q++)
shellPolygons[p][q].drawVertexNumbers();
}
+
+ if (showOverhang)
+ if (previous!=NULL) {
+ Clipping clipp;
+ clipp.addPolys(polygons, subject);
+ vector<Poly> prevoffset = Clipping::getOffset(previous->polygons, thickness/2);
+ clipp.addPolys(prevoffset, clip);
+ clipp.setZ(Z);
+ vector<Poly> overhangs = clipp.subtract();//CL::pftNonZero,CL::pftNonZero);
+ draw_polys(overhangs, GL_LINE_LOOP, 4, 3, VIOLET, 0.8);
+ //draw_polys_surface(overhangs, thickness/3, VIOLET , 0.5); // crash
+ }
}
void Layer::DrawMeasures(const Vector2d &point)
View
14 src/slicer/layer.h
@@ -36,7 +36,7 @@ class Layer
public:
Layer();
- Layer(int layerno=-1, double thick=0., uint skins=1);
+ Layer(Layer * previous, int layerno=-1, double thick=0., uint skins=1);
~Layer();
@@ -46,10 +46,17 @@ class Layer
double getZ(){return Z;}
void setZ(double z){Z=z;}
+ Layer * getPrevious() const {return previous;};
+ void setPrevious(Layer * prevlayer){previous = prevlayer;};
+
Vector2d getMin() const {return Min;};
Vector2d getMax() const {return Max;};
void setMinMax(const Poly &poly);
void setMinMax(const vector<Poly> &polys);
+
+
+ bool pointInPolygons(const Vector2d &p) const;
+
/* void setBBox(Vector2d min, Vector2d max); */
/* void setBBox(vector<Vector2d> minmax); */
/* void setBBox(Vector3d min, Vector3d max); */
@@ -123,7 +130,8 @@ class Layer
void Draw(bool DrawVertexNumbers, bool DrawLineNumbers,
bool DrawOutlineNumbers, bool DrawCPLineNumbers,
- bool DrawCPVertexNumbers, bool DisplayInfill, bool DebugInfill);
+ bool DrawCPVertexNumbers, bool DisplayInfill,
+ bool DebugInfill, bool showOverhang);
void DrawMeasures(const Vector2d &point);
void Clear();
@@ -139,6 +147,8 @@ class Layer
private:
+ Layer * previous;
+
Vector2d Min, Max; // Bounding box
Infill * normalInfill;
View
59 src/slicer/poly.cpp
@@ -72,56 +72,16 @@ Poly::~Poly()
void Poly::cleanup(double epsilon)
{
- vertices = cleaned(vertices, epsilon);
+ vertices = simplified(vertices, epsilon);
if (!closed) return;
uint n_vert = vertices.size();
vector<Vector2d> invert;
invert.insert(invert.end(),vertices.begin()+n_vert/2,vertices.end());
invert.insert(invert.end(),vertices.begin(),vertices.begin()+n_vert/2);
- vertices = cleaned(invert, epsilon);
+ vertices = simplified(invert, epsilon);
calcHole();
}
-// Douglas-Peucker algorithm
-vector<Vector2d> Poly::cleaned(const vector<Vector2d> &vert, double epsilon)
-{
- if (epsilon == 0) return vert;
- uint n_vert = vert.size();
- if (n_vert<3) return vert;
- double dmax = 0;
- //Find the point with the maximum distance from line start-end
- uint index = 0;
- Vector2d normal = normalV(vert.back()-vert.front());
- normal.normalize();
- if( (normal.length()==0) || ((abs(normal.length())-1)>epsilon) ) return vert;
- for (uint i = 1; i < n_vert-1 ; i++)
- {
- double dist = abs((vert[i]-vert.front()).dot(normal));
- if (dist >= epsilon && dist > dmax) {
- index = i;
- dmax = dist;
- }
- }
- vector<Vector2d> newvert;
- if (index > 0) // there is a point > epsilon
- {
- // divide at max dist point and cleanup both parts recursively
- vector<Vector2d> part1;
- part1.insert(part1.end(), vert.begin(), vert.begin()+index+1);
- vector<Vector2d> c1 = cleaned(part1, epsilon);
- vector<Vector2d> part2;
- part2.insert(part2.end(), vert.begin()+index, vert.end());
- vector<Vector2d> c2 = cleaned(part2, epsilon);
- newvert.insert(newvert.end(), c1.begin(), c1.end()-1);
- newvert.insert(newvert.end(), c2.begin(), c2.end());
- }
- else
- { // all points are nearer than espilon
- newvert.push_back(vert.front());
- newvert.push_back(vert.back());
- }
- return newvert;
-}
void Poly::calcHole()
@@ -576,10 +536,15 @@ int Poly::getTriangulation(vector<Triangle> &triangles) const
{
if(vertices.size()<3) return 0;
triangles.clear();
+
+ // return delaunayTriang(vertices, triangles, z);
+
vector<p2t::Point*> points(vertices.size());
- // add 1000,1000 because poly2tri crashed on some negative values
+ // add offset because poly2tri crashes on some negative values?
+ const double OFF = 0;
for (guint i=0; i<vertices.size(); i++) {
- points[i] = new p2t::Point(vertices[i].x()+1000,vertices[i].y()+1000);
+ points[i] = new p2t::Point(vertices[i].x()+OFF,
+ vertices[i].y()+OFF);
}
p2t::CDT cdt(points);
cdt.Triangulate();
@@ -588,9 +553,9 @@ int Poly::getTriangulation(vector<Triangle> &triangles) const
const p2t::Point *tp0 = ptriangles[i]->GetPoint(0);
const p2t::Point *tp1 = ptriangles[i]->GetPoint(1);
const p2t::Point *tp2 = ptriangles[i]->GetPoint(2);
- Vector3d A(tp0->x-1000, tp0->y-1000, z);
- Vector3d B(tp1->x-1000, tp1->y-1000, z);
- Vector3d C(tp2->x-1000, tp2->y-1000, z);
+ Vector3d A((tp0->x-OFF), (tp0->y-OFF), z);
+ Vector3d B((tp1->x-OFF), (tp1->y-OFF), z);
+ Vector3d C((tp2->x-OFF), (tp2->y-OFF), z);
triangles.push_back(Triangle(A, B, C));
}
return triangles.size();
View
4 src/slicer/poly.h
@@ -55,9 +55,7 @@ class Poly
// simplify douglas-peucker
void cleanup(double maxerror);
- static vector<Vector2d> cleaned(const vector<Vector2d> &vertices,
- double maxerror);
-
+
void reverse() {std::reverse(vertices.begin(),vertices.end());holecalculated = false;};
void clear(){vertices.clear(); holecalculated = false;};
View
24 src/slicer/printlines.cpp
@@ -19,6 +19,7 @@
#include "printlines.h"
#include "poly.h"
+#include "layer.h"
#include "gcodestate.h"
///////////// PLine3: single 3D printline //////////////////////
@@ -260,14 +261,16 @@ string PLine::info() const
///////////// Printlines //////////////////////
-Printlines::Printlines(const Settings * settings, double z_offset) :
+Printlines::Printlines(const Layer * layer, const Settings * settings, double z_offset) :
Zoffset(z_offset), name(""), slowdownfactor(1.)
{
this->settings = settings;
+ this->layer = layer;
}
-void Printlines::addLine(vector<PLine> &lines, const Vector2d &from, const Vector2d &to,
+void Printlines::addLine(PLineArea area, vector<PLine> &lines,
+ const Vector2d &from, const Vector2d &to,
double speed, double movespeed, double feedrate) const
{
if (to==from) return;
@@ -283,10 +286,18 @@ void Printlines::addLine(vector<PLine> &lines, const Vector2d &from, const Vecto
lfrom = lastpos;
}
}
+
+ // SLOW
+ // if (area == SHELL && layer->getPrevious() != NULL) {
+ // //bool freeair_from = layer->getPrevious()->pointInPolygons(from);
+ // bool freeair_to = layer->getPrevious()->pointInPolygons(to);
+ // //cerr << "free air?" << freeair_from << " - " <<freeair_to << endl;
+ // }
lines.push_back(PLine(lfrom, to, speed, feedrate));
}
-void Printlines::addPoly(vector<PLine> &lines, const Poly &poly, int startindex,
+void Printlines::addPoly(PLineArea area, vector<PLine> &lines,
+ const Poly &poly, int startindex,
double speed, double movespeed)
{
vector<Vector2d> pvert;
@@ -294,12 +305,13 @@ void Printlines::addPoly(vector<PLine> &lines, const Poly &poly, int startindex,
if (pvert.size() == 0) return;
assert(pvert.size() % 2 == 0);
for (uint i=0; i<pvert.size();i+=2){
- addLine(lines, pvert[i], pvert[i+1], speed, movespeed, poly.getExtrusionFactor());
+ addLine(area, lines, pvert[i], pvert[i+1], speed, movespeed, poly.getExtrusionFactor());
}
setZ(poly.getZ());
}
-void Printlines::makeLines(const vector<Poly> &polys,
+void Printlines::makeLines(PLineArea area,
+ const vector<Poly> &polys,
bool displace_startpoint,
Vector2d &startPoint,
vector<PLine> &lines,
@@ -347,7 +359,7 @@ void Printlines::makeLines(const vector<Poly> &polys,
nvindex = polys[npindex].nextVertex(nvindex);
}
if (npindex >= 0 && npindex >=0) {
- addPoly(lines, polys[npindex], nvindex, maxspeed, movespeed);
+ addPoly(area, lines, polys[npindex], nvindex, maxspeed, movespeed);
done[npindex]=true;
ndone++;
}
View
19 src/slicer/printlines.h
@@ -27,6 +27,7 @@
class PLine; // see below
+enum PLineArea { UNDEF, SHELL, SKIN, INFILL, SUPPORT, SKIRT };
// 3D printline for making GCode
@@ -63,6 +64,9 @@ class PLine
{
friend class PLine3;
friend class Printlines;
+
+ PLineArea area;
+
// non-arc
Vector2d from, to;
double speed; // mm/min (!)
@@ -109,13 +113,17 @@ class Printlines
string name;
- void addPoly(vector<PLine> &lines, const Poly &poly, int startindex=0,
+ void addPoly(PLineArea area, vector<PLine> &lines,
+ const Poly &poly, int startindex=0,
double speed=1, double movespeed=1);
- void addLine(vector<PLine> &lines, const Vector2d &from, const Vector2d &to,
+ void addLine(PLineArea area, vector<PLine> &lines,
+ const Vector2d &from, const Vector2d &to,
double speed=1, double movespeed=1, double feedrate=1.0) const;
+ const Layer * layer;
+
public:
- Printlines(const Settings *settings, double z_offset=0);
+ Printlines(const Layer * layer, const Settings *settings, double z_offset=0);
~Printlines(){};
const Settings *settings;
@@ -124,10 +132,11 @@ class Printlines
Vector2d lastPoint() const;
- void makeLines(const vector<Poly> &polys,
+ void makeLines(PLineArea area,
+ const vector<Poly> &polys,
bool displace_startpoint,
Vector2d &startPoint,
- vector<PLine> &lines,
+ vector<PLine> &lines,
double maxspeed = 0);
void optimize(double linewidth,

No commit comments for this range

Something went wrong with that request. Please try again.