Message 1 of 6
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
How to find the curves that cannot be joined in a selection set?
Solved! Go to Solution.
How to find the curves that cannot be joined in a selection set?
Solved! Go to Solution.
Hi,
You can have a look at the GeometryExtension library at TheSwamp, the PolylineSegmentCollection class provides a Join() method.
This reply shows a using example of the PolylineSegmentCollection.Join method.
Your GeometryExtensions is so great.
But the following code is ok for all the curves except polyline.
If the selectionset has a polyline, an error will throw:
The best overloaded method match for 'GeometryExtensions.PolylineSegmentCollection.PolylineSegmentCollection(System.Collections.Generic.IEnumerable<GeometryExtensions.PolylineSegment>)' has some invalid arguments.
public void MPline()
{
var db = HostApplicationServices.WorkingDatabase;
Editor ed = app.DocumentManager.MdiActiveDocument.Editor;
TypedValue[] filter = {
new TypedValue(0,"ARC,LINE,LWPOLYLINE,POLYLINE") };
var psr = ed.GetSelection(new SelectionFilter(filter));
if (psr.Status != PromptStatus.OK) return;
dynamic ms = SymbolUtilityServices.GetBlockModelSpaceId(db);
dynamic ids = psr.Value.GetObjectIds();
PolylineSegmentCollection psc = new PolylineSegmentCollection();
Plane plane = new Plane(Point3d.Origin, Vector3d.ZAxis);
foreach (dynamic id in ids)
{
switch (id.GetType().Name)
{
case "Arc":
psc.Add(new PolylineSegment(
new CircularArc2d(
id.Center.Convert2d(plane),
id.Radius,
id.StartAngle,
id.EndAngle,
Vector2d.XAxis,
false)));
break;
case "Ellipse":
psc.AddRange(new PolylineSegmentCollection(id));
break;
case "Line":
psc.Add(new PolylineSegment(
new LineSegment2d(
id.StartPoint.Convert2d(plane),
id.EndPoint.Convert2d(plane))));
break;
case "Polyline":
psc.AddRange(new PolylineSegmentCollection(id));
break;
}
}
foreach (var segs in psc.Join())
{
var pline = segs.ToPolyline();
ms.AppendEntity(pline);
}
}
if you also want to process old style 2d polylines, you should use a better selection filter to avoid polyline3d, polygon meshes and polyfaces (which dxf name is also POLYLINE) and you have to add the Polyline2d type in the switch statement.
IMHO, you should not use the dynamic type which makes you lose all the help that Visual Studio provides with the strong types..
public void Mpline()
{
var db = HostApplicationServices.WorkingDatabase;
var ed = AcAp.DocumentManager.MdiActiveDocument.Editor;
TypedValue[] filter = {
new TypedValue(-4,"<OR"),
new TypedValue(0, "ARC,LINE,LWPOLYLINE"),
new TypedValue(-4, "<AND"),
new TypedValue(0, "POLYLINE"),
new TypedValue(-4, "<NOT"),
new TypedValue(-4, "&"),
new TypedValue(70, 8 | 16 | 32 | 64), // only Polyline2d
new TypedValue(-4, "NOT>"),
new TypedValue(-4, "AND>"),
new TypedValue(-4, "OR>")};
PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));
if (psr.Status != PromptStatus.OK) return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
PolylineSegmentCollection psc = new PolylineSegmentCollection();
Plane plane = new Plane(Point3d.Origin, Vector3d.ZAxis);
foreach (ObjectId id in psr.Value.GetObjectIds())
{
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
switch (ent)
{
case Arc arc:
psc.Add(new PolylineSegment(
new CircularArc2d(
arc.Center.Convert2d(plane),
arc.Radius,
arc.StartAngle,
arc.EndAngle,
Vector2d.XAxis,
false)));
break;
case Line line:
psc.Add(new PolylineSegment(
new LineSegment2d(
line.StartPoint.Convert2d(plane),
line.EndPoint.Convert2d(plane))));
break;
case Polyline pline:
psc.AddRange(new PolylineSegmentCollection(pline));
break;
case Polyline2d pline2d:
psc.AddRange(new PolylineSegmentCollection(pline2d));
break;
default:
break;
}
}
foreach (PolylineSegmentCollection segs in psc.Join())
{
Polyline pline = segs.ToPolyline();
btr.AppendEntity(pline);
tr.AddNewlyCreatedDBObject(pline, true);
}
tr.Commit();
}
}
Thanks a lot.The code runs correctly.
Another question:
psc.Join() can join the curves correctly.How to get the curves that cannot be joined?
You can try this:
public static List<Curve> GetCurvesThatCannotBeJoined(List<Curve> source, Tolerance tolerance)
{
bool IsJoinable(Curve curve1, Curve curve2) =>
!(curve1 is Xline || curve1 is Ray || curve1.Closed ||
curve2 is Xline || curve2 is Ray || curve2.Closed) &&
(curve1.StartPoint.IsEqualTo(curve2.StartPoint, tolerance) ||
curve1.StartPoint.IsEqualTo(curve2.EndPoint, tolerance) ||
curve1.EndPoint.IsEqualTo(curve2.StartPoint, tolerance) ||
curve1.EndPoint.IsEqualTo(curve2.EndPoint, tolerance));
var result = new List<Curve>();
for (int i = 0; i < source.Count - 1; i++)
{
bool joinable = false;
for (int j = i + 1; j < source.Count; j++)
{
if (IsJoinable(source[i], source[j]))
{
joinable = true;
break;
}
}
if (!joinable)
{
result.Add(source[i]);
}
}
return result;
}