Skip to content

Commit

Permalink
Fixed tool direction in holes
Browse files Browse the repository at this point in the history
Clockwise in holes, counterclockwise outside.  Good and consistent.
  • Loading branch information
xenovacivus committed Jan 16, 2014
1 parent af62dbe commit ba19fc7
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 42 deletions.
20 changes: 15 additions & 5 deletions GUI/PathCAM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,25 @@ void worker_LoadMesh(object sender, DoWorkEventArgs e)
e.Result = triangleMesh;
}


// For debugging, generate paths for the first loaded
// trianglemesh every frame (allows drawing code inside the generation)
//TriangleMeshGUI m = null;
void IOpenGLDrawable.Draw()
{
try
{
foreach (var mesh in inProgressMeshes)
{
mesh.Draw();
//if (m == null)
//{
// m = mesh;
//}
}
//if (m != null)
//{
// PathPlanner.PlanPaths(m, m.Tabs.ConvertAll(tab => tab as Tabs), router);
//}
}
catch (Exception)
{
Expand Down Expand Up @@ -375,7 +385,7 @@ private void InitializeComponent()
//
this.showRobotFormCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.showRobotFormCheckbox.AutoSize = true;
this.showRobotFormCheckbox.Location = new System.Drawing.Point(-1, 449);
this.showRobotFormCheckbox.Location = new System.Drawing.Point(-1, 549);
this.showRobotFormCheckbox.Name = "showRobotFormCheckbox";
this.showRobotFormCheckbox.Size = new System.Drawing.Size(15, 14);
this.showRobotFormCheckbox.TabIndex = 69;
Expand All @@ -395,7 +405,7 @@ private void InitializeComponent()
//
this.robotControl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.robotControl.BackColor = System.Drawing.Color.Transparent;
this.robotControl.Location = new System.Drawing.Point(-1, 327);
this.robotControl.Location = new System.Drawing.Point(-1, 427);
this.robotControl.Name = "robotControl";
this.robotControl.Size = new System.Drawing.Size(169, 136);
this.robotControl.TabIndex = 8;
Expand All @@ -414,15 +424,15 @@ private void InitializeComponent()
this.drawing3D.MinimumSize = new System.Drawing.Size(10, 10);
this.drawing3D.Name = "drawing3D";
this.drawing3D.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
this.drawing3D.Size = new System.Drawing.Size(100, 98);
this.drawing3D.Size = new System.Drawing.Size(300, 198);
this.drawing3D.TabIndex = 68;
this.drawing3D.VSync = false;
//
// PathCAM
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(584, 462);
this.ClientSize = new System.Drawing.Size(784, 562);
this.Controls.Add(this.showRobotFormCheckbox);
this.Controls.Add(this.saveGcodeButton);
this.Controls.Add(this.button2);
Expand Down
4 changes: 2 additions & 2 deletions Geometry/Slice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public Slice(TriangleMesh mesh, Plane plane)
else
{
Slice s = new Slice(lineHandler.GetOuterLoops(), plane);
this.Add(s);
this.Union(s);
}
}
//GL.End();
Expand Down Expand Up @@ -760,7 +760,7 @@ private Slice GetPairs(bool outside)
return s;
}

public void Add(Slice other)
public void Union(Slice other)
{
Clipper c = new Clipper();
c.Clear();
Expand Down
3 changes: 2 additions & 1 deletion Robot/Robot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ private void NewDataAvailable(SerialPortWrapper.SimpleSerialPacket packet)
{
lock (thisLock)
{
elapsedCounter = 0;
if (currentCommand == null)
{
Console.WriteLine("Error: Received data, but no command was sent!");
Expand Down Expand Up @@ -173,7 +174,7 @@ private void NewDataAvailable(SerialPortWrapper.SimpleSerialPacket packet)

currentCommand = GetNextCommand(locations);

elapsedCounter = 0;

serial.Transmit(currentCommand.GenerateCommand(), 0x21);
}
else
Expand Down
106 changes: 72 additions & 34 deletions Router/Paths/PathPlanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,75 @@ namespace Router.Paths
public class PathPlanner
{
/// <summary>
/// Find a toolpath which will remove everything described in the slice.
/// Get slices from the top of the triangle mesh to the bottom, spaced no more than
/// the specified cut depth in router. The first slice is the highest.
/// </summary>
/// <param name="slice"></param>
public static void PlanPaths(Slice slice)
/// <param name="triangles"></param>
/// <param name="router"></param>
/// <returns></returns>
private static List<Slice> GetSlices(TriangleMesh triangles, Router router)
{
// 1. Get all small holes in the slice - rout them first
// 2. Rout everything remaining in the slice from
float maxCutDepth = router.MaxCutDepth;
float minZ = triangles.MinPoint.Z;
float maxZ = triangles.MaxPoint.Z;

float skin = 0.002f; // Depth above the minpoint and below the maxpoint to slice.

// Figure out an even maximum cut depth
int layers = (int)((maxZ - minZ) / maxCutDepth + 0.95f);
float actualCutDepth = (maxZ - minZ - 2*skin) / layers;
actualCutDepth = Math.Min(maxZ - minZ - 2*skin, actualCutDepth);

List<Slice> slices = new List<Slice>();

for (float height = maxZ - skin; height > -actualCutDepth / 2.0f; height -= actualCutDepth)
{
var slice = new Slice(triangles, new Plane(Vector3.UnitZ, new Vector3(0, 0, height)));
foreach (var higherSlice in slices)
{
slice.Union(higherSlice);
}
slices.Add(slice);
}
return slices;
}

public static List<LineStrip> PlanPaths(TriangleMesh triangles, List<Tabs> tabs, Router router)
{
List<LineStrip> routs = new List<LineStrip>();

float toolRadius = router.ToolDiameter / 2.0f; // Router units are inches
float toolRadius = router.ToolDiameter / 2.0f;
float maxCutDepth = router.MaxCutDepth;
float lastPassHeight = router.LastPassHeight;
float cleanPassFactor = 0.90f; // 90% of the tool radius will be removed on the clean pass

float minZ = triangles.MinPoint.Z;
float maxZ = triangles.MaxPoint.Z;

Slice boundary = new Slice(triangles, new Plane(Vector3.UnitZ, new Vector3(0, 0, minZ)));
var slices = GetSlices(triangles, router);
//GL.PushMatrix();
//foreach (var s in slices)
//{
// GL.Translate(triangles.MaxPoint.X - triangles.MinPoint.X, 0, 0);
// DrawSlice(Color.Orange, Color.Black, s);
//}
//GL.PopMatrix();

Slice top = slices[0];
slices.RemoveAt(0);
Slice boundary = new Slice (slices[slices.Count - 1]);

boundary.Offset(toolRadius * (cleanPassFactor + 1.05f)); // Note: this is slightly larger to allow some polygon width to exist

// Enable complete removal of holes with no tabs
foreach (var tab in tabs)
{
if (tab.TabLocations.Count() == 0)
{
boundary.Add(tab.Boundary);
boundary.Union(tab.Boundary);
}
}

Slice top = new Slice(triangles, new Plane(Vector3.UnitZ, new Vector3(0, 0, maxZ)));
top.SubtractFrom(boundary);

//GL.PushMatrix();
Expand All @@ -70,29 +107,22 @@ public static List<LineStrip> PlanPaths(TriangleMesh triangles, List<Tabs> tabs,
//GL.PopMatrix();

Slice holes = top.PolygonsWithoutHoles();


List<Hole> holeRouts = new List<Hole>();
foreach (var polygon in holes.IndividualPolygons())
{
holeRouts.Add(new Hole(polygon, toolRadius, cleanPassFactor));
}

// Figure out a nice even maximum cut depth
int layers = (int)((maxZ - minZ) / maxCutDepth + 0.95f);
float actualCutDepth = (maxZ - minZ) / layers;

for (float height = minZ; height < maxZ; height += actualCutDepth)
foreach (Slice current in slices)
{
Slice current = new Slice(triangles, new Plane(Vector3.UnitZ, new Vector3(0, 0, height)));
current.Offset(toolRadius);
GL.PushMatrix();
GL.Translate(0, 0, -0.001f);
//DrawSlice(Color.Tan, Color.Gray, boundary);
GL.PopMatrix();
//DrawSlice(Color.Red, Color.Blue, current);
//GL.PushMatrix();
//GL.Translate(0, 0, -0.001f);
////DrawSlice(Color.Tan, Color.Gray, boundary);
//GL.PopMatrix();
////DrawSlice(Color.Red, Color.Blue, current);


Slice original = new Slice(current);
current.SubtractFrom(boundary);

Expand Down Expand Up @@ -123,20 +153,20 @@ public static List<LineStrip> PlanPaths(TriangleMesh triangles, List<Tabs> tabs,

// Rout all outside paths. These will be done from top down, one layer at a time for structural reasons.
// For the top several layers, two paths could be combined...
//var withHoles = outsidePairs.PolygonsWithHoles();
var outsideRouts = RoutAreasWithHoles(outsidePairs, toolRadius, cleanPassFactor, tabs, false);
var outsideRouts = RoutAreasWithHoles(insidePairs.PolygonsWithHoles(), toolRadius, cleanPassFactor, tabs, true);
var newLines = new List<LineStrip>();
foreach (var line in outsideRouts)
{
var r = new LineStrip();
r.AddRange(line.Vertices);
r.Append(line.Vertices[0]);
r.Vertices.Reverse();
newLines.Add(r);
}
routs.InsertRange(0, newLines);
routs.AddRange(newLines);


outsideRouts = RoutAreasWithHoles(insidePairs.PolygonsWithHoles(), toolRadius, cleanPassFactor, tabs, true);
outsideRouts = RoutAreasWithHoles(outsidePairs, toolRadius, cleanPassFactor, tabs, false);
newLines = new List<LineStrip>();
foreach (var line in outsideRouts)
{
Expand All @@ -145,7 +175,7 @@ public static List<LineStrip> PlanPaths(TriangleMesh triangles, List<Tabs> tabs,
r.Append(line.Vertices[0]);
newLines.Add(r);
}
routs.InsertRange(0, newLines);
routs.AddRange(newLines);
}

foreach (var hole in holeRouts)
Expand Down Expand Up @@ -327,16 +357,16 @@ public List<LineStrip> GetRouts()
GL.PushMatrix();
Slice lastPolygon = null;

for (int i = polygons.Count - 1; i >= 0; i--)
foreach (var p in polygons)
{
var p = polygons[i];
var routLast = p.GetLines(Slice.LineType.Outside).First(s => true);
routLast.Vertices.Add(routLast.Vertices[0]);
routLast.Vertices.Reverse();

Slice obliterate = new Slice(p);
obliterate.Offset(-toolRadius * cleanRoutFactor);

var routFirst = PathTree.ObliterateSlice(obliterate, toolRadius * 2.0f);
var routFirst = PathTree.ObliterateSlice(obliterate, toolRadius * 2.0f, true);

if (lastPolygon == null)
{
Expand Down Expand Up @@ -429,6 +459,7 @@ private class PathTree
private Slice slice;
private List<PathTree> children = new List<PathTree>();
private List<PathTree> badTrees;
private bool reverse;

#region Public Methods

Expand All @@ -439,13 +470,13 @@ private class PathTree
/// <param name="polygons"></param>
/// <param name="maxShrink">maximum distance between disjoint paths</param>
/// <returns></returns>
public static List<LineStrip> ObliterateSlice(Slice polygons, float maxShrink)
public static List<LineStrip> ObliterateSlice(Slice polygons, float maxShrink, bool reverse = false)
{
List<LineStrip> lines = new List<LineStrip>();

foreach (Slice slice in polygons.IndividualPolygons())
{
PathTree tree = new PathTree();
PathTree tree = new PathTree(reverse);
Slice inside = new Slice(slice.GetLines(Slice.LineType.Hole), slice.Plane);
Slice shrink = new Slice(slice);
while (shrink.Area() > 0)
Expand Down Expand Up @@ -474,21 +505,28 @@ public static List<LineStrip> ObliterateSlice(Slice polygons, float maxShrink)

#region Private Methods

private PathTree()
private PathTree(bool reverse)
{
slice = null;
badTrees = new List<PathTree>();
this.reverse = reverse;
}

private PathTree(Slice slice, PathTree parent)
{
this.badTrees = parent.badTrees;
this.slice = slice;
this.reverse = parent.reverse;
}

private LineStrip CreatePath()
{
return slice.GetLines(Geometry.Slice.LineType.Outside).First(s => true);
var path = slice.GetLines(Geometry.Slice.LineType.Outside).First(s => true);
if (reverse)
{
path.Vertices.Reverse();
}
return path;
}

private void Draw(Color lineColor, Color planeColor)
Expand Down

0 comments on commit ba19fc7

Please sign in to comment.