March 23, 2015

Off the bat it’s worth stating that AutoCAD 2016 is a DWG compatible release: it’s using the same file format as AutoCAD 2013, 2014 and 2015. It’s also a binary application compatible release: ObjectARX apps written for AutoCAD 2015 should work in 2016 and it’s likely that .NET apps built for AutoCAD 2014 will work, too. That said, some changes have been made to the security model for this release of AutoCAD, so you may want to make sure these changes haven’t impacted your application…

Security

You’ll see straight away when you try to load your application that there’s a bit more going on in the 2016 version of this dialog.

Firstly, the word “unsigned” indicates something very important: we’re encouraging developers to sign their executables – and even their LISP files – to improve security. An increasing number of AutoCAD customers – often the larger ones, as you might expect – are requiring application modules to be signed. This is certainly a topic that’s worth go into more deeply in a future post.

The other addition to the dialog is the “Always load this application” checkbox. This tells AutoCAD to continue loading this module from a non-trusted location, with the caveat that if the module changes the user will be prompted again.

LEGACYCODESEARCH is important to note: AutoCAD’s default “find file” behaviour has been changed neither to search the current working folder nor the folder of the active drawing. This will make it much harder for people to write viruses that travel around with AutoCAD drawings.

On the subject of sysvars, I do think the System Variable Monitor – which we mentioned last time – will be a useful diagnostic tool for developers. If you know you’re using sysvars in your code – such as CMDECHO, CMDDIA, FILEDIA, etc. – try adding them to the monitor and see whether you get any notifications about your commands not setting them back properly. If you get any you can bet your users will, too.

Now let’s take a look at the new .NET API features (equivalent – and in a few cases more – functionality is also available via ObjectARX).

Reality computing

A number of point cloud-related features have been added to the product and are also available via the API.

You can create point cloud extension definitions (PointCloudDefEx objects) by attaching .RCS/.RCP files. These are analogous to block definitions. You can also create point cloud extension entities (PointCloudEx objects) that “insert” these into the drawing. A whole slew of properties and methods are exposed from both these classes.

A number of capabilities have been added relating to extraction of features from point clouds. Firstly, the Section class now has a “slice” type, and can be used to slice through a point cloud. Correspondingly it’s possible to use a PointCloudCrop object to crop a point cloud relative to a plane.

The extraction itself can also be driven programmatically. I’ve put together a sample that performs an extraction and adds the extracted geometry to the drawing: we’ll take a look at that in an upcoming post.

Rendering

A number of capabilities related to the newly introduced RapidRT rendering system have been added to the API in this release. You can add and control image-based lighting, for instance, as well as managing the various settings related to RapidRT.

As this is a binary application compatible release, when we change an API significantly we make sure we do so via a new class until we can safely break API compatibility in a future release. So there’s a new Autodesk.AutoCAD.GraphicsSystem.Manager2 class which contains GetOffScreenDevice() and GetOffScreenView() methods making use of the RapidRT engine.

Miscellaneous

Here’s a quick round-up of some of the more interesting miscellaneous API enhancements in this release…

The Spline.ToPolyline() method has a couple of new Boolean parameters allowing you to specify that you wish to create arc segments as well as requesting the generation of lightweight polylines.

The Dimension.TextDefinedSize property allows you to control the width associated with long dimension text.

The MText class has a couple of new properties: ContentsRTF allows you to extract a version of the contents in Rich Text Format, while ShowBorders allows you to query or control whether an MText object’s borders are visible.

We mentioned the ability for CAD managers to lock certain system variables. There’s a corresponding Variable.IsLocked property allowing you to test this programmatically.

And finally my personal favourite miscellaneous enhancement in this release… you can now request code to be executed within a command context from the application context using DocumentCollection.ExecuteInCommandContextAsync(). Now this may not sound like much, but this one method allows you to do some really interesting things, such as calling commands from AutoCAD event handlers or even OS-level events. This is definitely a method of which we’re going to make a great deal of use, both in a few near-term posts and in the longer term.

Update:

It turns out that while the documentation for ACADLSPASDOC and TRUSTEDDOMAINS state they “may be locked by CAD managers”, the CAD Manager Control Utility currently does not, in fact, allow you to lock these two sysvars. Thanks to Dieter and Karen for tracking this one down: we’ll make sure the docs get fixed during the next update.

December 15, 2014

This is really cool. Fellow architect on the AutoCAD team, Jiri Kripac – who originally wrote AutoCAD’s “AModeler” facet modeler and is the driving force behind AutoCAD’s Associative Framework – has written a really interesting ObjectARX sample to perform an associative fillet between two curves. Given Jiri’s background, this is as close to a canonical sample for implementing an operation using the Associative Framework – in this case by creating a custom AcDbAssocActionBody – as you’re likely to find.

Here’s a video showing this custom fillet in action, and how it can be used with parameters and expressions to do some really impressive things (for instance, Jiri demonstrates basing an extruded surface on curves linked via an associative fillet… really nice).

When building the app, be sure to follow Jiri’s instructions in the ReadMe: you’ll need to place the code in the samples\entity folder of the ObjectARX SDK for AutoCAD 2015 and then build it using Visual Studio 2012 (or at least the v110 “platform toolset” build tools, allowing you to use the VS 2013 IDE with the 2012 compiler). You will need to load the .vcxproj – no .sln is provided – and do remember to set the build configuration appropriately (the default is Win32 rather than x64, and this often isn’t directly obvious through the Visual Studio UI).

November 12, 2014

The C++ developers among you may remember the autoexp.dat file, which tells older versions of Visual Studio how to visualize custom C++ types during a debug session. Here’s an ancient post showing how we extended it for some basic ObjectARX types and another showing how to do so via a custom plug-in.

In Visual Studio 2012, a newer XML-based mechanism was introduced to do something similar. In today’s post we’ll look at a custom .natvis file that exposes some basic ObjectARX types to the Visual Studio debugger.

This file was created by Davis Augustine in response to a query from Augusto Gonçalves. Augusto has also posted the file to GitHub – something we talked about in the last post – which will allow you all to contribute changes to the file, should you so wish.

For Visual Studio (2012 or later) to find the .natvis file, it has to be in one of these locations:

%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers

%USERPROFILE%\My Documents\Visual Studio 2012\Visualizers

[The first requires admin rights and the second should have the 2012 changed to the appropriate number for newer versions of VS, of course.]

Here’s a recent version of the acad.natvis file, reformatted for this blog. This version supports AcString, AcArray, AcRxClass, AcString, CAdUiPathName, CAdUiVolumeDescriptor and resbuf, with future candidates being AcRxValue, AcDbObject, AcDbObjectId, AcGe*, etc. You’ll continue to find the latest & greatest on GitHub, of course.

<?xmlversion="1.0"encoding="utf-8"?>

<AutoVisualizer

xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

<!-- Version 1.0e 11nov14 -->

<!-- for acad/arx types -->

<TypeName="AcArray&lt;*&gt;">

<DisplayString>

{{Len = {mLogicalLen}}}

</DisplayString>

<Expand>

<ItemName="Len">mLogicalLen</Item>

<ItemName="Buf Siz">mPhysicalLen</Item>

<ArrayItems>

<Size>mLogicalLen</Size>

<ValuePointer>mpArray</ValuePointer>

</ArrayItems>

</Expand>

</Type>

<TypeName="AcRxClass">

<DisplayStringCondition="m_pImp!=0">

{*(((wchar_t **)m_pImp)+1),su}

</DisplayString>

</Type>

<TypeName="AcString">

<DisplayStringCondition="mnFlags==0">""</DisplayString>

<DisplayStringCondition="mnFlags==1">{mszStr,s}</DisplayString>

<DisplayStringCondition="mnFlags==2">

{mchr.mwszStr,su}

</DisplayString>

<DisplayStringCondition="mnFlags==3">

{mptr.mpszData,s}

</DisplayString>

<DisplayStringCondition="mnFlags==4">

{mptr.mpwszData,su}

</DisplayString>

<DisplayStringCondition="mnFlags==5">

{*(wchar_t **)(mptr.mpPtrAndData),su}

</DisplayString>

<StringViewCondition="mnFlags==0">""</StringView>

<StringViewCondition="mnFlags==1">mszStr,s</StringView>

<StringViewCondition="mnFlags==2">mchr.mwszStr,su</StringView>

<StringViewCondition="mnFlags==3">mptr.mpszData,s</StringView>

<StringViewCondition="mnFlags==4">mptr.mpwszData,su</StringView>

<StringView>mptr.mpPtrAndData</StringView>

</Type>

<TypeName="CAdUiPathname">

<DisplayStringCondition="m_pathbuffer!=0">

{*m_pathbuffer,su}

</DisplayString>

<DisplayStringCondition="m_this_type==0">

NO_PATH

</DisplayString>

<StringViewCondition="m_pathbuffer!=0">

*m_pathbuffer

</StringView>

</Type>

<TypeName="CAdUiVolumeDescriptor">

<DisplayStringCondition="m_vol_localname!=0">

{*m_vol_localname}

</DisplayString>

<StringViewCondition="m_vol_localname!=0">

*m_vol_localname

</StringView>

</Type>

<TypeName="resbuf">

<!--ARX/Lisp Function arg-->

<DisplayStringCondition="restype==5000">

rtnone

</DisplayString>

<DisplayStringCondition="restype==5001">

{resval.rreal} rreal</DisplayString>

<DisplayStringCondition="restype==5002">

{resval.rpoint[0]},{resval.rpoint[1]}

</DisplayString>

<DisplayStringCondition="restype==5003">

{resval.rint} rint

</DisplayString>

<DisplayStringCondition="restype==5004">

{resval.rreal} rreal

</DisplayString>

<DisplayStringCondition="restype==5005">

{resval.rstring}

</DisplayString>

<DisplayStringCondition="restype==5006">

soft pointer id

</DisplayString>

<DisplayStringCondition="restype==5007">

pick set

</DisplayString>

<DisplayStringCondition="restype==5008">

orientation</DisplayString>

<DisplayStringCondition="restype==5009">

{resval.rpoint[0]},{resval.rpoint[1]},{resval.rpoint[2]}

</DisplayString>

<DisplayStringCondition="restype==5010">

{resval.rlong} rlong

</DisplayString>

<DisplayStringCondition="restype==5016">

list-begin

</DisplayString>

<DisplayStringCondition="restype==5017">

list-end

</DisplayString>

<DisplayStringCondition="restype==5018">

dotted pair

</DisplayString>

<DisplayStringCondition="restype==5031">

{resval.mnInt64} int64

</DisplayString>

<!--DXF/XData String-->

<DisplayString

Condition="(restype&gt;=1) &amp;&amp; (restype&lt;=9)">

{resval.rstring}

</DisplayString>

<DisplayString

Condition="(restype&gt;=100) &amp;&amp; (restype&lt;=103)">

{resval.rstring}

</DisplayString>

<DisplayStringCondition="restype==105">

{resval.rstring}

</DisplayString>

<DisplayString

Condition="(restype&gt;=300) &amp;&amp; (restype&lt;=309)">

{resval.rstring}

</DisplayString>

<DisplayStringCondition="restype==410">

{resval.rstring}

</DisplayString>

<DisplayString

Condition="(restype&gt;=430) &amp;&amp; (restype&lt;=439)">

{resval.rstring}

</DisplayString>

<DisplayString

Condition="(restype&gt;=470) &amp;&amp; (restype&lt;=479)">

{resval.rstring}

</DisplayString>

<DisplayString

Condition="(restype&gt;=999) &amp;&amp; (restype&lt;=1003)">

{resval.rstring}

</DisplayString>

<!--DXF/XData Double-->

<DisplayString

Condition="(restype&gt;=38) &amp;&amp; (restype&lt;=59)">

{resval.rreal} rreal

</DisplayString>

<DisplayString

Condition="(restype&gt;=140) &amp;&amp; (restype&lt;=149)">

{resval.rreal} rreal

</DisplayString>

<DisplayString

Condition="(restype&gt;=460) &amp;&amp; (restype&lt;=469)">

{resval.rreal} rreal

</DisplayString>

<DisplayString

Condition="(restype&gt;=1040) &amp;&amp; (restype&lt;=1042)">

{resval.rreal} rreal

</DisplayString>

<!--DXF/XData Point-->

<DisplayString

Condition="(restype&gt;=10) &amp;&amp; (restype&lt;=17)">

{resval.rpoint[0]},{resval.rpoint[1]},{resval.rpoint[2]}

</DisplayString>

<DisplayString

Condition="(restype&gt;=110) &amp;&amp; (restype&lt;=112)">

{resval.rpoint[0]},{resval.rpoint[1]},{resval.rpoint[2]}

</DisplayString>

<DisplayString

Condition="(restype&gt;=210) &amp;&amp; (restype&lt;=219)">

{resval.rpoint[0]},{resval.rpoint[1]},{resval.rpoint[2]}

</DisplayString>

<DisplayString

Condition="(restype&gt;=1010) &amp;&amp; (restype&lt;=1013)">

{resval.rpoint[0]},{resval.rpoint[1]},{resval.rpoint[2]}

</DisplayString>

<!--DXF/XData Int16-->

<DisplayString

Condition="(restype&gt;=60) &amp;&amp; (restype&lt;=79)">

{resval.rint} rint

</DisplayString>

<DisplayString

Condition="(restype&gt;=270) &amp;&amp; (restype&lt;=279)">

{resval.rint} rint

</DisplayString>

<DisplayString

Condition="(restype&gt;=370) &amp;&amp; (restype&lt;=389)">

{resval.rint} rint

</DisplayString>

<DisplayString

Condition="(restype&gt;=400) &amp;&amp; (restype&lt;=409)">

{resval.rint} rint

</DisplayString>

<DisplayString

Condition="restype==1070">

{resval.rint} rint

</DisplayString>

<!--DXF/XData Int32-->

<DisplayString

Condition="(restype&gt;=90) &amp;&amp; (restype&lt;=99)">

{resval.rlong} rlong

</DisplayString>

<DisplayString

Condition="(restype&gt;=420) &amp;&amp; (restype&lt;=429)">

{resval.rlong} rlong

</DisplayString>

<DisplayString

Condition="(restype&gt;=440) &amp;&amp; (restype&lt;=459)">

{resval.rlong} rlong

</DisplayString>

<DisplayString

Condition="restype==1071">

{resval.rlong} rlong

</DisplayString>

<!--DXF/XData ObjectId-->

<DisplayString

Condition="(restype&gt;=330) &amp;&amp; (restype&lt;=339)">

soft pointer id

</DisplayString>

<DisplayString

Condition="(restype&gt;=340) &amp;&amp; (restype&lt;=349)">

hard pointer id

</DisplayString>

<DisplayString

Condition="(restype&gt;=350) &amp;&amp; (restype&lt;=359)">

soft owner id

</DisplayString>

<DisplayString

Condition="(restype&gt;=360) &amp;&amp; (restype&lt;=369)">

hard owner id

</DisplayString>

<DisplayString

Condition="(restype&gt;=390) &amp;&amp; (restype&lt;=399)">

hard pointer id

</DisplayString>

<!--DXF/XData 8bit int-->

<DisplayString

Condition="(restype&gt;=280) &amp;&amp; (restype&lt;=289)">

{resval.rint} 8-bit rint

</DisplayString>

<DisplayString

Condition="(restype&gt;=290) &amp;&amp; (restype&lt;=299)">

{resval.rint} bool rint

</DisplayString>

<!--DXF/XData Binary Chunk -->

<DisplayString

Condition="(restype&gt;=310) &amp;&amp; (restype&lt;=319)">

binary size={resval.rbinary.clen}

</DisplayString>

<DisplayString

Condition="restype==1004">

binary size={resval.rbinary.clen}

</DisplayString>

<!--DXF/XData Int64 -->

<DisplayString

Condition="(restype&gt;=160) &amp;&amp; (restype&lt;=169)">

{resval.mnInt64} int64

</DisplayString>

<Expand>

<ItemName="rbnext">rbnext</Item>

<ItemName="restype">restype</Item>

</Expand>

</Type>

</AutoVisualizer>

To see the difference it makes to variable viewing, here’s how the debugger displays various kinds of AcStrings by default without the .natvis file:

June 18, 2014

We’ve been getting some interesting responses back from the AutoCAD Security Survey that has been posted over on the AutoCAD Futures beta forum. (If you haven’t already responded, we’d appreciate you taking the time to do so: it’ll probably take you less time than reading the rest of this blog post. Then please come back and finish reading this, too. ;-) The survey is intended to gauge whether the safeguards we first introduced in AutoCAD 2013 SP1 (and then further enhanced with the SECURELOAD mechanism in AutoCAD 2014) are properly understood and considered valuable.

From some of the feedback we’ve seen so far from the survey, it seems there are people out there who have concerns that introducing a JavaScript API somehow increases AutoCAD’s vulnerability to malicious code. I suspect this is due to the general sense that accessing the Internet is somehow what causes malicious code to infect computers, and that desktop software is inherently safer in nature.

This isn’t quite right. Yes, having computers connected to the Internet does increase their chances of being infected by malware, but it’s just one way of getting malicious code onto your system: aside from the obvious risks of malware coming across on pluggable media (CDs, DVDs, USB keys, etc.) recent research shows that it’s now possible to bridge the air gap, which is just plain scary.

Ignoring that last point, for now, system security ultimately comes down to trust. If you’re running AutoCAD on Windows, you (or perhaps your IT department) have placed trust in Microsoft and Autodesk to provide executable code that behaves in line with your expectations. Every time you install additional software onto your system – or open a DWG file that has been sent to you, more on this later – you are trusting the source of those bits.

Operating systems – especially those in the mobile space – are increasingly sandboxed, which means applications don’t have access to the APIs that could do naughty things on your system (sometimes the user gets the chance to approve or veto, sometimes the APIs are simply not there). This is also partially true on the desktop – where users can run with limited privileges – but to a far lesser extent.

Desktop AutoCAD does not run within an OS sandbox and neither does it provide nor enforce use of its own sandbox for applications, so application code that executes inside AutoCAD generally has the privileges accorded to the current OS user. As an AutoCAD user, you need to think carefully before running any custom application code inside AutoCAD, irrespective of the mechanism used to get it onto your system.

Software vendors are increasingly providing curated online marketplaces (a.k.a App Stores ;-) in an attempt to address both the discoverability of applications but also to increase the level of trust users have in them: typically some level of QA has been performed by the vendor to decrease the chances of these applications doing bad things. This is certainly true of Autodesk Exchange, for instance.

Running a custom module that happens to access the internet to download HTML and JavaScript which then gets executed locally isn’t fundamentally less secure than local executable code. In fact the nature of our hosting means that the code can run in the browser sandbox and only call into a limited set of functions that we make available to it. Alright, so these functions allow the HTML/JavaScript to call into .NET or native code, whether exposed as a callable function or a command, but then the application modules need to be present (and trusted) to provide these functions.

And the user isn’t free to browse to any web-page from an AutoCAD-hosted HTML dialog: it’s the local .NET or ObjectARX application that decides which pages to load into the browser, and if that application is doing something malicious then it’s much simpler to do so directly than loading a web-page to do it.

We introduced the SECURELOAD system variable to make people think carefully about the source of the application code they’re loading and running. If you don’t know or trust the source of executable code then you should not run it. Although it’s possible to do so – and it removes the annoyance factor of seeing this dialog on a regular basis – you should not disable the SECURELOAD feature. You should configure it to load modules you trust automatically but leave it enabled, otherwise.

The same goes for drawings you receive from untrusted sources: people may not realise this, but security researchers have found vulnerabilities in our DWG processing code (which have since been patched for AutoCAD 2011-2014 and fixed in AutoCAD 2015) that could allow users to execute malicious code that’s delivered as part of a specially crafted DWG file. We have a team focused on shoring up AutoCAD’s security to reduce the risk associated with this kind of attack, but this is really to point out that users need to think about trust whenever they load an application or open a DWG file from an unknown source.

In the next post I’m going to give some more context as to why all this matters (I would have included it here, but today’s post is already long enough). I’ll also introduce some resources that will hopefully make you think differently about security, as well as serving as some really interesting summer reading (honest!).

March 31, 2014

As mentioned in the last post, fibers are now inactive in AutoCAD 2015 (the code paths are still there, largely for testing purposes, but should not need to be enabled for typical usage of the product).

Fibers were a technology that Microsoft introduced way back when to help single document (and typically single-threaded) applications adapt more easily to the brave new world of MDI. At least that’s my recollection and understanding. They were basically a mechanism by which applications such as AutoCAD could manage their per-document state, making the relevant data current depending on the activated document. I’ve heard fibers referred to as “manually-scheduled threads”, although that’s likely to be a simplification of the real situation.

So what does this mean to AutoCAD developers, and why do we care?

Aside from making debugging more predictable – Visual Studio hasn’t allowed debugging of applications using fibers for a few releases – this work has brought significant benefits for developers.

The way I understand it – and it’s very likely that my understanding is either incomplete or flawed, as I haven’t spent a significant amount of time looking at the guts of this mechanism – AutoCAD commands depend on state associated with the current document. Moving away from fibers means the execution context of AutoCAD commands is quite different, but it also brings about opportunities that weren’t there before, as we’ve rationalized the way commands can be called, making them first-class, fully supported ways of making use of the huge amount of pre-existing code inside AutoCAD. Which essentially means AutoCAD developers should no longer feel bad (if they ever did ;-) about calling commands from their code. It’s now absolutely valid to do this – it’s just as valid to call commands as it is to make use of a lower-level API.

Prior to AutoCAD 2015, you would generally call AutoCAD commands by firing tokens – command names and the user inputs those commands expected – into AutoCAD’s input throat. From AutoCAD 2015 onwards, there are two approaches for calling commands: subroutine and coroutine. Subroutine command-calling means that you want to execute a command in its entirety: you know exactly how the command should be called and don’t want things to be open-ended. Coroutine command-calling is more open-ended: you don’t have all the arguments to provide to the command – and don’t know exactly how it’s going to proceed – so you’re really calling a partial command.

Without fibers acting as a support structure, these two styles of command-calling now need to be handled separately.

In ObjectARX, for instance, you’ll no longer find acedCommand() or acedCmd(), you have to use either acedCommandS()/acedCmdS() or acedCommandC()/acedCmdC(), depending on the command-calling style you choose. acedCommandS()/acedCmdS() are easy: they work in much the same way as acedCommand()/acedCmd() used to, but only with complete command/argument sets. acedCommandC()/acedCmdC() are more complicated: you need to provide a callback function that will be called to further process input tokens (it’s a form of continuation passing that is very common when dealing with asynchronous method calls, for example). ObjectARX developers should take a look at the ObjectARX Developer’s Guide as well as acedCmdNF.h (NF presumably stands for non-fiber in this context) for more information.

So ObjectARX developers have some work to do if they’re calling commands in AutoCAD 2015, then. What about the other programming environments?

AutoLISP is much simpler: Autodesk has full control over the “virtual machine” that executes LISP code inside AutoCAD, so we can choose which of the two underlying ObjectARX functions to call, depending on the scenario and without requiring a change in the LISP calling code. That said, the ADN team tells me they’ve seen scenarios where a developer specifically needed to specify the subroutine style, at which point they’ve been able to call (command-s …) instead.

For VBA – which has now been updated to VBA 7.1 and is still available as a separate download – I don’t think anything has changed: it still has the AcadDocument.SendCommand() method, which seems to work with partial commands (I’ll update this post if I hear anything different on that front).

.NET is also simple in its own way: subroutine calls are straightforward – they simply run synchronously via Editor.Command() – and because AutoCAD 2015 now makes use of .NET 4.5 – which provides C# with the async/await mechanism for calling asynchronous methods – we’ve been able to implement that mechanism for coroutine calls. These now make use of the compiler’s automatic callback generation via the await keyword to work asynchronously – e.g. await Editor.CommandAsync(…). You’ll need to tag any command method using CommandAsync() with the async modifier, just as you would when using other awaitable methods.

The difference between C# and C++ is analogous to general asynchronous coding: changes have been made at the language level to make asynchrony easier to handle from C#, and in time comparable extensions will make their way into C++ also.

Do bear in mind that to target .NET 4.5 – which is a requirement to use the API enhancements in AutoCAD 2015 – you will need to use Visual Studio 2012 or 2013: VS2010 cannot target .NET 4.5. (ObjectARX developers will have to use the toolset from VS2012 to compile their C++ modules, as that’s the compiler being used to build AutoCAD.) I’m personally now using VS2013 as a primary IDE, but make use of the VS2012 toolset when building ObjectARX modules.

If you’re still using VS2010, you *should* be able to target your .NET application against the class libraries for AutoCAD 2013 or 2014 (as long as you’re not making use of newer APIs) and run that code in AutoCAD 2015, but do make sure you test your application thoroughly.

In tomorrow’s post we’ll take a look at a new capability related to product theming that has been enabled in AutoCAD 2015.

Update:

To give a sense for the differences between Command() and CommandAsync() when used from C#, here are two commands, one that calls INSERT synchronously with the full set of arguments and one that calls it asynchronously, asking the user to enter the insertion point (a very common scenario, as jigging the block to show the block’s graphics is much more complicated than just calling INSERT).

March 04, 2013

Viru Aithal from the ADN team posted a link to this survey on the ADN DevBlog and asked that I post it here, too.

The survey will help us determine your priorities for developer-oriented documentation, so we definitely appreciate the time you take to fill it out. [You might even find out about documentation resources of which you were previously unaware – there’s quite a list in there.]

My inbox is nearly back under control after my week of holiday, so I’ll certainly be posting more during the course of the week.

The survey will remain open until June 22nd, but don’t delay – you’ll find it very quick to complete. This year’s survey has a somewhat different format: it has a number of questions dedicated to understanding your needs around AutoCAD WS and developing for the cloud. This doesn’t mean we’re no longer interested in the desktop – nothing could be further from the truth – so be sure to use the survey to let us know your requirements for full AutoCAD, too.

September 07, 2011

In the last post, we saw the steps involved in preparing an AutoCAD application for posting to the Autodesk Exchange store. In this post, we’ll step through the submission process.

Let’s start with some basics: posting to Autodesk Exchange currently happens from within the AutoCAD product, which means you’ll need AutoCAD 2012 installed (and running) to submit your product.

Step 1 – sign into (or up for and then into) Autodesk Exchange.

Within AutoCAD 2012, sign in to Autodesk Exchange.

If you’re not already in possession of an Autodesk ID, click on the link to create one. If you have one, just use it to sign in and then skip ahead to Step 2.

You’ll need to fill out some information to get an Autodesk ID. I’ve gone through the process of creating a new one, for the purposes of this post (I wanted to show all the steps involved, rather than skipping ones I’d gone through in the past).

Once your account is created, you’ll receive a notification in AutoCAD that you’ve been signed in automatically.

Step 2 – request your publisher status.

Open Autodesk Exchange via the icon next to the notification, above. You’ll find the button to click on in order to start the process proper at the bottom-right of the Apps tab:

You’ll be presented with an explanation of the concept behind Autodesk Exchange Apps and how to take advantage of it. Click on the “Publish Now” button at the bottom of the page, which will start the process of requesting the status of App Publisher.

Fill out the form with the pertinent details.

There are several pages worth of agreement to read (and hopefully accept)…

… via the radio-button at the bottom of the page.

Step 3 – fill out the product submission form.

As you fill out this form – which includes quite a lot of information – I do recommend keeping a Notepad session going into which you copy & paste the information you enter. This just makes it less likely that if a catastrophic error happens you’ll have to start from scratch.

Start by giving your application a name (which must be unique – you’ll be told if the name has already been taken when you try to preview the online help-file, later on), and then provide a short and long description of its functionality.

Use the “Choose File” button to select your ZIPped application bundle (as created in the previous post) and then “Upload” it.

If you scroll down, you can specify the experience level required to use the application, the name and URL of your company as well as the email address to be used for support issues.

It’s here that you can specify the price of your application. If you select the “USD” option, you can enter the price you wish to charge. If you choose this option, you will need to provide details on your PayPal account (which you will need to set up separately – something beyond the scope of this particular post).

Next you should select the type of product (the most likely choice is “App”, given the focus of this post) and its compatibility with AutoCAD-based products. Be sure that this compatibility reflects reality, otherwise you will certainly receive support issues related to incompatible products (as well as having disgruntled users), at some point in the future.

Next you should select the store categories. While this particular app is of general interest, I haven’t checked the various industries that might use it (all of them, I suspect). I selected “Productivity Tools”, and might have also selected “Translators”, but consider that as being more for model – rather than language – translation.

Lower down you can specify and upload a thumbnail image for your app and screenshots of it in action (images which need to be .jpg, .png of .gif – not .bmp).

Next you can add information for each command exposed by your application:

Followed by some general, descriptive text for the application itself:

And then the final set of information around the author and the mechanism for support.

You can add information on the various versions, at this point, too, and then preview the HTML help that will get auto-generated using much of this content.

At this stage it’s important to check the preview of the online help for errors and correct them:

And then hit submit, to send it across to us:

At which point you’ll receive a notification that the submission has occurred, all being well:

I also received an email describing the successful submission:

In the next post, we’ll take a look at the process to follow should your application be rejected by the Autodesk Exchange Apps testing team (many applications end up needing an iteration or two of this process, for one reason or another).

August 26, 2011

In the 2010 release, we introduced 2D geometric constraints to AutoCAD. The feature was implemented using AutoCAD’s low-level – and very powerful – Associative Framework, which has subsequently been used to implement features such as parametric surfaces in AutoCAD 2011 (more information on that here). Our initial API implementation for creating and accessing geometric constraints (which you can find out more about via the DevTV session linked to from this previous post) in many ways reflects the low-level nature of the underlying framework: it was unfortunately just a bit too complicated for most mortals to get to grips with.

Philippe Leefsma, from DevTech EMEA, and Gopinath Taget, from DevTech Americas, have worked with our Engineering team to develop a “high-level” API for constraints inside AutoCAD, which does a great job of abstracting away much of this complexity.

The API distribution includes a single VS 2008 solution – as the API has been implemented using ObjectARX, which currently requires the use of VS 2008 – containing projects for the C++ API, the mixed-mode layer exposing this to .NET and a test project for each of these managed and unmanaged APIs.

For people such as myself using VS 2010, the best thing to do is to load this solution – converting the various projects – and then unload the projects you don’t need: AdnAssocConstraintAPI, AdnAssocConstraintAPIMgd and ArxConstraintAPITest. You will then need to set a “Reference Path” in the remaining project (MgdConstraintAPITest), pointing it to the compiled AdnAssocConstraintAPIMgd.dll file in the “bin resource” folder, as well as to the usual AcDbMgd.dll and AcMgd.dll files.

Beyond that, the implementation should be relatively straightforward: I suggest trying out the various commands implemented in the test project to get a feel for what’s possible, as well as taking a look at the compiled help-file provided in the Help folder.

Here are a list of these commands with a brief description of what they do:

March 23, 2011

As you may have seen – including over at Shaan’sblog – the 2012 family of our products has now been announced.

Stephen Preston, our DevTech Americas Manager, has recorded a DevTV session on the new APIs in AutoCAD 2012. This material was presented during our recent Developer Days tour, attended by ADN members around the world.

I’ll definitely be following up with more information on these APIs over the coming weeks/months, in particular the new Autoloader feature, which I think readers of this blog will find extremely valuable.