Author Topic: Cut polyline  (Read 2496 times)

0 Members and 1 Guest are viewing this topic.

latour_g

  • Newt
  • Posts: 184
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: 450
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_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2120
  • 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
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

WILL HATCH

  • Bull Frog
  • Posts: 450
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: 184
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 !