AutoCAD .net Customization: Is there an entget equivalent for .net?

69 views Asked by At

I can find very little information about manipulating or reading AutoCAD shape entities using a .net language. What I really want to do is simply retrieve the name of a shape (as it is defined in the SHX (SHP) file) from its "ShapeNumber". I started down this rabbit hole as I was writing a simple little .net extension for gathering all of the linetypes in a file and sending their definitions to a *.lin file. I have just about everything working except for retrieving the names of shapes used in complex linetypes.

Basically, my little program iterates through the records in the linetype symbol table and pulls all of the properties from each table record and formats them into the standard *.lin file text. I can get a shape's number directly from the linetype's table record, but I have not found a method for getting its name. (The shx compiler must convert the shape name to its number.)

I tried instantiating an empty shape object, assigning the shapenumber to the object, and then retrieving its name property, but that did not work (as I fully expected since it was not instantiated using a constructor that could resolve the shapenumber into a name).

I suspect that the answer could lie in the dxf entity codes for the shape (e.g. Code 2), but I don't know how to access the dxf codes from .net. Is there an autocad .net function equivalent to the ENTGET function in autolisp? If I could get that far and find the dxf block that holds that particular shape definition from its shapenumber, I should be able to get the shape name from the entget list.

2

There are 2 answers

2
CAD Developer On

I was struggling with that some time ago. The only way I found was to import it from external DLL. Probably I found it somewhere but now I don't remember where. I would link and honour all the copyrights but don't know where and who. So to answer by code try this:

[DllImport("acdb19.dll", CallingConvention = CallingConvention.Cdecl,  EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")]
extern static public ErrorStatus acdbGetAdsName(out Int64 entres, ObjectId id);


[DllImport("acCore.dll", CallingConvention = CallingConvention.Cdecl)]
extern static IntPtr acdbEntGet(out Int64 e);

.....

ObjectId id = initializeObjectIdByYourObjectLinetypeMaybe();
Int64 e = new Int64();
IntPtr p = new IntPtr();
if (acdbGetAdsName(out e, id) == ErrorStatus.OK)
{
    p = acdbEntGet(out e);
    ResultBuffer rb = ResultBuffer.Create(p, true);
    return rb;
}

Maybe in differend version and CAD platforms other entrypoints will be needed.

1
gileCAD On

From this topic.

public static class Extension
{
    // Replace the DLL name according to the AutoCAD targeted version
    // 2013-2014:   "acdb19.dll"
    // 2015-2016:   "acdb20.dll"
    // 2017:        "acdb21.dll"
    // 2018:        "acdb22.dll"
    // 2019-2020:   "acdb23.dll"
    // 2021-2024:   "acdb24.dll"
    // Replace the EntryPoint according to AutoCAD plateform
    // 32 bits:     "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z"
    // 64 bits:     "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z"
    [System.Security.SuppressUnmanagedCodeSecurity]
    [DllImport("acdb24.dll", CallingConvention = CallingConvention.Cdecl,
        EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")]
    static extern AcRx.ErrorStatus acdbGetAdsName(out AdsName ename, ObjectId id);

    [System.Security.SuppressUnmanagedCodeSecurity]
    [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl,
        EntryPoint = "acdbEntGet")]
    static extern IntPtr acdbEntGet(AdsName ename);

    public static ResultBuffer EntGet(this ObjectId id)
    {
        var errorStatus = acdbGetAdsName(out AdsName ename, id);
        if (errorStatus != AcRx.ErrorStatus.OK)
            throw new AcRx.Exception(errorStatus);
        var result = acdbEntGet(ename);
        if (result != IntPtr.Zero)
            return ResultBuffer.Create(result, true);
        return null;
    }
}