How to find the curves that cannot be joined in a selection set?

How to find the curves that cannot be joined in a selection set?

arxbird
Enthusiast Enthusiast
730 Views
5 Replies
Message 1 of 6

How to find the curves that cannot be joined in a selection set?

arxbird
Enthusiast
Enthusiast

How to find the curves that cannot be joined in a selection set?

0 Likes
Accepted solutions (1)
731 Views
5 Replies
Replies (5)
Message 2 of 6

_gile
Consultant
Consultant

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.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 6

arxbird
Enthusiast
Enthusiast

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);
    }
}

 

 

0 Likes
Message 4 of 6

_gile
Consultant
Consultant

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();
    }
}

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 6

arxbird
Enthusiast
Enthusiast

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?

 

0 Likes
Message 6 of 6

_gile
Consultant
Consultant
Accepted solution

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;
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes