예제 #1
0
파일: Tabs.cs 프로젝트: JackTing/PathCAM
        public Tabs(LineStrip boundary, float toolRadius, bool inside = false)
        {
            originalBoundary = new Slice(new LineStrip[] { boundary }, new Plane(Vector3.UnitZ, Vector3.Zero));
            float offset = toolRadius;
            if (inside)
            {
                offset = -offset;
            }
            Slice slice = new Slice(originalBoundary);
            slice.Offset(offset);
            this.boundary = slice.GetLines(Slice.LineType.Outside).First(s => true);
            this.toolRadius = toolRadius;

            float length = this.boundary.Length(LineStrip.Type.Closed);
            int numTabs = (int)(length / desiredSpacing);
            if (numTabs < minTabs)
            {
                numTabs = 0;
            }

            float tabSpacing = length / numTabs;

            tabLocations = new List<Vector3>();
            foreach (var point in this.boundary.PointsAlongLine(tabSpacing, tabSpacing / 2.0f))
            {
                tabLocations.Add(point);
            }
        }
예제 #2
0
        private LineStrip LineStripFromPolygon(Path polygon)
        {
            LineStrip line = new LineStrip();

            foreach (IntPoint point in polygon)
            {
                line.Append(TransformTo3D(point));
            }
            return(line);
        }
예제 #3
0
        private Path LineStripToPolygon(LineStrip line)
        {
            Path polygon = new Path();

            foreach (var point in line.Vertices)
            {
                Vector2 result = Vector3.Transform(point, transform).Xy;
                polygon.Add(new IntPoint((long)Math.Round(result.X), (long)Math.Round(result.Y)));
            }
            return(polygon);
        }
예제 #4
0
            /// <summary>
            /// Convert the internal data to a list of the largest possible contiguous loops.
            /// NOTE: This is destructive!
            /// </summary>
            /// <returns></returns>
            public List <LineStrip> GetOuterLoops()
            {
                List <LineStrip> loops = new List <LineStrip>();

                foreach (Segment segment in segments)
                {
                    LineStrip loop = FindLargestLoop(segment);
                    if (loop != null)
                    {
                        loops.Add(loop);
                    }
                }
                return(loops);
            }
예제 #5
0
        /// <summary>
        /// Create a slice from an open path with the given width
        /// </summary>
        /// <param name="path"></param>
        /// <param name="width"></param>
        /// <param name="plane"></param>
        public Slice(LineStrip path, float width, Plane plane, bool closed = false)
        {
            this.plane       = plane;
            transform        = plane.CreateMatrix();
            transform        = Matrix4.Mult(transform, Matrix4.CreateScale(scale));
            inverseTransform = Matrix4.Invert(transform);
            polyTree         = new PolyTree();

            ClipperOffset co = new ClipperOffset();

            co.ArcTolerance = scale * 0.0001f;
            if (closed)
            {
                co.AddPath(LineStripToPolygon(path), JoinType.jtRound, EndType.etClosedLine);
            }
            else
            {
                co.AddPath(LineStripToPolygon(path), JoinType.jtRound, EndType.etOpenRound);
            }
            co.Execute(ref this.polyTree, scale * width / 2.0f);
        }
예제 #6
0
파일: Slice.cs 프로젝트: JackTing/PathCAM
            //private float height = .050f;
            private LineStrip FindLargestLoop(Segment start)
            {
                //height += 0.050f;
                Vector3 normal = new Vector3 (0, 0, 1);

                Segment next = start;

                List<Segment> seen = new List<Segment>();

                while (!seen.Contains(next))
                {
                    //GL.Disable(EnableCap.Lighting);
                    //GL.LineWidth(3);
                    //GL.Begin(PrimitiveType.Lines);
                    //GL.Color3(Color.Blue);
                    //GL.Vertex3(next.a.vector.X, next.a.vector.Y, height);
                    //GL.Color3(Color.LightGreen);
                    //height += .010f;
                    //GL.Vertex3(next.b.vector.X, next.b.vector.Y, height);
                    //GL.End();
                    //GL.LineWidth(1);
                    //GL.Enable(EnableCap.Lighting);

                    seen.Add(next);
                    Segment best = null;
                    float largestAngle = 0;
                    foreach (Segment s in next.b.used_as_a)
                    {
                        float angle = Angle(-s.Normal, next.Normal, normal);
                        if (angle > largestAngle)
                        {
                            largestAngle = angle;
                            best = s;
                        }
                    }
                    if (best == null)
                    {
                        // No loops
                        return null;
                    }

                    // Destructive: remove references to this element so it's not searched again.
                    // Note: only need to remove forward links (from used_as_a).  The links from
                    // used_as_b could be cleared too, but it's not necessary for the algorithm.
                    next.b.used_as_a.Clear();
                    //next.b.used_as_b.Clear();

                    next = best;
                }
                // Remove all up to the first matched index
                int index = seen.IndexOf(next);
                seen.RemoveRange(0, index);

                LineStrip loop = new LineStrip();
                foreach (Segment seg in seen)
                {
                    loop.Append(seg.a.vector);
                }

                return loop;
            }
예제 #7
0
파일: Slice.cs 프로젝트: JackTing/PathCAM
 private Path LineStripToPolygon(LineStrip line)
 {
     Path polygon = new Path();
     foreach (var point in line.Vertices)
     {
         Vector2 result = Vector3.Transform(point, transform).Xy;
         polygon.Add(new IntPoint((long)Math.Round(result.X), (long)Math.Round(result.Y)));
     }
     return polygon;
 }
예제 #8
0
파일: Slice.cs 프로젝트: JackTing/PathCAM
 private LineStrip LineStripFromPolygon(Path polygon)
 {
     LineStrip line = new LineStrip();
     foreach (IntPoint point in polygon)
     {
         line.Append(TransformTo3D(point));
     }
     return line;
 }
예제 #9
0
파일: Slice.cs 프로젝트: JackTing/PathCAM
        /// <summary>
        /// Create a slice from an open path with the given width
        /// </summary>
        /// <param name="path"></param>
        /// <param name="width"></param>
        /// <param name="plane"></param>
        public Slice(LineStrip path, float width, Plane plane, bool closed = false)
        {
            this.plane = plane;
            transform = plane.CreateMatrix();
            transform = Matrix4.Mult(transform, Matrix4.CreateScale(scale));
            inverseTransform = Matrix4.Invert(transform);
            polyTree = new PolyTree();

            ClipperOffset co = new ClipperOffset();
            co.ArcTolerance = scale * 0.0001f;
            if (closed)
            {
                co.AddPath(LineStripToPolygon(path), JoinType.jtRound, EndType.etClosedLine);
            }
            else
            {
                co.AddPath(LineStripToPolygon(path), JoinType.jtRound, EndType.etOpenRound);
            }
            co.Execute(ref this.polyTree, scale * width / 2.0f);
        }
예제 #10
0
파일: TabsGUI.cs 프로젝트: JackTing/PathCAM
 public TabsGUI(LineStrip boundary, float toolRadius, bool inside = false)
     : base(boundary, toolRadius, inside)
 {
     drawSlice = new Slice(this.TabPath, toolRadius * 2.0f, new Plane(Vector3.UnitZ, Vector3.Zero), true);
 }
예제 #11
0
파일: PathCAM.cs 프로젝트: JackTing/PathCAM
        private void boundaryCheckButton_Click(object sender, EventArgs e)
        {
            float xMin = -router.ToolDiameter;
            float xMax = router.ToolDiameter;
            float yMin = -router.ToolDiameter;
            float yMax = router.ToolDiameter;

            foreach (Object o in drawing3D.GetObjects())
            {
                if (o is TriangleMeshGUI)
                {
                    var triangles = o as TriangleMeshGUI;
                    xMin = Math.Min(triangles.MinPoint.X - router.ToolDiameter + triangles.Offset.X, xMin);
                    xMax = Math.Max(triangles.MaxPoint.X + router.ToolDiameter + triangles.Offset.X, xMax);
                    yMin = Math.Min(triangles.MinPoint.Y - router.ToolDiameter + triangles.Offset.Y, yMin);
                    yMax = Math.Max(triangles.MaxPoint.Y + router.ToolDiameter + triangles.Offset.Y, yMax);
                }
            }

            LineStrip r = new LineStrip();
            r.Append(new Vector3(xMin, yMin, router.MoveHeight));
            r.Append(new Vector3(xMax, yMin, router.MoveHeight));
            r.Append(new Vector3(xMax, yMax, router.MoveHeight));
            r.Append(new Vector3(xMin, yMax, router.MoveHeight));
            r.Append(new Vector3(xMin, yMin, router.MoveHeight));
            router.RoutPath(r, false, Vector3.Zero);
            router.Complete();
        }
예제 #12
0
파일: Tabs.cs 프로젝트: JackTing/PathCAM
        /// <summary>
        /// Create another line strip which follows the same path, but avoids tab locations.
        /// NOTE: this currently only works on closed input lines.  The algorithm could
        /// be modified to work correctly with open paths too, but that's not needed yet.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public LineStrip AvoidTabs(LineStrip input)
        {
            LineStrip ret = new LineStrip();
            foreach (var segment in input.Segments(LineStrip.Type.Closed))
            {
                if (segment.Length < 0.0001f)
                {
                    continue;
                }
                if (segment.A.Z > tabHeight && segment.B.Z > tabHeight)
                {
                    ret.Append(segment.B);
                    continue;
                }
                List<LineSegment> remainingSegments = new List<LineSegment>();
                remainingSegments.Add(segment);
                foreach (Vector3 tab in this.TabLocations)
                {
                    var i = new LineSegmentCircleIntersect(segment, tab, tabRadius + toolRadius);
                    if (i.type == LineSegmentCircleIntersect.IntersectType.Segment)
                    {
                        List<LineSegment> temp = new List<LineSegment>();

                        foreach (var seg in remainingSegments)
                        {
                            temp.AddRange(seg.Subtract(i.IntersectSegment));
                        }
                        remainingSegments = temp;
                    }
                }
                remainingSegments.RemoveAll(s => s.Length < 0.0001f);

                if (remainingSegments.Count == 0)
                {
                    // Entire segment is within a tab
                    TestAddPoint(ClearHeight(segment.B, tabHeight), ret.Vertices);
                }
                else
                {
                    // Everything described in "remainingSegments" is outside of the tab, and the spaces
                    // between are on the tab.  The path between is known since it's always a straight line.
                    remainingSegments.Sort((s1, s2) => (s1.A - segment.A).Length.CompareTo((s2.A - segment.A).Length));
                    foreach (var s in remainingSegments)
                    {
                        TestAddPoint(ClearHeight(s.A, tabHeight), ret.Vertices);
                        TestAddPoint(s.A, ret.Vertices);
                        TestAddPoint(s.B, ret.Vertices);
                        TestAddPoint(ClearHeight(s.B, tabHeight), ret.Vertices);
                    }
                    TestAddPoint(ClearHeight(segment.B, tabHeight), ret.Vertices);
                }
            }

            return ret;
        }
예제 #13
0
            //private float height = .050f;
            private LineStrip FindLargestLoop(Segment start)
            {
                //height += 0.050f;
                Vector3 normal = new Vector3(0, 0, 1);

                Segment next = start;

                List <Segment> seen = new List <Segment>();

                while (!seen.Contains(next))
                {
                    //GL.Disable(EnableCap.Lighting);
                    //GL.LineWidth(3);
                    //GL.Begin(PrimitiveType.Lines);
                    //GL.Color3(Color.Blue);
                    //GL.Vertex3(next.a.vector.X, next.a.vector.Y, height);
                    //GL.Color3(Color.LightGreen);
                    //height += .010f;
                    //GL.Vertex3(next.b.vector.X, next.b.vector.Y, height);
                    //GL.End();
                    //GL.LineWidth(1);
                    //GL.Enable(EnableCap.Lighting);

                    seen.Add(next);
                    Segment best         = null;
                    float   largestAngle = 0;
                    foreach (Segment s in next.b.used_as_a)
                    {
                        float angle = Angle(-s.Normal, next.Normal, normal);
                        if (angle > largestAngle)
                        {
                            largestAngle = angle;
                            best         = s;
                        }
                    }
                    if (best == null)
                    {
                        // No loops
                        return(null);
                    }

                    // Destructive: remove references to this element so it's not searched again.
                    // Note: only need to remove forward links (from used_as_a).  The links from
                    // used_as_b could be cleared too, but it's not necessary for the algorithm.
                    next.b.used_as_a.Clear();
                    //next.b.used_as_b.Clear();

                    next = best;
                }
                // Remove all up to the first matched index
                int index = seen.IndexOf(next);

                seen.RemoveRange(0, index);

                LineStrip loop = new LineStrip();

                foreach (Segment seg in seen)
                {
                    loop.Append(seg.a.vector);
                }

                return(loop);
            }
예제 #14
0
파일: Router.cs 프로젝트: JackTing/PathCAM
        public void RoutPath(LineStrip line, bool backwards, Vector3 offset)
        {
            bool first = true;

            foreach (Vector3 point in line.Vertices)
            {
                // TODO: Pick some unit and stick with it!  Inches would be fine.
                Vector3 pointOffset = point + offset;

                MoveTool m = new MoveTool(pointOffset, MoveTool.SpeedType.Cutting);
                if (first)
                {
                    first = false;

                    if ((finalPosition.Xy - pointOffset.Xy).Length > .0001)
                    {
                        // Need to move the router up, over to new position, then down again.
                        MoveTool m1 = new MoveTool(new Vector3(finalPosition.X, finalPosition.Y, move_height), MoveTool.SpeedType.Rapid);
                        MoveTool m2 = new MoveTool(new Vector3(m.Target.X, m.Target.Y, move_height), MoveTool.SpeedType.Rapid);
                        AddCommand(m1);
                        AddCommand(m2);
                    }
                }
                AddCommand(m);
            }
        }