简体   繁体   中英

Is there a way to get all Polylines in autocad (.dwg) using C#?

I don't want to select the specific polyline in runtime. Is there a way to directly get all polylines in .dwg file using C# without selection during runtime ? AutoCAD has a command called DATAEXTRACTION to get related information for different objects (eg polyline, circle, point ...etc), but I don't know if it can be called and used in C#.

FYI: Sample code to get specific polyline during runtime from
http://through-the-interface.typepad.com/through_the_interface/2007/04/iterating_throu.html :

Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
   DBObject obj = tr.GetObject(per.ObjectId, OpenMode.ForRead);
   Polyline lwp = obj as Polyline; // Get the selected polyline during runtime
   ...
}

Sounds like you're looking for something like this. Remove the layer criteria if not needed.

public ObjectIdCollection SelectAllPolylineByLayer(string sLayer)
{
    Document oDwg = Application.DocumentManager.MdiActiveDocument; 
    Editor oEd = oDwg.Editor;

    ObjectIdCollection retVal = null;

    try {
        // Get a selection set of all possible polyline entities on the requested layer
        PromptSelectionResult oPSR = null;

        TypedValue[] tvs = new TypedValue[] {
            new TypedValue(Convert.ToInt32(DxfCode.Operator), "<and"),
            new TypedValue(Convert.ToInt32(DxfCode.LayerName), sLayer),
            new TypedValue(Convert.ToInt32(DxfCode.Operator), "<or"),
            new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE"),
            new TypedValue(Convert.ToInt32(DxfCode.Start), "LWPOLYLINE"),
            new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE2D"),
            new TypedValue(Convert.ToInt32(DxfCode.Start), "POLYLINE3d"),
            new TypedValue(Convert.ToInt32(DxfCode.Operator), "or>"),
            new TypedValue(Convert.ToInt32(DxfCode.Operator), "and>")
        };

        SelectionFilter oSf = new SelectionFilter(tvs);

        oPSR = oEd.SelectAll(oSf);

        if (oPSR.Status == PromptStatus.OK) {
            retVal = new ObjectIdCollection(oPSR.Value.GetObjectIds());
        } else {
            retVal = new ObjectIdCollection();
        }
    } catch (System.Exception ex) {
        ReportError(ex);
    }

    return retVal;
}

Updated 1/12/2015

This will work as well and keep you from having to deal with all the typedvalues...

I wrote a blog post about this subject, Check it out.

public IList<ObjectId> GetIdsByType()
{
    Func<Type,RXClass> getClass = RXObject.GetClass;

    // You can set this anywhere
    var acceptableTypes = new HashSet<RXClass>
    {
        getClass(typeof(Polyline)),
        getClass(typeof (Polyline2d)),
        getClass(typeof (Polyline3d))
    };

    var doc = Application.DocumentManager.MdiActiveDocument;
    using (var trans = doc.TransactionManager.StartOpenCloseTransaction())
    {
        var modelspace = (BlockTableRecord)
        trans.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(doc.Database), OpenMode.ForRead);

        var polylineIds = (from id in modelspace.Cast<ObjectId>()
            where acceptableTypes.Contains(id.ObjectClass)
            select id).ToList();

        trans.Commit();
        return polylineIds;
    }
}

I know it is old question, but maybe someone will find it useful.

Using SelectionFilter to select only opened or closed polylines (any type of polyline):

Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;

int polylineState = 1; // 0 - closed, 1 - open
TypedValue[] vals= new TypedValue[]
{
    new TypedValue((int)DxfCode.Operator, "<or"),

    // This catches Polyline object.
    new TypedValue((int)DxfCode.Operator, "<and"),
    new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
    new TypedValue(70, polylineState),
    new TypedValue((int)DxfCode.Operator, "and>"),

    new TypedValue((int)DxfCode.Operator, "<and"),
    new TypedValue((int)DxfCode.Start, "POLYLINE"),
    new TypedValue((int)DxfCode.Operator, "<or"),
    // This catches Polyline2d object.
    new TypedValue(70, polylineState),
    // This catches Polyline3d object.
    new TypedValue(70, 8|polylineState),
    new TypedValue((int)DxfCode.Operator, "or>"),
    new TypedValue((int)DxfCode.Operator, "and>"),

    new TypedValue((int)DxfCode.Operator, "or>"),
};
SelectionFilter filter = new SelectionFilter(vals);
PromptSelectionResult prompt = ed.GetSelection(filter);

// If the prompt status is OK, objects were selected
if (prompt.Status == PromptStatus.OK)
{
    SelectionSet sset = prompt.Value;
    Application.ShowAlertDialog($"Number of objects selected: {sset.Count.ToString()}");
}
else
{
    Application.ShowAlertDialog("Number of objects selected: 0");
}

List of all drawing entities: link 1 (older) or link 2 (newer)

In this link we see that code 70 with value of 1 is closed polyline.

And in this link we see that same applies for polyline 2d/3d, but additionaly with value 8 we define if it is 2d or 3d polyline. Values can be bitwise combined, so 8|1 means closed 3d polyline.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM