OffsetInXref: September’s ADN Plugin of the Month, now live on Autodesk Labs

As announced on Scott Sheppard's blog, It's Alive in the Lab, you can now find the inaugural ADN Plugin of the Month available for download on Autodesk Labs. I introduced the concept a little over a month ago โ€“ thanks to all of you who responded! โ€“ and we've decided to get things started with OffsetInXref, an AutoCAD plugin allowing you to offset geometry contained in external references without first having to explode them. The code for this plugin can be found in these previous posts on this blog, as well as with the plugin download itself. The inspiration for the plugin came from Mark Doel, from RMJM Hong Kong Ltd., who also helped test the application and has now deployed it successfully to his various users.

I've already received a question about the contents of the package, which I'll reproduce here, in case it helps anyone:

Thanks for the "Offset in Xref" plugin. Simple question for a start: why are there two identical readme.txt files in the ZIP and apparently two identical .dll files? Thanks.

Here was my responseโ€ฆ

The ReadMe is duplicated because I wanted it to be outside the source folder, but also in the project (so it appears in the solution explorer window inside Visual Studio). When you add a file to a project that's outside the project folder, Visual Studio copies it into the project folder. So it was a choice: only have it in the project folder (bad), don't have it in the project (a little less bad), or have the file duplicated (the choice I went for).

You'll hopefully find the DLLs only to be "apparently" identical: one is for use in 32-bit and the other is for use in 64-bit AutoCAD versions. The source used to build the DLLs is indeed identical, but you need to include different reference assemblies (i.e. different versions of both AcMgd.dll & AcDbMgd.dll) depending on whether you build for a 32- or 64-bit platform. So one (the one found in the win32 folder) should only work on 32-bit AutoCAD, and the other (the one in the x64 folder) should only work on 64-bit AutoCAD.

One additional, related point to mention: the 32-bit version will load in 64-bit AutoCAD โ€“ but cause it to crash once its code is executed โ€“ just as the 64-bit version will do in 32-bit AutoCAD. I'm not sure why this happens, but care should be taken to pick up the correct DLL for the target system.

We've had some really interesting "plugin of the month" submissions come in from this blog's readership โ€“ October's plugin, a very cool Clipboard Manager for AutoCAD, is a great example โ€“ and I'm really excited about how these plugins will (hopefully) show people that customizing software โ€“ tailoring it to their specific needs โ€“ can pay real dividends in terms of productivity. As we also make progress defining a learning path for novice programmers (something else that's on my plate, at the moment), I'm optimistic that more people will feel motivated to take the plunge. ๐Ÿ™‚

13 responses to “OffsetInXref: September’s ADN Plugin of the Month, now live on Autodesk Labs”

  1. We are happy to have the Autodesk Labs feedback process reach out to programmers. We look forward to their comments.

  2. I've written this in lisp using activex style code and entmake and other options. I even paid for a 3rd party version of the tool written by an author I trust.
    The issue I have seen is the nentsel function will crash on certain drawings, locking the session. I spent days figuring this out back in version 2002 because we needed the tool to work. I just tell people the command is not totally stable so save your work before using.
    Hopefully the .net api version is more stable of course.
    Thx for the code.

  3. Hi James,

    If you (or others) come across problematic files, please do let me know (either via this post or by email).

    Hopefully the additional exception handling makes this version more tolerant, but then data corruption can take apps down badly, as I'm sure you know.

    Regards,

    Kean

  4. Works as advertise. Thanks.

    My only suggestions/request/begs would be to modify it to work with blocks as well. And somehow wrap the xline offset command into it as well.

    Thanks again.

  5. Thanks, Ted.

    Actually it should be a one-line change to support standard blocks: if you comment out line 455 of offset-xref.cs, it should work.

    //if (btr.IsFromExternalReference)

    I did some cursory testing and it appears to work well (my main concern was if you use the XOFFSETLAYER command to choose the "Source" setting, but that doesn't appear to be a problem).

    To work with XLINE offset, lines 398 and 412 should be changed with the same modification, adding support for the XLINE command:

    if (e.GlobalCommandName == "OFFSET" || e.GlobalCommandName == "XLINE")

    It doesn't respect the "Source" option in the XOFFSETLAYER command, but then this doesn't appear to be an option for XLINE offset, in any case.

    Hopefully you're able to make these changes yourself (if you have a development environment such as Visual C# Express or full Visual Studio). If not, let me know your email address, and I'll email you a built version. I'll also add these items to the list of enhancements for the next version (as and when that happens).

    Regards,

    Kean

  6. Hi Kean,
    This code demonstrates some pretty interesting possibilities. One thing I've always hoped AutoCAD could do was make the XOPEN command work so when a user selects an object in the Xref, the XOPEN command or some other command would open the selected Xref, but also once the drawing opens, zoom the user right to the selected object he chose when running the Xopen command. I'm going to take a stab at trying to modify this code to do something like this. If you have any pointers or sample code would be great to get me going. Anyway thanks for posting the source code.

    Mark

  7. Hi Mark,

    Interesting idea...

    The "easy" way would be to leverage the XOPEN command as much as possible, and that expects a point. You would want to make sure at least one selection operation involved selecting the Xref itself (a single entity) and then probably a set of geometry within that Xref.

    Then you would call the XOPEN command with the point, but the tricky thing is - as with any command creating new documents - getting the XOPENed document to execute the ZOOM operation to the geometry selected in your command. Hmm.

    I don't have a quick answer on how to do that, but hopefully this will at least give you somewhere to start...

    Kean

  8. "The source used to build the DLLs is indeed identical, but you need to include different reference assemblies (i.e. different versions of both AcMgd.dll & AcDbMgd.dll) depending on whether you build for a 32- or 64-bit platform. So one (the one found in the win32 folder) should only work on 32-bit AutoCAD, and the other (the one in the x64 folder) should only work on 64-bit AutoCAD."

    Sorry, this is not the case.

    The assemblies that are loaded at runtime, are the ones in the AutoCAD root folder, on either 32 or 64 bit AutoCAD. We don't distribute those assemblies with apps, because they're part of AutoCAD.

    There are 32- and 64-bit versions of those DLLs in the SDK, because they are mixed-mode (e.g., native and managed code) assemblies, and the correct ones must be used in the development environment, but the fact of the matter is that you can build an app that references either the 32- or 64-bit reference assemblies, and deploy it on either 32 or 64 bit AutoCAD.

    Given that, pure managed code does not have the restriction you suggest above.

  9. Actually, no.

    The versions of the reference assemblies in the ObjectARX SDK have been "liposuctioned" (an internal term we use), to remove any implementation dependencies: mainly to allow them to be loaded by the form designer in Visual Studio. In theory, the versions of these assemblies in the inc-win32 and inc-x64 folders *should be identical in every way* - we've kept them in separate folders for consistency.

    Unfortunately - and this has really only been noticed because of this specific application - there are occasions (which Engineering is investigating) where you need to build your application with the right version of the DLL. This should not be the case, but it happens to be true. We should find out why (and hopefully address it) before too long.

    Feel free to give it a try with the provided project, Tony: this behaviour has been reproduced a number of times by various members of my team (as well as by our API QA team).

    Kean

  10. Kean - I was addressing your comments in the context of a general stipulation that *all* AutoCAD managed extensions require platform-specific builds that reference the 32 or 64 bit versions of the reference assemblies. While that may not have been the intended message, recent conversations I noticed on various public fora seem to have misinterpreted it thusly.

    That is not the case.

    The issue you stumbled on is in fact a bug (confirmed by the 'architect':), and there are several other similar bugs in the API, where needed overloads that take or return an IntPtr rather than an Int32 (on x86) or an Int64 (on x64) were not added, but should have been. Most of them involve ordinal values that represent GS Markers.

    For example, the SelectedObject's GraphicsSystemMarker property is Int32 on x86 and Int64 on x64. In general, cases like that require an overload (or in the case of a property, another new property) that expose the value as an IntPtr.

    You can download the diff reports between the 32 and 64 bit assemblies (AcMgd and AcDbMgd only) that I did when investigating this myself, from here:

    caddzone.com/AcDbMgd_diff.xml
    caddzone.com/AcMgd_diff.xml

    Both of these MS Word xml documents show the specific differences between the 32 and 64 bit assemblies, and while it is necessary to deal with those issues in order to be able to deploy a single build on either platform, the fact of the matter is that you can do that without having to create seperate platform-specific builds, just as you can P/Invoke native APIs with differring export signatures from the same assembly that targets both 32 and 64 bit platforms.

    I'll be happy to demonstrate how if you're interested.

  11. Hi Kean.

    At the link below is a revised copy of the offset-xref.cs from your project, that allows you to build a single managed assembly that can run on either 32 or 64 bit AutoCAD.

    caddzone.com/offset-xref.cs

    I encourage you and your readers to download and examine it, to better understand how this issue can be dealt with, to avoid the need for multiple, platform-specific builds, when that isn't really necessary.

  12. Hi Tony,

    Thank you both for tracking this down and for sharing your findings. I'll take a look next week and roll the changes into a future update of the tool.

    Regards,

    Kean

  13. Hi Tony,

    OK - I've tried hard to get this working on my win32 system:

    * I'm building with the right reference assemblies from the inc-win64 folder of the ObjectARX 2010, making sure they have "Copy Local" to false.
    * I copy the DLL to the AutoCAD 2010 install folder, to make sure that's location is not an issue, before NETLOADing it.

    The module loads, but when I attempt to OFFSET, AutoCAD 2010 crashes.

    Before I spend time trying to diagnose the problem (which won't happen until I get back from vacation, next week), can you confirm you managed to run the DLL created with this code (built with the x64 assemblies) on a Win32 system?

    Assuming it does work for you, how far back do you expect the module to function? Will it work as far back as AutoCAD 2007?

    (By the way - I'm loving the fact I can ask questions via my own blog's comments, rather just answering them. Very novel. ๐Ÿ™‚

    Kean

Leave a Reply to Ted Krush Cancel reply

Your email address will not be published. Required fields are marked *