Autocad® Architecture and Autocad® Mep: About The Speaker
Autocad® Architecture and Autocad® Mep: About The Speaker
DE211-1 The maturing AutoCAD Architecture and AutoCAD MEP .NET APIs in recent releases give you
more reasons than ever to get started with .NET programming. This course will introduce you to these .NET APIs.
We’ll discuss project setup, class hierarchy, and techniques for accessing objects and data. You should have some
basic programming knowledge, but the class will cover a broad range of beginner to intermediate programming
concepts.
[email protected]
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
Course Objective
This course is designed to introduce the .NET programming environment now available in AutoCAD
Architecture (ACA) and AutoCAD MEP (AMEP).
“The .NET Framework is a development and execution environment that allows different
programming languages & libraries to work together seamlessly to create Windows-based
applications that are easier to build, manage, deploy, and integrate with other networked systems.
One of the common misconceptions is around its name. The term .NET seems to indicate that this
new programming environment is primarily for web development. However, it should be viewed as a
platform framework in the same sense that “Windows API”, “MFC”, or “COM”, etc. are also used. The
difference being that the .NET Framework is a basis of platform and system functionalities regardless
of language, and it is not specific to a single programming domain (like “the web”).
For further information, please see the following links at the MSDN web site. There are many topics
that will help you to discover all the .NET fundamentals and taking you through very advanced topics
and capabilities.
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
http://msdn2.microsoft.com/en-us/netframework/aa569294.aspx
http://msdn2.microsoft.com/en-us/netframework/default.aspx
Managed Code
Let’s drill down a little deeper into the .NET terminology and discuss what managed code is all about.
First, as its name implies, managed code is “managed” by the system. All code is executed and
managed by the .NET Framework's Common Language Runtime (CLR). The language compilers all
produce code that is in the Microsoft Intermediate Language (MSIL) format and executes as
managed code. With this strategy, one benefit is that the system provides memory management for
you. As a C++ programmer, memory management is of utmost importance. For Visual Basic (VB) it
has not been as important, and the coding practices are a bit different. The concept of managed code
aims to make programming concepts consistent and eliminate the need for differing memory
management techniques.
Unmanaged Code
Exactly as it states, unmanaged code is just that… unmanaged. This is code that is compiled down to
“p-code” and is executed by the CPU in a native mode. Typically a “pure” C++ application is an
example of this.
Assemblies
Assemblies are a fundamental part of programming with the .NET Framework. Here’s the MSDN
definition:
“Assemblies are the building blocks of .NET Framework applications; they form the fundamental unit
of deployment, version control, reuse, activation scoping, and security permissions. An assembly is a
collection of types and resources that are built to work together and form a logical unit of functionality.
An assembly provides the common language runtime with the information it needs to be aware of
type implementations. To the runtime, a type does not exist outside the context of an assembly.”
http://msdn2.microsoft.com/en-us/library/hk5f40ct(VS.80).aspx
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
Structure
How is the .NET Framework structured? The CLR sits at the base of the system. It is responsible for
executing the code that comes from various sources through the MSIL format. It then has various
base-level platform libraries. The ASP and Windows forms sit on those. Finally the languages are at
the top to provide access to the libraries in their own unique way. See figure 1 for a diagram of the
structure.
Figure 2 illustrates the process used to compile and execute managed code that uses the CLR.
Source code written in C#, VB.NET, or some other language that targets the CLR is first transformed
into MSIL by the appropriate language compiler. Before execution, this MSIL is JIT (Just In Time)
compiled into native code for whatever processor the code will run on. The default is to JIT compile
each method when it is first called, but it’s also possible to “pre-JIT” the MSIL. With this option, all
methods are compiled before the application is loaded, so the overhead of JIT compilation on each
initial method call is avoided. Its worth noting is that all languages targeting the CLR should exhibit
roughly the same performance. While some compilers may produce better MSIL code than others,
large variations in execution speed are unlikely.
Reflection
Reflection is a basic feature of the .NET Framework. Essentially the .NET Framework provides APIs
that allow you to interrogate runtime information about assemblies in different ways. For example, you
could load an assembly and find out its types and members. Or from a specific instance of an object,
determine its type information and then actually call it members.
The ObjectARX Wizard (included with the ObjectARX SDK) provides a tool that will setup a minimal
VB.NET or C# project. However, this is not necessary to create a basic project. We will cover the
fundamental steps later in this document.
Implementing Commands
As mentioned earlier, the ACA and AMEP .NET API build on AutoCAD .NET API. Therefore, you will
probably utilize the AutoCAD command mechanism to invoke your .NET functionality. Creating a
command in the .NET API is quite different than ObjectARX or LISP (or VBA where it’s impossible
without another language’s help). The AutoCAD .NET API uses a specific attribute on a public
method to indicate that the method is to be invoked when the command is entered. The attribute is
appropriately called CommandMethod. The arguments are similar to those in the ObjectARX
addCommand function. For example in C#:
Or in VB.NET:
Implementing IExtensionApplication
The IExtensionApplication interface provided by AutoCAD allows another way to have your code
executed (instead of via a command). This mechanism allows you to have code executed upon start-
up (and shut-down, but note that there is no way to unload your application other than at shut-down!).
This allows you to initialize things at load time, but is completely optional.
Or in VB.NET:
Tip: You might chose to setup your applications in this manner (as above) all the time so that when
you try to load the application you know whether it loaded or not. AutoCAD provides no easy way to
see if your application is in fact loaded. By using the message at load time, you can see during
development whether the app loaded correctly before you spend time trying to run commands that
won’t be there!
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
Error handling
The .NET API provides errors in the form of exceptions. The exception handling is very similar to the
C++ style. An exception will be thrown by the API when an error condition arises. Typical exceptions
are in the form of:
• System.InvalidOperationException
• System.ArgumentNullException
• System.ArgumentOutOfRangeException
• System.ArgumentException
Here is an example in C#:
double result = 0;
try {
result = Converter.StringToDistance("foo");
}
catch (Autodesk.AutoCAD.Runtime.Exception e) {
result = double.NaN;
}
finally {
MessageBox.Show("Distance: " + result);
}
In VB.NET:
Catch e As Exception
' Since Autodesk.AutoCAD.Runtime.Exception is derived from
' System.Exception, this block fill catch *any* exception
MessageBox.Show(e.GetType.ToString + ": " + e.Message())
result = Double.NaN
The following ACA example shows how to catch a generic System.Exception and then cast it down to
check for the specific error you want. This allows you to catch a very fundamental exception, but then
check it for a specific condition.
The following AMEP example shows that when you query the AMEP Part Catalog an AMEP specific
exception may be thrown and if that is the only condition you really want to check, you can simply
catch that specific-level exception. In this case it is checking the ErrorCode of the exception to find
out what condition caused it. The example shows that in the case of
ErrorCode.QueryResultNull error code being returned, it requires additional specialized
handling.
Transactions
Transactions are a major part of dealing with AutoCAD database resident information. In order to
access or create anything within the AutoCAD database (including ACA and AMEP objects), you
must initiate a transaction. Transactions provide you with the ability to group operations together in a
single action, which can help with things like UNDO. You can nest transactions and either commit or
abort each sub-level as you wish. The transaction itself will deal with the closing or aborting of the
objects based on how the transaction ended.
Database db = HostApplicationServices.WorkingDatabase;
TransactionManager tm = db.TransactionManager;
In VB.NET:
Try
Dim obj As DBObject = tr.GetObject(id, OpenMode.ForXXXX)
‘ access/modify obj
‘...
‘ If a new object created and added to DB, must also:
tr.AddNewlyCreatedDBObject(objNew, True)
tr.Commit()
Catch ‘Not needed if only tr.Abort called. Dispose will call Abort if no
Commit called beforehand
tr.Abort()
Finally
tr.Dispose()
End Try
NOTE: The transaction itself must also be aware of new objects being added. So in addition to the
typical “add to the database” operation, you must also tell the transaction about the new object with
the Transaction.AddNewlyCreatedDBObject method.
Both C# and VB.NET now support the special keyword called using. By coding with this keyword, it
makes the transaction setup even easier. The transaction will automatically dispose (and abort when
appropriate). For example in C#:
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction t = db.TransactionManager.StartTransaction())
{
//...
object obj = tm.GetObject(id, OpenMode.ForWrite);
//...
Tip: In many cases you may be opening objects simply to read the data. In these cases it may be
logical to simply let the transaction automatically abort and dispose of itself. Unfortunately due to an
internal implementation detail in AutoCAD, it is ALWAYS faster to commit the transaction at the end,
even in the read-only situation. Because of this, only use the abort mechanism if you specifically want
to abort changes. You should get into the habit of committing the transaction in all successful cases.
This is especially true for applications that will be querying a large number of objects that has
performance concerns.
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
NOTE: The transaction requirement in .NET API is different than the ObjectARX model. In ObjectARX
you have two ways to deal with database resident objects. The first uses the open/close mechanism,
and the second is the transaction model. Either approach is fine for ObjectARX C++, although the
transaction approach has the additional benefits. AutoCAD .NET API provides only the transaction
model and is a requirement except in special circumstances.
To summarize, it is important to have a good base understanding of the AutoCAD .NET API before
diving into the ACA and AMEP APIs. Resources for AutoCAD .NET API information and training:
The AutoCAD .NET API (samples and documentation) is provided as part of the ObjectARX SDK.
The ObjectARX SDK is located here:
http://www.autodesk.com/objectarx
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
See figure 3.
Project Setup
First of all, let’s discuss the requirements for .NET API development. The basic piece that you need is
a compiler that supports the .NET Framework 2.0. If you review the material from the CLR discussion
previously, you will know that the resulting code is in the fundamental format called MSIL and
therefore is the only requirement for AutoCAD to load it. There are a number of sources that will
produce this format, but the most common environment is the Microsoft Visual Studio 2005 version.
We will be using this software for the class and the steps provided here are for that version.
http://msdn.microsoft.com/vstudio/ - Top level MS Visual Studio information. Also note that Visual
Studio is part of some MSDN level subscriptions (might be better value).
http://msdn.microsoft.com/vstudio/express/ - Express compiler editions are free, but are more difficult
to setup for debugging into an assembly that has been loaded by AutoCAD. For information on the
express editions debugging, see:
http://through-the-interface.typepad.com/through_the_interface/2006/07/debugging_using.html
Add References
In order to use objects from an assembly, we need to add a reference of the assembly to the project.
You can do this in the Project Menu->Add Reference. Each language has various other ways to reach
this dialog too. Note that the add reference dialog starts with the .NET components tab. The .NET API
assembly modules that Autodesk provides are not signed and do not reside in the Global Assembly
Cache (GAC), so we must specifically reference them from the acad.exe directory (the root directory
of where your ACA or AMEP software is installed). This is done from the Browse tab.
The following is a list of modules for use with ACA and AMEP:
these files will always be present with any ACA or AMEP install, there is no obvious benefit to using
the Copy Local flag and it can cause confusion if you try to package these with a distribution.
Tip: The browse tab is a file dialog. After browsing to the ACA or AMEP root directory, type-into the
File Name edit box: *Mgd.dll, which will filter down to match all the possible Autodesk managed
assemblies. This will help narrow down the files needed. This is also a multi-select dialog, so using
the Ctrl key you can multi-select all the assemblies that you need in a single action.
For example, there is a different object named DBObject in both ACA and AutoCAD .NET APIs. You
will see an ambiguous reference error when trying to use this type in a typical way. The reason for
this is because the object lives in both the Autodesk.AutoCAD.DatabaseServices and
Autodesk.Aec.DatabaseServices namespaces. In order to resolve the ambiguity, you must
clarify the namespace of the version you are intending to use. For example in a project that
references both AutoCAD and ACA database services, the code
Autodesk.Aec.DatabaseServices.DBObject obj =
new Autodesk.Aec.DatabaseServices.DBObject();
But that is a lot of extra code that makes it more difficult to read and will lead to code that
unnecessarily wraps to the next line, etc.
Another way to resolve this is to use an alias. There are two ways to provide this. At a specific object
level, or at a namespace level. For example, at the object level:
NOTE: You can use the actual name of the object to provide the alias, too. In the case of DBObject
and DBObjectId, this strategy might make sense because the AEC versions of these are not used
very often. The drawback is that for the other type you would need to provide a different alias, or fully
qualify it. Additionally, it is not obvious which object is actually being used unless you have specific
coding standards setup. For example:
Tip: Personally, I believe the namespace level alias is better if you plan large projects. This covers all
objects in the namespace, and it also does not change the name of the object itself, making
readability and maintenance easier over time. The drawback is that once you alias the entire
namespace; you must use the alias to reference all the objects within the namespace. It is certainly a
personal preference, but one to consider before writing a lot of code.
NOTE: ACA also provides an ActiveX API. Please note that in some cases there may be more
functionality exposed there than is present in the .NET API. If you do hit a road-block in .NET API,
please review the ActiveX object model for additional functionality. The nice thing about the .NET
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
development environment is that you can use COM interop easily (as easy as making a reference)
and mix the two APIs in the same program. Some frown upon this, but there is nothing wrong with it.
The AutoCAD and AEC development groups encourage you to use COM interop when necessary. Of
course please send us feedback if you do run into limitations in .NET API.
Hierarchy
As indicated earlier, ACA is built on top of the AutoCAD .NET API. This means that ACA APIs
actually derive from the base AutoCAD functionality, and the ACA API further derives from itself to
deliver robust functionality.
NOTE: This is major difference from the ActiveX API. ActiveX, even though it has a object hierarchy,
it does not derive from AutoCAD’s base objects. It will reuse things, but there is no actual derivation.
Autodesk.AutoCAD.DatabaseServices.Entity
Autodesk.AutoCAD.DatabaseServices.Curve
♦ Autodesk.Aec.DatabaseServices.Entity
Autodesk.Aec.DatabaseServices.Geo
♦ Autodesk.Aec.Arch.DatabaseServices.Wall
All ACA entities (for example Wall or Door) are derived from Geo.
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
For objects (for example an Anchor or a Wall Style), the basic hierarchy is as follows:
Autodesk.AutoCAD.DatabaseServices.DBObject
Autodesk.Aec.DatabaseServices.DBObject
♦ Autodesk.Aec.DatabaseServices.Anchor
♦ Autodesk.Aec.DatabaseServices.DictionaryRecord
Autodesk.Aec.Arch.DatabaseServices.WallStyle
All style objects (for example Wall Style or Door Style) are typically derived from DictionaryRecord.
For objects that support other objects (for example, a WallModifier), these are typically derived from
an internal ACA class called ImpObject:
Autodesk.AutoCAD.Runtime.RXObject
Autodesk.Aec.DatabaseServices.ImpObject
Autodesk.Aec.Arch.WallModifer
Because the objects are derived from each other, we can benefit from the true object oriented nature
of having access to the specific class functionality, and all derived class functionality.
Tip: There is a freeware tool available called .NET Reflector that can help you discover and explore
the hierarchy of any .NET API assembly. This tool works very well to quickly see what’s available
through the object model. It can be downloaded from there:
http://www.aisto.com/roeder/dotnet/
Catch ex As System.Exception
' a problem…
' call dispose to close all the open entities,
' but not commit anything to the drawing
tr.Dispose()
' lets display what the problem is
MsgBox("Error creating the wall: " + ex.Message)
End Try
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
[CommandMethod("WallStyleExample")]
public void test1()
{
Autodesk.AutoCAD.EditorInput.Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
AcDbObjectId id;
DictionaryWallStyle wallstyledict = new DictionaryWallStyle(db);
try
{
id = wallstyledict.GetAt("fred");
trans.Commit();
}
catch (System.Exception e)
{
if (e.GetType() == typeof(Autodesk.AutoCAD.Runtime.Exception))
{
Autodesk.AutoCAD.Runtime.Exception acade =
e as Autodesk.AutoCAD.Runtime.Exception;
if (acade.ErrorStatus ==
Autodesk.AutoCAD.Runtime.ErrorStatus.KeyNotFound)
{
ed.WriteMessage("\nAdding the Wall style we need.");
WallStyle wallstyle = new WallStyle();
wallstyle.SetToStandard(db);
wallstyle.SubSetDatabaseDefaults(db);
wallstyle.Description = "fred style";
wallstyledict.AddNewRecord("fred", wallstyle);
trans.AddNewlyCreatedDBObject(wallstyle, true);
trans.Commit();
}
} else {
ed.WriteMessage("\nError: " + e.Message);
}
}
}
}
• SetDatabaseDefaults
• SetToStandard
When initializing an ACA Object (anything derived from Autodesk.Aec.DatabaseServices.DBObject,
but is NOT an Entity), you need to call:
• SubSetDatabaseDefaults
• SetToStandard
The SetDatabasebaseDefaults function is an AutoCAD API which will establish basic entity level
properties such as layer, linetype, and color.
The SetToStandard function provides object initialization and some default values to make the
object “valid” without further initialization. The concept is that by making this call, you are guaranteed
that the object will have its data filled with valid values without any further initialization. For example,
simply allocating a wall without any further initialization will provide settings for the base height,
thickness, and cleanup radius.
Although the details are really not that important to the .NET API user, the reason for
SubSetDatabaseDefaults is because of a minor AutoCAD limitation. On the ObjectARX side,
there is a method implemented at the entity level called subSetDatabaseDefaults. The AutoCAD
framework calls this method for any derived entity when the setDatabaseDefaults is called. This
is why the AEC side does NOT require an explicit call to the subSetDatabaseDefaults for an
entity. However, there is no automatic framework for the object level, so the
SubSetDatabaseDefaults should be explicitly called in order for the object to be setup correctly
(ie. db references to other objects are often initialized here).
Anchors
Anchors are used typically to establish geometric relationships between objects. They exist as a
database object, so they are persistent and have data associated with them. For example, a door is
typically anchored to a wall at a specific location. If the wall is moved, the door stays in its position
relative to the wall. When working with objects in the context of anchoring it is a good idea to
determine if the objects are already anchored. The Geo derived objects provide a property for
determining the existing anchor called AnchorId. A typical scenario might be:
Hierarchy
AMEP is built on ACA, so it again reuses many of the base functionalities. Because it is also
interoperable with ACA, the AMEP programmer is obviously going to want to know some of the ACA
API in order to accomplish the desired tasks.
Base classes:
Autodesk.Aec.DatabaseServices.Geo
Autodesk.Aec.DatabaseServices.LayoutTool
♦ Autodesk.Aec.Building.DatabaseServices.LabelCurve
♦ Autodesk.Aec.Building.DatabaseServices.Fitting
♦ Autodesk.Aec.Building.DatabaseServices.Member
♦ Autodesk.Aec.Building.DatabaseServices.MultiViewPartBase
♦ Autodesk.Aec.Building.DatabaseServices.Schematic
♦ Autodesk.Aec.Building.DatabaseServices.Segment
Autodesk.Aec.DatabaseServices.ConnectionComponent
♦ Autodesk.Aec.Building.DatabaseServices.ConnectionComponentMember
Autodesk.Aec.Building.DatabaseServices.Segment
♦ Autodesk.Aec.Building.Elec.DatabaseServices.CableTray
Autodesk.Aec.Building.DatabaseServices.Fitting
♦ Autodesk.Aec.Building.Elec.DatabaseServices.CableTrayFitting
Autodesk.Aec.Building.DatabaseServices.MultiViewPartBase
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
♦ Autodesk.Aec.Building.Elec.DatabaseServices.Device
Autodesk.Aec.Building.DatabaseServices.Segment
♦ Autodesk.Aec.Building.Hvac.DatabaseServices.Duct
Autodesk.Aec.Building.DatabaseServices.Fitting
♦ Autodesk.Aec.Building.Hvac.DatabaseServices.DuctFitting
Autodesk.Aec.Building.DatabaseServices.MultiSegment
♦ Autodesk.Aec.Building.Hvac.DatabaseServices.DuctFlex
Autodesk.Aec.Building.DatabaseServices.Segment
♦ Autodesk.Aec.Building.Piping.DatabaseServices.Pipe
Autodesk.Aec.Building.DatabaseServices.Fitting
♦ Autodesk.Aec.Building.Piping.DatabaseServices.PipeFitting
Autodesk.Aec.Building.DatabaseServices.MultiSegment
♦ Autodesk.Aec.Building.Piping.DatabaseServices.PipeFlex
Autodesk.Aec.Building.DatabaseServices.Member
♦ Autodesk.Aec.Building.Plumbing.DatabaseServices.SchematicPipe
Autodesk.Aec.Building.DatabaseServices.MultiViewPartBase
♦ Autodesk.Aec.Building.Plumbing.DatabaseServices.SchematicPipeFitting
This assembly has methods needed to query, create and modify AMEP parametric parts.
DataPartLookup - Contains information about parts such as name, GUID and Path
DataQuery - Represents the query object for accessing the underlying xml files. This is where you
can specify how granular you want your results.
DataExpandedTable - The expanded table represents the results of the query. It will contain 0 to N
records based on the specifics of the DataQuery. You may limit the number of items returned by
providing a max search in the call: PartManager.GetPartTable(query, maxRecords);
DataField - The Datafield class represents the container object for the data. The datafield can hold
the following types:
• Boolean
• Double
• Integer
• ObjectId
• String
DataFieldCollection - Collection of the Datafields in a DataRecord. This class also contains the
methods for finding specific DataFields in the collection. For example:
Part Manager
The part manager provides static methods that help you to perform queries, part creation and
modification.
The PartManager class is responsible for all data associated with parts. Through the PartManager
you are able to add, query and modify the parts. It provides the following helpers:
• GetPartTable - Accepts a data query and finds the expanded table containing the parts
matching the query.
• ModifyPartViaQueryParameters - Accepts a query and modifies a part using the first valid
combination of parameters.
• ModifyPartViaRecord - Accepts a data record and expanded table to modify a specific part.
Queries
A query is something you will use to get access to the catalog data and connect it to a part. The
quickest and easiest way to drill down into the 1000s of parts available is to use a Part GUID. Each
part will have a GUID, but it is not enough information to identify the specific part based on size and
other attributes. In order to drill further down into the parts available, it is helpful to know the part
GUID ahead of time. The easiest way to browse the catalog from a GUID standpoint is to open the
XML files or write code to iterate over everyting.
Creating a Part
As compared to the ACA style of creating objects, AMEP requires the extra level of information from
the catalog to correctly establish the part. This is handled through the PartManager class and
involves querying the catalog for the specific part catalog data. Here are the steps to create a part:
Modifying a Part
To modify a part, it is very similar to the create part strategy. Again, you must perform a query to get
the correct catalog data, and then tell the PartManager of the new data.
AutoCAD® Architecture and AutoCAD® MEP
.NET Programming: A Beginner's Guide
Part Relationships
In AMEP the parts are usually linked together to form a system. You can use the objects to determine
what they are connected to, and then iterate over everything to find out the entire system’s set of
parts. The relationships are governed by the ConnectionComponentMember. Each object derived
from member (ie. Duct, CableTray, Pipe) will have this method and it will return a collection of
ConnectionComponentMembers.
Resources
Help files
ACA and AMEP Managed Help Files located in the <install dir>\Help directory. There is a single
umbrella help that contains access to all the sub-files.
Samples
There are several samples located in the CS.NET and VB.NET folders at <install dir>\Samples.
AecDisplayMgd – This is a new sample that demonstrates some of the display capability of the .NET
API.
AecHardwiredStylesMgd – This sample sets up all the styles to have default values.
AecProjectBaseMgd – This provides an example of how to navigate the project’s file system.
AModelerSampleMgd – This sample provides a variety of examples showing how to utilize the AEC
modeler.
Support
The discussion forums are a good place to get help from colleagues.
http://discussion.autodesk.com/forum.jspa?forumID=54
http://discussion.autodesk.com/forum.jspa?forumID=61
To become a developer (and receive developer support) see the ADN Site:
http://www.autodesk.com/adn