Author Topic: Cut polyline  (Read 182 times)

0 Members and 1 Guest are viewing this topic.

latour_g

  • Newt
  • Posts: 120
Cut polyline
« on: September 22, 2017, 11:29:47 am »
Hi,
I'm trying to cut a polyline (and add gap between the cut) where other polylines intersect with it.  I did the same for a line and it's working fine.  I have an error message when I try to change startpoint and endpoint of the

Code - C#: [Select]
  1. if (plL != null)
  2. {
  3.    DBObjectCollection objs = plL.GetSplitCurves(pnts);
  4.  
  5.    foreach (DBObject obj in objs)
  6.    {
  7.            Polyline plN = obj as Polyline;
  8.            Line li = new Line(plN.StartPoint, plN.EndPoint);
  9.  
  10.            //method or operation is not implemented
  11.            if (plN.StartPoint != plL.StartPoint || plN.StartPoint == pnts[0]) plN.StartPoint = UTIL.PolarPoint(plN.StartPoint, li.Angle, nScale * gap);
  12.            //method or operation is not implemented
  13.            if (plN.EndPoint != plL.EndPoint || plN.EndPoint == pnts[pnts.Count - 1]) plN.EndPoint = UTIL.PolarPoint(plN.EndPoint, li.Angle + Math.PI, nScale * gap);
  14.  
  15.            btr.AppendEntity(plN);
  16.            tr.AddNewlyCreatedDBObject(plN, true);
  17.            li.Dispose();
  18.    }
  19.    plL.Erase(true);
  20.    objs = null;
  21. }

UTIL.PolarPoint return a point.  I have replace it by a specific value just to make sure it's not the problem but I get the same error message.


Thanks

WILL HATCH

  • Bull Frog
  • Posts: 405
Re: Cut polyline
« Reply #1 on: September 22, 2017, 06:58:13 pm »
built this years ago to address this sort of situation, pretty fuzzy memories so you're on your own from here
Code - C#: [Select]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Autodesk.AutoCAD.ApplicationServices;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using Autodesk.AutoCAD.Runtime;
  9. using Autodesk.AutoCAD.EditorInput;
  10. using Autodesk.AutoCAD.Geometry;
  11.  
  12. namespace Gaps
  13. {
  14.    public static class Extention
  15.    {
  16.        public static bool Parallel(this Vector3d a, Vector3d b, double delta)
  17.        {
  18.            double c = Math.Abs(a.GetAngleTo(b));
  19.            return c < delta || c > Math.PI - delta;
  20.        }
  21.        public static Line Extrapolate(this IEnumerable<Line> lines)
  22.        {
  23.            List<Point3d> points = new List<Point3d>();
  24.            Line line = lines.First();
  25.            foreach (var item in lines)
  26.            {
  27.                points.Add(item.StartPoint);
  28.                points.Add(item.EndPoint);
  29.            }
  30.            points = points.OrderBy(a => line.Delta.DotProduct(a.GetAsVector())).ToList();
  31.            return new Line(points.First(),points.Last());
  32.        }
  33.    }
  34.    public class Gaps
  35.    {
  36.        double _gap = 6;
  37.        [CommandMethod("Heal")]
  38.        public void healGaps()
  39.        {
  40.            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  41.            Database db = doc.Database;
  42.            Editor ed = doc.Editor;
  43.            PromptSelectionOptions pso = new PromptSelectionOptions();
  44.            pso.MessageForAdding = "\nSelect lines to heal";
  45.            TypedValue[] tv = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LINE") };
  46.            PromptSelectionResult psr = ed.GetSelection(pso, new SelectionFilter(tv));
  47.            if (psr.Status != PromptStatus.OK) return;
  48.            using (Transaction tr = doc.TransactionManager.StartTransaction())
  49.            {
  50.                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  51.                List<Line> lines = psr.Value.GetObjectIds().Select(a => (Line)tr.GetObject(a, OpenMode.ForRead)).ToList();
  52.                IEnumerator<Line> Iline = lines.GetEnumerator();
  53.                Iline.MoveNext();
  54.                do
  55.                {
  56.                    Line line = Iline.Current;
  57.                    Point3d a = line.EndPoint, b = line.StartPoint;
  58.                    IEnumerable<Line> healers = lines.Where(c => c.Delta.Parallel(line.Delta, .1) && (
  59.                    (c.GetClosestPointTo(a, false).GetVectorTo(a).Parallel(c.Delta, 0.1))
  60.                    || (c.GetClosestPointTo(b, false).GetVectorTo(b).Parallel(c.Delta, 0.1))
  61.                    ));
  62.                    if (healers.Count() > 1)
  63.                    {
  64.                        Line healed = healers.Extrapolate();
  65.                        ed.WriteMessage("\n{0}..{1}", healed.StartPoint, healed.EndPoint);
  66.                        healed.SetPropertiesFrom(healers.First());
  67.                        foreach (var item in healers.ToArray())
  68.                        {
  69.                            lines.Remove(item);
  70.                            item.UpgradeOpen();
  71.                            item.Erase();
  72.                        }
  73.                        btr.AppendEntity(healed);
  74.                        tr.AddNewlyCreatedDBObject(healed, true);
  75.                        lines.Add(healed);
  76.                        Iline = lines.GetEnumerator();
  77.                    }
  78.                } while (Iline.MoveNext());
  79.                tr.Commit();
  80.            }
  81.        }
  82.        public void HealPolyLines()
  83.        {
  84.            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  85.            Database db = doc.Database;
  86.            Editor ed = doc.Editor;
  87.            PromptSelectionOptions pso = new PromptSelectionOptions();
  88.            pso.MessageForAdding = "\nSelect lines to heal";
  89.            TypedValue[] tv = new TypedValue[4]; //new TypedValue[4];
  90.            tv.SetValue(new TypedValue((int)DxfCode.Operator, "<or"), 0);
  91.            tv.SetValue(new TypedValue((int)DxfCode.Start, "LWPOLYLINE"), 1);
  92.            tv.SetValue(new TypedValue((int)DxfCode.Start, "LINE"), 2);
  93.            tv.SetValue(new TypedValue((int)DxfCode.Operator, "or>"), 3);
  94.            PromptSelectionResult psr = ed.GetSelection(pso, new SelectionFilter(tv));
  95.            if (psr.Status != PromptStatus.OK) return;
  96.            using (Transaction tr = doc.TransactionManager.StartTransaction())
  97.            {
  98.                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  99.                List<Curve> lines = psr.Value.GetObjectIds().Select(a => (Curve)tr.GetObject(a, OpenMode.ForRead)).ToList();
  100.            }
  101.            Polyline p = new Polyline();
  102.            SegmentType t = p.GetSegmentType(p.NumberOfVertices);
  103.            List<LineSegment3d> segments = new List<LineSegment3d>();
  104.            switch (t)
  105.            {
  106.                case SegmentType.Arc:
  107.                    break;
  108.                case SegmentType.Coincident:
  109.                    break;
  110.                case SegmentType.Empty:
  111.                    break;
  112.                case SegmentType.Line:
  113.                    segments.Add(p.GetLineSegmentAt(p.NumberOfVertices));
  114.                    break;
  115.                case SegmentType.Point:
  116.                    break;
  117.                default:
  118.                    break;
  119.            }
  120.        }
  121.        [CommandMethod("GF")]
  122.        public void gapFast()
  123.        {
  124.            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  125.            Database db = doc.Database;
  126.            Editor ed = doc.Editor;
  127.            PromptEntityOptions peo = new PromptEntityOptions("\nSelect the line to break around: ");
  128.            peo.SetRejectMessage("Only a line!");
  129.            peo.AddAllowedClass(typeof(Line), false);
  130.            peo.AddAllowedClass(typeof(Polyline), false);
  131.            peo.AddAllowedClass(typeof(Polyline2d), false);
  132.            peo.AddAllowedClass(typeof(Polyline3d), false);
  133.            //peo.AddAllowedClass(typeof(Line2d), false);
  134.            //peo.AddAllowedClass(typeof(Line3d), false);
  135.            PromptEntityResult per = ed.GetEntity(peo);
  136.            if (per.Status != PromptStatus.OK) return;
  137.            ObjectId keepId = per.ObjectId;
  138.            peo.Message = "\nSelect the line to break: ";
  139.            per = ed.GetEntity(peo);
  140.            if (per.Status != PromptStatus.OK) return;
  141.            ObjectId breakId = per.ObjectId;
  142.            try
  143.            {
  144.                using (Transaction tr = doc.TransactionManager.StartTransaction())
  145.                {
  146.                    _btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  147.                    _OriginalCurves = new Dictionary<ObjectId, Curve>();
  148.                    Curve breakCurve = (Curve)tr.GetObject(breakId, OpenMode.ForRead);
  149.                    Curve keepCurve = (Curve)tr.GetObject(keepId, OpenMode.ForRead);
  150.                    breakLines(new Curve[1] { breakCurve }, new Curve[1] { keepCurve }, ed, db, doc);
  151.                    tr.Commit();
  152.                }
  153.            }
  154.            catch (System.Exception e)
  155.            {
  156.                ed.WriteMessage("\nError: {0}\n{1}", e.GetBaseException(), e.Message);
  157.            }
  158.            finally
  159.            {
  160.                _btr = null;
  161.                _OriginalCurves = null;
  162.            }
  163.        }
  164.  
  165.        [CommandMethod("gap")]
  166.        public void TestBreaks()
  167.        {
  168.            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  169.            Database db = doc.Database;
  170.            Editor ed = doc.Editor;
  171.            PromptSelectionOptions pso = new PromptSelectionOptions();
  172.            pso.MessageForAdding = "\nSelect lines to break around";
  173.            TypedValue[] tv = new TypedValue[4];
  174.            tv.SetValue(new TypedValue((int)DxfCode.Operator, "<or"), 0);
  175.            tv.SetValue(new TypedValue((int)DxfCode.Start, "LWPOLYLINE"), 1);
  176.            tv.SetValue(new TypedValue((int)DxfCode.Start, "LINE"), 2);
  177.            tv.SetValue(new TypedValue((int)DxfCode.Operator, "or>"), 3);
  178.            TypedValue[] fil = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") };
  179.            SelectionFilter sf = new SelectionFilter(tv);
  180.            PromptSelectionResult psr = ed.GetSelection(pso, sf);
  181.            if (psr.Status != PromptStatus.OK) return;
  182.            SelectionSet keepers = psr.Value;
  183.            pso.MessageForAdding = "\nSelect lines to break";
  184.            psr = ed.GetSelection(pso, sf);
  185.            if (psr.Status != PromptStatus.OK) return;
  186.            SelectionSet breakers = psr.Value;
  187.            PromptDoubleOptions pdo = new PromptDoubleOptions("\nEnter spacing");
  188.            pdo.DefaultValue = _gap;
  189.            pdo.AllowNone = true;
  190.            pdo.AllowNegative = false;
  191.            pdo.AllowZero = false;
  192.            PromptDoubleResult pdr = ed.GetDouble(pdo);
  193.            if (pdr.Status != (PromptStatus.OK | PromptStatus.None))
  194.            {
  195.                ed.WriteMessage("\nInvalid input");
  196.                return;
  197.            }
  198.            _gap = pdr.Value;
  199.            ObjectIdCollection keepIds = new ObjectIdCollection(keepers.GetObjectIds());
  200.            ObjectIdCollection breakIds = new ObjectIdCollection(breakers.GetObjectIds());
  201.            try
  202.            {
  203.                using (Transaction tr = doc.TransactionManager.StartTransaction())
  204.                {
  205.                    _btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  206.                    _OriginalCurves = new Dictionary<ObjectId, Curve>();
  207.                    List<Curve> keepCurves = new List<Curve>();
  208.                    foreach (ObjectId id in keepIds)
  209.                    {
  210.                        keepCurves.Add((Curve)tr.GetObject(id, OpenMode.ForRead));
  211.                    }
  212.                    List<Curve> breakCurves = new List<Curve>();
  213.                    foreach (ObjectId id in breakIds)
  214.                    {
  215.                        breakCurves.Add((Curve)tr.GetObject(id, OpenMode.ForRead));
  216.                    }
  217.                    breakLines(breakCurves.ToArray(), keepCurves.ToArray(), ed, db, doc);
  218.                    tr.Commit();
  219.                }
  220.            }
  221.            catch (System.Exception e)
  222.            {
  223.                ed.WriteMessage("\nError: {0}\n{1}", e.GetBaseException(), e.Message);
  224.            }
  225.            finally
  226.            {
  227.                _btr = null;
  228.                _OriginalCurves = null;
  229.            }
  230.        }
  231.        private BlockTableRecord _btr;
  232.        private Dictionary<ObjectId, Curve> _OriginalCurves;
  233.        public void breakLines(Curve[] breakCurves, Curve[] keepCurves, Editor ed, Database db, Document doc)
  234.        {
  235.            Transaction tr = doc.TransactionManager.TopTransaction;
  236.            try
  237.            {
  238.                Dictionary<Curve, Point3dCollection> intersections = new Dictionary<Curve, Point3dCollection>();
  239.                for (int i = breakCurves.Length - 1; i >= 0; i--)
  240.                {
  241.                    Point3dCollection intersectionPoints = new Point3dCollection();
  242.                    for (int j = keepCurves.Length - 1; j >= 0; j--)
  243.                    {
  244.                        Point3dCollection tempIntersectionPoints = new Point3dCollection();
  245.                        breakCurves[i].IntersectWith(keepCurves[j], Intersect.OnBothOperands, tempIntersectionPoints, (IntPtr)0, (IntPtr)0);
  246.                        foreach (Point3d point in tempIntersectionPoints)
  247.                        {
  248.                            try
  249.                            {
  250.                                double dist = breakCurves[i].GetDistAtPoint(point);
  251.                                double length = breakCurves[i].GetDistAtPoint(breakCurves[i].EndPoint);
  252.                                if (dist > _gap / 2 & length - dist > _gap / 2)
  253.                                {
  254.                                    intersectionPoints.Add(point);
  255.                                }
  256.                            }
  257.                            catch { }
  258.                        }
  259.                    }
  260.                    List<Point3d> sortPoints = new List<Point3d>();
  261.                    foreach (Point3d point in intersectionPoints)
  262.                        sortPoints.Add(point);
  263.                    intersectionPoints.Clear();
  264.                    foreach (Point3d point in sortPoints.OrderBy(pt => breakCurves[i].GetParameterAtPoint(pt)))
  265.                        intersectionPoints.Add(point);
  266.                    intersections.Add(breakCurves[i], intersectionPoints);
  267.                }
  268.                foreach (Curve breakCurve in breakCurves)
  269.                {
  270.                    if (intersections[breakCurve].Count == 0) continue;
  271.                    DBObjectCollection brokenCurves = breakCurve.GetSplitCurves(intersections[breakCurve]);
  272.                    if (brokenCurves.Count == 0) continue;
  273.                    List<DBObject> curves = new List<DBObject>();
  274.                    foreach (DBObject o in brokenCurves)
  275.                        curves.Add(o);
  276.                    curves.OrderBy(o => breakCurve.GetParameterAtPoint((o as Curve).StartPoint));
  277.                    DBObjectCollection newcurves = new DBObjectCollection();
  278.                    for (int i = 0; i < curves.Count; i++)
  279.                    {
  280.                        Curve curve = curves[i] as Curve;
  281.                        if (curve.GetDistAtPoint(curve.EndPoint) > _gap)
  282.                        {
  283.                            curve.SetPropertiesFrom(breakCurve);
  284.                            _btr.AppendEntity(curve);
  285.                            tr.AddNewlyCreatedDBObject(curve, true);
  286.                            newcurves.Add(curve);
  287.                        }
  288.                    }
  289.                    Curve brokenCurve = null;
  290.                    Polyline poly = null;
  291.                    for (int n = 0; n < newcurves.Count; n++)
  292.                    {
  293.                        brokenCurve = (Curve)newcurves[n];
  294.                        double startParam = brokenCurve.StartParam;
  295.                        double endParam = brokenCurve.EndParam;
  296.                        Point3d newStartPoint = brokenCurve.GetPointAtDist(_gap / 2);
  297.                        Point3d newEndPoint = brokenCurve.GetPointAtDist(brokenCurve.GetDistanceAtParameter(brokenCurve.EndParam) - brokenCurve.GetDistanceAtParameter(brokenCurve.StartParam) - _gap / 2);
  298.                        Point3d startPoint = new Point3d();
  299.                        Point3d endPoint = new Point3d();
  300.                        try
  301.                        {
  302.                            bool isPoly = (brokenCurve.GetRXClass().DxfName == "LWPOLYLINE");
  303.                            if (isPoly)
  304.                                poly = (Polyline)brokenCurve;
  305.                            if (n == 0) //first curve in list
  306.                            {
  307.                                endPoint = brokenCurve.GetClosestPointTo(newEndPoint, false);
  308.                                if (isPoly)
  309.                                    poly.SetPointAt(poly.NumberOfVertices - 1, new Point2d(endPoint.X, endPoint.Y));
  310.                                else
  311.                                    brokenCurve.EndPoint = endPoint;
  312.                            }
  313.                            else if (n == newcurves.Count - 1)//last curve in list
  314.                            {
  315.                                startPoint = brokenCurve.GetClosestPointTo(newStartPoint, false);
  316.                                if (isPoly)
  317.                                    poly.SetPointAt(0, new Point2d(startPoint.X, startPoint.Y));
  318.                                else
  319.                                    brokenCurve.StartPoint = startPoint;
  320.                            }
  321.                            else
  322.                            {
  323.                                startPoint = brokenCurve.GetClosestPointTo(newStartPoint, false);
  324.                                endPoint = brokenCurve.GetClosestPointTo(newEndPoint, false);
  325.                                if (isPoly)
  326.                                {
  327.                                    poly.SetPointAt(0, new Point2d(startPoint.X, startPoint.Y));
  328.                                    poly.SetPointAt(poly.NumberOfVertices - 1, new Point2d(endPoint.X, endPoint.Y));
  329.                                }
  330.                                else
  331.                                {
  332.                                    brokenCurve.StartPoint = startPoint;
  333.                                    brokenCurve.EndPoint = endPoint;
  334.                                }
  335.                            }
  336.                        }
  337.                        catch (System.Exception e)
  338.                        {
  339.                            ed.WriteMessage("\nError processing {2}: {0}\n{1}", e.Message, e.StackTrace, brokenCurve.GetType());
  340.                        }
  341.                    }
  342.                    breakCurve.UpgradeOpen();
  343.                    breakCurve.Erase();
  344.                }
  345.            }
  346.            catch (System.Exception e)
  347.            {
  348.                Autodesk.AutoCAD.Runtime.Exception ex = e as Autodesk.AutoCAD.Runtime.Exception;
  349.                if (ex != null)
  350.                {
  351.                    if (ex.ErrorStatus == Autodesk.AutoCAD.Runtime.ErrorStatus.InvalidInput)
  352.                    {
  353.                    }
  354.                }
  355.                ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
  356.                throw;
  357.            }
  358.        }
  359.    }
  360. }
  361.  

kdub

  • SuperMod
  • Swamp Rat
  • Posts: 993
  • class keyThumper<T>:ILazy<T>
Re: Cut polyline
« Reply #2 on: September 22, 2017, 07:03:53 pm »
I can't make time to play, but ;

Next month are you likely to be confused by the variables plL, p1L, p1N  ... and will you remember what they identify ?


Does Normans post help :
http://drive-cad-with-code.blogspot.com.au/2016/12/splitting-polylinecurve-with-autocad.html
called Kerry in my other life

Sometimes the question is more important than the answer.

WILL HATCH

  • Bull Frog
  • Posts: 405
Re: Cut polyline
« Reply #3 on: September 22, 2017, 07:05:44 pm »
I can't make time to play, but ;

Next month are you likely to be confused by the variables plL, p1L, p1N  ... and will you remember what they identify ?


Does Normans post help :
http://drive-cad-with-code.blogspot.com.au/2016/12/splitting-polylinecurve-with-autocad.html
There's a serious truth right there!  :2funny:

latour_g

  • Newt
  • Posts: 120
Re: Cut polyline
« Reply #4 on: September 25, 2017, 01:59:18 pm »
Yes kdub you are right, I have change the variables names to make it more clear.

Thanks Will and kdub for the exemples, I will check them both !