getting started with autocad civil 3d .net programming
TRANSCRIPT
Page 1 of 18
Getting Started With AutoCAD Civil 3D .NET Programming Josh Modglin – InMotion Consulting
SD4888-L Have you ever wanted to program and customize AutoCAD Civil 3D software but couldn’t seem
to make the jump from Microsoft VBA (Visual Basic for Applications Module)? We will walk through a real, live project idea from start to deployment using VBA, Microsoft .NET, and the AutoCAD Civil 3D software .NET API. In the process we will learn about proper referencing, object structure, transactions, and the loading of our built application into AutoCAD Civil 3D software.
Learning Objectives
At the end of this class, you will be able to:
Learn how to start and create a Microsoft .NET project
Learn how to build a .NET AutoCAD software command
Learn how to interact with the AutoCAD Civil 3D software .NET API
Learn how to deploy the completed code
About the Speaker
From being an award winning regional CAD Manager for a national Top 500 Engineering Firm, to
working with the implementation of AutoCAD Civil 3D by an International Engineering Firm, during the
software’s infancy in 2006 – Josh is recognized as a leader in the use, training, implementation,
consulting, and customizing of Autodesk Infrastructure products.
Josh started with AutoCAD Release 12 over 18 years ago and progressing through each release is
now building .Net applications for AutoCAD Civil 3D 2015. For the past 3 years, Josh has served as
the technical editor for the best-selling book, Civil 3D Essentials. In addition to writing and working with
the software, Josh has been a top-rated presenter at Autodesk University for four years.
Currently, Josh serves as the Managing Partner for InMotion Consulting, a technical consulting
solution provider and a member of the Autodesk Developer’s Network.
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 2 of 18
START AND CREATE A MICROSOFT .NET PROJECT All .Net customization starts with an IDE, or interactive development environment. Currently, Microsoft
provides two IDE’s for .Net programming within AutoCAD – Microsoft Visual Studio Professional and
Express for Windows Desktop.
Microsoft Visual Studio Express 2013 for Windows Desktop is free and, to get started with .Net
programming, is probably the best choice since it has most of the tools you will need to begin creating
very complex .Net add-ins for AutoCAD Civil 3D. In our class, we will be working with Microsoft Visual
Studio Professional 2013.
Nevertheless, once you have chosen to use .Net the next big step is to choose a language that works
FOR YOU. The great thing about .Net is that it takes whatever is written in the coding language and
compiles it into a common language at runtime meaning it makes no difference what language you
choose to write the code in. C++, C#, VB, and even F# all have the same capabilities when working
with the managed .Net API from Autodesk. Thus, the choice is left with what you are most comfortable
with, what language has the most samples to learn from, and what other type of coding you anticipate
doing in the future. In our class today, we will be using VB.Net since it is usually the easiest transition
for those who have coded in VBA.
Creating your Microsoft .Net Project Once you have installed Microsoft Visual Studio and selected the language you will be using, it is time
to build your Microsoft .Net Project.
Creating a .Net Project for AutoCAD Civil 3D – The Manual Process 1 Launch Microsoft Visual Studio
2
From the File menu
pulldown, select
New>Project
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 3 of 18
Creating a .Net Project for AutoCAD Civil 3D – The Manual Process
3
In the New Project
window, select on the left
side to use
Templates>Visual
Basic>Windows
Desktop>Class Library
4
Enter the name
and location of
the project.
You may also
want to Uncheck
the Create
Directory for
Solution option to
reduce the
making of extra
folders.
Click ok
5 From the view menu, select to view the Solution
Explorer palette
6
Within Solution Explorer, right-click on your project’s
name and select Properties from the menu More information about what is stored within your project’s
properties is l isted in the appendix.
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 4 of 18
Creating a .Net Project for AutoCAD Civil 3D – The Manual Process
7 Click on the references tab of your project’s properties.
8
Below the references list, click the Add… button. Once inside the Reference manager, select the
Browse… button down at the bottom right. We need to add references to Autodesk’s AutoCAD (since Civil 3D is built on top of AutoCAD) and Civil 3D APIs.
9
Browse to either the
location of the AutoCAD
exe or, better yet, browse
to the downloaded
ObjectARX directory and
add the following
references:
accoremgd.dll
acdbmgd.dll
acmgd.dll
AecBaseMgd.dll
10
Repeat step 8 and browse
to the location of the
AutoCAD exe. From that
location, browse to the
C3D folder and add the
following references:
AeccDbMgd.dll
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 5 of 18
Creating a .Net Project for AutoCAD Civil 3D – The Manual Process
11 From the View menu, select Properties
12
In the references list,
select the five
references, we just
added.
Using the Properties
palette, set the copy
local property to False
13 Select the Debug tab of your project’s properties
14
For the Start Action, set to Start
external program and browse to and
select the acad.exe
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 6 of 18
Creating a .Net Project for AutoCAD Civil 3D – The Manual Process
15
Set the Command line arguments to:
/ld "C:\Program
Files\Autodesk\AutoCAD
2015\\AecBase.dbx" /p
"<<C3D_Imperial>>" /product "C3D" If you don’t remember the above, go to the Civil
3D shortcut, right-click to select properties and
copy the information from the target (minus the
actual exe path of course)
That is a lot to do to just setup your project. I mean we haven’t even started coding yet. Granted, we
can store a lot of customization in one project (and even have more fun in using solutions) but isn’t
there an easier way? Yes, thanks to the ADN support team that just released a new project wizard for
Civil 3D .Net Projects. You can download the wizard from here.
Creating a .Net Project for AutoCAD Civil 3D using The Wizard 1 Launch Microsoft Visual Studio
2
From the File menu
pulldown, select
New>Project
3
In the New Project window, select on
the left side to use
Templates>Visual
Basic>Autodesk>Civil 3D 2015 Addin
4
Enter the name and
location of the project.
You may also want to
Uncheck the Create
Directory for Solution
option to reduce the
making of extra folders.
Click ok
5 That’s it! Note the Command line arguments discussed in Step 15 of Creating a .Net Project for AutoCAD Civil 3D using The
Wizard. The Wizard’s arguments point to Civil 3D’s Metric Profile.
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 7 of 18
As you can see, using the Wizard is much easier in the setup of our .Net project. Since this is the case,
all the rest of the exercises are built based upon the use of this Wizard. However, information will be
provided in the appendix to assist if you are building your add-in for earlier versions.
BUILD A .NET AUTOCAD SOFTWARE COMMAND Within our new project is a class called Commands.vb. It is within this class that we are going to write
our first AutoCAD command.
Creating a Command – Exercise 1 1 Launch Microsoft Visual Studio
2 From the File menu pulldown, select
Open>Project/Solution
3 Browse to the MyFirstProject1 directory
and select MyFirstProject1.sln
4 From the view menu, select to view the Solution
Explorer palette
5
Within Solution Explorer, right-click on your class
named Commands and select Open from the menu
More information about what is a class in the appendix
6
Inside the class, we are going to create a command
by entering the following between End Sub and End
Class:
<CommandMethod("ChangeAlignmentStyles")> _ Public Sub cmdChgAlignStyles() End Sub
We have just created a command named
ChangeAlignmentStyles. When this command is typed into the
command line, the Sub routine named cmdChgAlignStyles will
run.
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 8 of 18
Creating a Command – Exercise 1
7
Inside the sub routine, we are going to add the following line:
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
The current document (or drawing’s) editor allows us to output to the command line but also get input from the user at
the command line.
8
Within the sub and below the line we added in step 7, add the following:
Dim civDoc As Autodesk.Civil.ApplicationServices.CivilDocument civDoc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument We need to the Civil 3D Document object to interact with any C3D objects within the drawing. The code above gets the
active Civil 3D document (or drawing) and assigns it to a variable named civDoc.
9
Continue below the line added in step 8 by typing the following:
Dim alignIds As ObjectIdCollection = civDoc.GetAlignmentIds
We get a collection of objectIds for all the alignments within the drawing. ObjectId’s are unique Id’s for every object
within the drawing and created for each object per session (meaning they are different each time you open the drawing)
10
Add the following below the line added in step 9:
If alignIds.Count = 0 Then ed.WriteMessage(vbLf & "No alignments in drawing.") Exit Sub End If The above is a quick check to see if there are any alignments within the drawing. If none are found we write to the
command line (notice the call to the editor variable we created in step 7?) to tell the user such and end the command.
We have the beginnings of our command completed. Let’s test it.
Debugging/Testing our Project in AutoCAD Civil 3D
1 With your Visual Studio Project Open, click the Start button.
2
If you started with the .Net Wizard from Autodesk, that’s it. Your assembly (dll file) is loaded. Type
the command(s) at the command line.
If you did not start your project with the .Net Wizard, go to step 3. For more information on how this works, see Deploy the Completed Code
3 From the command line within Civil 3D, type NETLOAD
4 Browse to your project’s bin/Debug folder and load
your project’s dll
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 9 of 18
INTERACT WITH THE AUTOCAD CIVIL 3D SOFTWARE .NET API So we have created our first command and even begun to interact with Civil 3D’s document object.
Nevertheless, what we are really after is being able to query and change Civil 3D object properties and
more. To be able to do this we will have to run a transaction on the active document’s database.
Transactions To get anything from the document’s database, you need to query it. To query you need to start a
Transaction which ‘opens’, or connects you to the drawing database. Using the word, “Transaction”
let’s use a word picture. You go to the bank to:
Find out the current balance of your account
Withdraw some money
With the way a bank works, each event is a transaction. You start the transaction and then provide
some unique means to identify to the bank what account you are getting information on or even
making changes to.
Using that analogy let’s do a transaction on our alignments.
Creating a Command – Exercise 2 1 Launch Microsoft Visual Studio
2 From the File menu pulldown, select
Open>Project/Solution
3
Browse to the MyFirstProject2
directory and select
MyFirstProject2.sln
4 From the view menu, select to view the Solution
Explorer palette
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 10 of 18
Creating a Command – Exercise 2
5
Within Solution Explorer, right-click on your class
named Commands and select Open from the menu More information about what is a class in the appendix
6
Inside the cmdChgAlignStyles sub routine, we are going to make edits below the comment line.
First we are going to create a transaction. Type the following:
Using db As Database = HostApplicationServices.WorkingDatabase End Using
This gets the active drawing’s database and assigns it to a variable named db.
The Using Statement is a special way to code cleanly in VB.Net. The database variable is disposed of immediately after
the using Statement
7
Inside the db using statement added in Step 6, add the following:
Using db As Database = HostApplicationServices.WorkingDatabase Using trans As Transaction = db.TransactionManager.StartTransaction End Using End Using
We are taking advantage of the Using Statement for starting a transaction within the active database. The transaction is
assigned to the trans variable.
8
Inside the trans Using statement added in Step 7, add the following:
Dim align As Alignment For Each id As ObjectId In alignIds align = trans.GetObject(id, OpenMode.ForWrite) align.StyleId = civDoc.Styles.AlignmentStyles(0) Next We are interacting with our first REAL Civil 3D object within the .Net API. We are getting each alignment object created
in the Civil 3D drawing and assigning the first Civil 3D alignment style created to it.
To do this, we create a variable called align. We iterate through each ObjectId we got in Exercise 1, step 9 and get the
actual alignment object associated with the ObjectId. With the alignment object, we now have the ability to read to its
properties and even change its properties – such as assigning the alignment’s style by associating a style ObjectId to the
property.
9
Add the following below the line and outside of the next statement added in step 8:
trans.Commit Although we have made the changes to the alignments, no changes are committed or actually saved to the database
unless we call this method.
This is a basic example of applying changes to the properties of alignment objects. Let’s take this a little
bit further and provide information regarding what was done to our user. In the process, we will get
interact with the Alignment Style further.
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 11 of 18
Creating a Command – Exercise 3 1 Launch Microsoft Visual Studio
2 From the File menu pulldown, select
Open>Project/Solution
3 Browse to the MyFirstProject3 directory
and select MyFirstProject3.sln
4 From the view menu, select to view the Solution
Explorer palette
5 Within Solution Explorer, right-click on your class
named Commands and select Open from the menu More information about what is a class in the appendix
6
Inside the cmdChgAlignStyles sub routine, we are going to make edits below the comment line.
First we are going to create a transaction. Type the following:
Dim alignStyle As Styles.AlignmentStyle alignStyle = trans.GetObject(civDoc.Styles.AlignmentStyles(0), OpenMode.ForRead)
We create a new variable to store our alignment style object and then using the transaction, we get the object associated
with the objectId derived from selecting the first style in the alignmentstyles collection. We open it only to read
information but not make any changes.
7
Inside the For Each…Next statement, change align.StyleId = civDoc.Styles.AlignmentStyles(0)
to the following:
align.StyleId = alignStyle.Id
The old process we used in exercise 2 still works but this is another way to assign a specific style’s ID to an alignment.
8
Inside the trans Using statement, right above trans.Commit(), add the following:
ed.WriteMessage(vbLf & alignStyle.Name & " style has been applied to " & _ alignIds.Count & " alignments") Using the name of the alignment style that we retrieved in step 6, we tell the user (at the command line) what style we
change the alignments to and how many alignments received this change.
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 12 of 18
DEPLOY THE COMPLETED CODE Of course, chances are you want to share what you have done with others and want to make this as
automatic as possible. Autodesk came up with an improvement to automatic deployment through the
use of the application plug-ins folder and package contents file.
All you have to do is copy your dll to the C:\Program Files\Autodesk\ApplicationPlugins directory in a
special folder for your project. For example,
myproject.bundle folder. The two files required to exist in
this folder is your project assembly (the dll) and a
PackageContents.xml file.
When you use the Wizard to start your project it creates the base PackageContents.xml file for
you!
This is why you haven’t had to load your assembly for testing. It loads it for you by compiling your code
and placing a .bundle folder in your Roaming directory. Let’s look at editing this PackageContents.xml.
Editing the PackageContents.xml 1 Launch Microsoft Visual Studio
2 From the File menu pulldown,
select Open>Project/Solution
3 Browse to the MyFirstProject4 directory
and select MyFirstProject4.sln
4 From the view menu, select to view the Solution
Explorer palette
The folder must contain “.bundle”
at the end of the name
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 13 of 18
Editing the PackageContents.xml
5
Within Solution Explorer, right-click on your
PackageContents.xml file and select Open from the
menu
6
Inside the ComponentEntry element, we
are going to erase the
LoadOnCommandInvocation and
LoadOnRequest attributes. LoadOnCommandInvocation will only load the
library when one of the command names in the list
is called.
LoadOnRequest confirms WHEN the assembly
will load.
These options are VERY useful to reduce load
times at AutoCAD startup but require each
command to be entered into the Commands
element of the PackageContents.xml. Thus for
testing before deployment you may choose
replace them with Step 7.
7
In the ComponentEntry element, below the
AppDescription attribute, we are going to add
the following:
LoadOnStartup="True"
This attribute will always load the assembly on AutoCAD
startup.
8 Remove the Commands Element We don’t need the Commands element since we are not
using the attributes removed in Step 6.
9 The completed PackageContents.xml file should look like below.
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 14 of 18
Editing the PackageContents.xml <?xml version="1.0" encoding="utf-8" ?> <ApplicationPackage SchemaVersion="1.0" AutodeskProduct="AutoCAD" ProductType="Application" Name="MyFirstProject4"> <CompanyDetails Name="" Phone=" " Url="" Email="" /> <RuntimeRequirements SeriesMax="R20.0" SeriesMin="R20.0" Platform="Civil3D" OS="Win32|Win64" /> <Components> <ComponentEntry AppName="Commands for MyFirstProject4" Version="1.0" ModuleName="./Contents/Win/MyFirstProject4.dll" AppDescription="Description for command module of MyFirstProject4" LoadOnStartup="True"> <Commands> <Command Local="testMyFirstProject4" Global="testMyFirstProject4" /> </Commands> </ComponentEntry> </Components> </ApplicationPackage>
More information about the package contents file is located at:
http://help.autodesk.com/view/ACD/2015/ENU/?guid=GUID-BC76355D-682B-46ED-B9B7-
66C95EEF2BD0
APPENDIX
Additional Resources http://autodesk.com/developautocad
http://autodesk.com/developcivil
http://adndevblog.typepad.com/infrastructure
http://adndevblog.typepad.com/autocad
http://through-the-interface.typepad.com
Civil 3D Project Templates for Visual Studio
Introduction to Civil 3D 2015 Programming (YouTube)
http://www.inmotioncon.com
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 15 of 18
Project Properties In our Solution Explorer, if we right-click on our project’s name and select properties this will open a
project’s properties tab.
Notice that our assembly name (or the dll that will be made for our plug-in once everything is compiled)
is the same name as our project. We can change the name of our output assembly but it is usually a
good practice to keep it the same as our project.
Namespaces Namespaces are what you might consider a directory structure (tree structure) for libraries. Thus, it
is a good practice to assign namespaces that organize all your libraries under one major
namespace (think Root directory).
The easiest way to make sure that all libraries we build are under the same root directory is to set
the root directory to our company name.
For example, in our project the main root directory, or first namespace, will be “AU”.
Now since this project will include all functions, methods, etc that is specific to working with Civil 3D,
we will add one more directory or namespace –
“Civil3D”. Thus, in our Root namespace we will
have “AU.Civil3D”.
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 16 of 18
References We have already added references to the required AutoCAD API libraries. However, Autodesk
provides additional libraries that can be used when developing in AutoCAD. For example,
adWindows.dll provides more integrated user interface tools.
Autodesk references aren’t the only references we can add. We can select additional Microsoft,
third party, or even references from other projects we have created.
Copy Local
Since we are building an AutoCAD add-on, then when our software runs the AutoCAD references
will already exist in and be called from AutoCAD. Thus, we need to set each of these references to
not be copied with our project. In fact most references we add do not need to be copied locally.
Pay attention to this property as you add references.
Classes
What is a Class? Oftentimes we refer to the file holding a class object as a class. However, classes in .Net are
actually objects. For example, you have in Civil 3D an Alignment object. This alignment object
INHERITS the traits and properties of a base AutoCAD object. You can create your own special
object in .Net with its own properties, methods, and functions by creating a new class. Then you
can use these for presenting user interfaces to the user and accomplish quicker coding.
Creating a Base Class For example, in our project we may need a user interface where the user can actually select a new
alignment style and from a group of alignments the user can use check boxes to select which
alignments they want to change styles to match the style selection. A lot more interactive than our
current command, right?
To do this, we are going to create a base class and populate this base class using functions. To
create a new class, right-click on our project name in Solutions Explorer and choose to
Add>Class…
This class is going to have two properties - Name and Id. We add properties using the following:
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 17 of 18
Public Class BaseC3DObject Private oId As ObjectId = Nothing Public Property Id As ObjectId Get Return oId End Get Set(value As ObjectId) oId = value End Set End Property Private oName As String = "" Public Property Name As String Get Return oName End Get Set(value As String) oName = value End Set End Property End Class
In this class, we have a variable defined which is only available within the class (declared Private)
set to something as default. Then we create a property which is available everywhere (declared
Public) and store the value for use.
Can you think you think of another property that belongs to all C3D objects? Maybe a description?
Or maybe you could add a property called IsSelected. This property will be a Boolean (or a
True/False) which can be bound to Controls in your Windows (forms or dialog boxes).
Using Classes Now that we have this base class, let’s see its real power by using it in a function. The function can
be called from anywhere and can populate a collection of these base class objects with all the
information we need. The function could be similar to the following:
SD4888-L – Getting Started With AutoCAD Civil 3D .NET Programming
Page 18 of 18
Public Shared Function GetAlignmentStyles() As List(Of BaseC3DObject) Dim civDoc As Autodesk.Civil.ApplicationServices.CivilDocument civDoc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument Dim alignStyles As Styles.AlignmentStyleCollection = civDoc.Styles.AlignmentStyles Dim aligns As New List(Of BaseC3DObject) Dim aBobj As BaseC3DObject Using trans As Transaction = _ HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction Dim align As Styles.AlignmentStyle For Each id As ObjectId In alignStyles Try align = trans.GetObject(id, OpenMode.ForRead) aBobj = New BaseC3DObject aBobj.Id = align.Id aBobj.Name = align.Name aligns.Add(aBobj) Catch End Try Next End Using Return aligns End Function
By doing this, we have all kinds of information about objects outside of a transaction. The uses for
classes are limitless so the key is don’t limit yourself to using classes simply as containers for your
code.