0% found this document useful (0 votes)
11 views43 pages

getting-started-with-objectarx

Uploaded by

wplais
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
11 views43 pages

getting-started-with-objectarx

Uploaded by

wplais
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 43

CP11-4 Getting Started with ObjectARX

Tom Stoeckel

ObjectARX® is the most versatile and powerful programming


interface for developing new commands and applications to customize
and extend AutoCAD®. This course will introduce you to the basics of
ObjectARX and its classes. It will provide an overview of what
ObjectARX is all about, how it works, some of things you can expect
to do with it and what you'll need to get started.

1
Getting Started with ObjectARX

Your instructor – Tom Stoeckel


• Autodesk programmer for 6 years
• Express Tools and AutoCAD
• Battman, Layer Translator
• Digital Signatures, Reference Manager
• Customizing AutoCAD since Release 9

Getting Started with ObjectARX

This is an INTRODUCTION to ObjectARX


Some knowledge of C++ is assumed
A chance for info later in the week
• CP43-1 – December 5th @ 11:30am
• Beginning ARX for the LISP and VBA programmer
• Randy Kintzley

2
Housekeeping

Class Materials
Breaks
Questions
Session Evaluation Form

My Objective

You should know …


• Some basics about ObjectARX
• How to setup and use the ObjectARX SDK
• Where to find help and reference materials
• How to setup and use your compiler
• How to create an ObjectARX project
• Q&A

3
What is ObjectARX?

ARX (AutoCAD Runtime eXtension)


• A set of object oriented C++ libraries
• Comprehensive API
• Hundreds of classes
• Thousands of unique member functions

Advantages to ObjectARX

New objects can be added to AutoCAD and existing


programs can work with them right away!
Performance - Speed of execution
Notification of events
Provides a deep level of access into the system - the
same as used by Autodesk themselves
Database, operator interface, events

4
Downloading the ObjectARX SDK

Free for downloading


• www.autodesk.com/developautocad
• www.autodesk.com/objectarx
• www.objectarx.com

Reference Materials
ObjectARX SDK Help
Autodesk Developer Network (ADN)
• Free - www.autodesk.com/developautocad
• Membership - www.autodesk.com/joinadn
• Access to lots of Autodesk software
• Beta releases (NDA)
• Direct e-mail support
• On-line access to samples and solutions
• Invitations to ADN Technical Conferences
• Opportunities to attend API training classes
Newsgroups
• news://discussion.autodesk.com/autodesk.autocad.objectarx

5
Compiler Requirements
If developing for AutoCAD 2004
• Microsoft® Windows® XP (Professional or Home), Windows
2000, or Windows NT® 4.0 (SP6a or later)
• Microsoft Visual C++® version 7.0

Visual Studio.NET 2003 (VC7.1) is NOT supported for ObjectARX


development with AutoCAD 2004.
Since Microsoft no longer sells Visual Studio .NET 2002 (VC7.0)
directly, if you don’t already own this version, the alternative is to
purchase the Visual Studio .NET 2003, and downgrade to 2002.
Information on downgrading can be found at
http://msdn.microsoft.com/vstudio/previous/downgrade.aspx

Compiler Requirements

If developing for AutoCAD 2002, 2000i or 2000


• Microsoft® Windows® NT 4.0 or Microsoft®
Windows® 2000
• Microsoft Visual C++® version 6.0

6
Integrating the SDK into the compiler environment
Add the path to the SDK
include and library directories
to the list of Visual Studio
search folders.
Tools->Options menu
Projects->VC++ Directories

Primary ObjectARX Libraries


AcRx
• System level routines (initialization, linking, registration, etc)
AcEd
• Editor services (monitoring and notification)
• New AutoCAD command (defining and registering)
AcDb
• Database definitions for all geometry and table objects
• Query, manipulation and creation
AcGi
• Graphic interface, drawing entities
AcGe
• 2D and 3D geometry elements and geometry data manipulation
AdUi/AcUi
• MFC derived controls

7
Linking Requirements
All ObjectARX applications must link with acad.lib and rxapi.lib
Most will also require acdb16.lib so just include it as well

Additional libs required for classes:


• AcRx, AcDb and AcGi - None
• AcEd - acedapi.lib
• AcGe - acge16.lib
• AdUi - adui16.lib
• AcUi - adui16.lib and acui16.lib
• COM - axdb16.lib

How ObjectARX works

ObjectARX is supplied as a set of libraries.


ObjectARX programs are DLLs called by AutoCAD.
AutoCAD starts an ObjectARX program
• when loading initially
• when loaded by another ARX module
• when loaded using the command ARXLOAD

8
How ObjectARX works (cont’d)

After loading,
• AutoCAD calls a standard entry point
• Sends a code that tells the module to initialize
• Sends other codes as needed
• new drawing load
• AutoLISP subr request
• drawing saved

ObjectARX

Linking up with AutoCAD


• ARX module is loaded
• AutoCAD calls the “entry point”
• acrxEntryPoint()
• required in every ObjectARX program

First call is to initialize the interface


• kInitAppMsg

9
Messages

kInitAppMsg - initialize
kUnloadAppMsg - unload
kLoadDwgMsg - new drawing loaded
kUnloadDwgMsg - drawing unloaded
KInvkSubrMsg - from AutoLISP
KEndMsg - end
kQuitMsg - quit

Messages

The “k” names are constants set to integers.


During initialization it is time to establish
communication with AutoCAD.
• AutoCAD may NOT be all the way up!
• DO NOT run commands or expect entities to exist.
• DO establish new commands and reactor linkages
to your functions.

10
Messages

The second message into your ARX module will be to


inform you that a drawing is loaded.
Now AutoCAD is ready to process commands, allow
for entity linkages to reactors and so forth.
Init message will be sent once, load message may be
sent multiple times.

The AutoCAD Editor

The AcEd class has many services which include:


• Command stack utilities
• Event notification
• AcEdJig (used for interactive dragging)

There are two ways to register commands in ARX


• acedDefun()
• acedRegCmds->addCommand()

11
Command Registration
acedDefun()

Registers your commands as a LISP function


Invoked using (command)
Register during kLoadDwgMsg request
Must be removed with acedUndef() during
kUnloadDwgMsg request

Command Registration (cont’d)


acedRegCmds->addCommand()

Registers your commands as “native” commands on


the AutoCAD command stack with all the other
AutoCAD commands
ARX registered commands can be invoked using LISP
(command) or acedCommand()

12
AcDbLibrary

An AutoCAD drawing file is a collection of objects


stored in a database
By default a new database contains
• 9 symbol tables
• Named object dictionary
• 200+ header variables (not objects)

AcDb classes give you access to these objects

AcDb Functions

Get the current database for the AutoCAD edit session


• acdbHostApplicationServices()->workingDatabase()

Multiple databases can be loaded at one time with


• readDwgFile()

• The AutoCAD editor can only work with the file that
it has opened
• Since a handle is only unique for a single database,
an object ID is automatically created for each object
in the session

13
AcDbDatabase
Is a collection of objects
• Each with a unique identifier that is guaranteed for the context
of that drawing
• Entities
• Graphical objects
• Objects
• Non-graphical
• A fixed set of symbol tables
• Layer, Linetype, Block, etc.
• Dictionaries
• Named object dictionary, Groups, etc.

Object IDs
Handle
• Object stored on disk
• Never changes and is never reused in the same drawing
• Use when the ID must persist between sessions
• Slower than ObjectID because they are stored as strings and
string comparison is slow
ObjectID
• Assigned when the drawing is opened
• Will be different from session to session
Object Pointer
• Assigned when an object is opened in memory
• Only valid while the object is open

14
ObjectID

The system creates an object ID for each object in the


database when it is read into memory
With the object ID, you can get a pointer to the actual
database object and modify it
Always use an object ID if you can as they are faster
than handles
Automatically translated to handles on filing
operations

Identifying an Object
There are several ways to determine what kind of object is
open
• desc
• Returns the class descriptor
• cast
• Returns an object of the specified type or NULL
AcDbEllipse* ellipseEntity = AcDbEllipse::cast(curEntity);
• isKindOf
• Object belongs to or is derived from the specified class
pObj->isKindOf(AcDbText::desc()
• isA()
• Returns the class descriptor object of an object whose
class is unknown
pObj->isA() == AcDbViewTableRecord::desc()

15
Working with Database Resident Objects
Creating New DRO
• Create an instance of the objects’ class
• Modify its state using it’s member functions
• Add it to the proper table or dictionary
• Close or cancel the object

Modify or Query a DRO


• Open the object using the objectID
• Modify or query the object using the objects member functions
• Close or cancel the object

Creating a New Object


AcGePoint3d p1, p2;
p1(0) = 1.0; p1(1) = 2.0; p1(2) = 0.0;
p2(0) = 2.5; p2(1) = 4.25; p2(2) = 1.0;

AcDbLine *pLine = new AcDbLine(p1, p2);

AcDbBlockTable *pBTable;
acdbHostApplicationServices()->workingDatabase->getSymbolTable(pBTable,
AcDB::kForRead);

AcDbBlockTableRecord *pBRec;
pBTable->getAt(ACDB_MODEL_SPACE, pBRec, AcDb::kForWrite);
pBTable->close();

AcDbObjectId lineID;
pBRec->appendAcDbEntity(lineID, pLine);

pBRec->close();
pLine->close();

16
Opening Database Resident Objects

Get a pointer to the actual object with


acdbOpenObject()
acdbOpenObject(pLayer, objIdCurLayer, AcDb::kForRead);

Specify which mode of access you want


• kForRead - up to 256 at one time on one object
• kForWrite – only 1 at a time per object

Open for read then upgradeOpen() for write

Object State Query/Manipulation

You can choose to open erased objects, the default is


false
Use the member functions to directly access object’s
state (data)
When looking for functions in header files or the help
files, don’t forget that some member functions will be
inherited from base classes

17
Ending Object Query/Manipulation

When Finished
• close()
• cancel()

Recording is automatic from open() to close()


Undo playback occurs automatically when cancel() is
called instead of close()
Use Smart Pointers (dbobjptr.h)

Basic Error Handling in ObjectARX

Always check your return values before proceeding


Do not assume anything
Acad::ErrorStatus
Check for NULL values
Use acadErrorStatusText()

Return useful error information from your own


functions

18
Memory Management - General

Close everything you open


Delete your iterators
Use Smart Pointers when possible
• include “dbobjptr.h”
• Takes some of the burden off of the developer to
keep track of everything

Memory Management - Objects


The responsibility of memory management changes
during the life cycle of an object.
When you create an instance of an object with new, it
allocates memory from AutoCAD’s drawing database
heap.
If your application never adds the object to the
database YOU are responsible for freeing that memory
with delete.
If the object is added to the database AutoCAD is now
responsible for that memory and you should NOT
delete it. Doing so would very likely cause AutoCAD to
terminate.

19
Memory Management - Strings

char* strings returned by the SDK are always allocated


from the AutoCAD heap
These strings should be de-allocated with
acutDelString()

char* pName = NULL;


if (pLayout->getLayoutName(pName) == Acad::eOk)
acutDelString(pName);

Memory Management - Strings

const char* strings returned by the SDK are the


responsibility of AutoCAD and should not be de-
allocated
const char* pName;
pLayout->getLayoutName(pName);

When in doubt, check the SDK help for the function in


question

20
Container Objects

Symbol tables
• Fixed set, you can not add or delete (only purge)
• Contains instances of symbol table records
• Layers
• Linetypes
• Blocks
• Dictionaries
• Generic container for any type of object
• Can create your own

Special Symbol Table

Block Table
• All entities are owned by block table records
• Has three default records
• *MODEL_SPACE
• *PAPER_SPACE0
• *PAPER_SPACE1
• Entities must be added one of these BTR’s to be
visible in AutoCAD editor

21
AcDbDictionary Definition

Database resident object


Maintains a map between text strings and database
objects
Becomes the owner of the added objects
Attaches itself to the object as a persistent reactor so
the dictionary can be notified when the object is
erased

Iterating Through Object Containers

Objects that use iterators


• Symbol tables
• Block table records
• Dictionaries
• Polylines
• Block references (inserts)
• Only useful when attributes are present

22
Iterator Protocol

Iterators can return erased as well as unerased


object/entities
Iterators can start at the beginning or end of the
container and walk forward or backward
Step direction can be changed any time
Iterators also provide a “seek” function to find a
specific object (by objectID or by object address)

Iterator Protocol

Inconsistency of iterator protocol reflects differences


in underlying containers
Obtaining, using, deleting iterators
• Use the newIterator() function (when it exists) to
create an iterator object and get a pointer to it
• Use the iterator member functions to walk the list of
objects in the container
• Delete the iterator object when finished
• Close the container object once the iterator is
deleted

23
Navigating Through Symbol Tables

AcDbSymbolTableIterator
• AcDbLinetypeTableIterator
• AcDbBlockTableIterator
• AcDbBlockTableRecordIterator
• AcDbLayerTableIterator
• AcDbTextStyleIterator

Reacting to Events

Events are when something happens


Process controls are examples of event driven
systems.
Reacting to seemingly random events may seem
complicated, but it really isn’t and it is common in
many applications.

24
Reactor

A reactor is something that reacts to a notification.


ObjectARX provides a set of standard reactors that
can be used.
You can have any number of reactors for a given
notification type.
There are five reactor categories in ARX

Reactor types

General database
Specific object
Command activities
ObjectARX monitoring
General purpose transaction

25
Notification Definition
Every object maintains a list of reactors itself
Transient Reactors
• Commonly known as event notification, to be used when you
want to monitor things that are happening during the edit
session

Persistent Reactors
• A way to make your object intelligent, your custom object can
react to whatever you want
• Other object being moved or copied
• Environment changes

Transient vs. Persistent


Transient Reactor
• Is an instance of a class
• Not saved from edit session to session
• Not copied with the objects

Persistent Reactor
• Is an objectID of a database resident object
• Can be derived from any type AcDbObject
• Stay with the drawing
• Copied when object is copied.

26
Editor Reactors – Notification Functions

commandWillStart()
commandEnded()
commandCancelled()
beginSave()
saveComplete()
etc.

Database Reactors – Notification Functions

objectAppended()
objectModified()
objectErased()
objectUnappended()
objectReappended()
etc.

27
Object Reactors – Notification Functions

copied()
openedForModify()
modified()
modifiedGraphics()
modifiedXData()
erased()
objectClosed()

Adding a Reactor
Finding the name to use is often the hardest step!
Three steps
• Derive from the appropriate base class
• Override member functions for notifications you
wish to receive
• Instantiate an object of your derived class
• Call addReactor() to addPersistentReactor()
member of the notifier object, passing it either a
pointer to or an objectID of the reactor object

No VETO power!

28
Removing a Reactor

Remove reactors by calling removeReactor() or


removePersistentReactor() function of the notifier
object, passing a pointer to the reactor object.
When your application unloads, it should remove all
transient reactors it planted
AutoCAD will take care of deleting persistent reactors
because they are database objects

Transient Reactor Details

The reactor object is directly called by the notifier


object
Can be added to/removed from watched object in any
open mode
Addition/removal not subject to UNDO
Transient reactor attachments are not copied when an
object is copied

29
Persistent Reactors Details
Persistent reactors can only be derived from AcDbObject and
classes derived from it (i.e. AcDbEntity, Custom Objects)
Reactor objects must be added o the database and given an
owner so they will persist
Can only be added to/removed from watched object when open
from write
This object must be added to the database and given an owner,
preferably a container object (i.e. dictionary)
When an object is copied, any persistent reactors attached to the
object are copied as well.

Notification Restrictions

While object is notifying it is in a read-only state


You are not able to modify it until the end of the
commit process which can be checked with
• objectClosed()
• transactionEnded()

Notification is a read-only affair: No Veto!


• (but workarounds…)

30
“Undoing” an Event

No veto so how do I “undo” a change that I’ve been


notified of?
• Cache state at time of openedForModify()
• When objectClosed() notification occurs, open
object for write and change state back (watch out
for infinite notification loop)
• Or put reactors on editor for lispEnded and
commandEnded. When one of these notifications
comes through then open object and change it back

Custom Objects

Why create a new object?


• For specific applications
• For specific needs in your programs
• For the fun of it?

New objects are complete class definitions


• You must explain everything about them to
AutoCAD!

31
Custom Objects

There are three macros that are available in


ObjectARX that make the creation of new objects
easy.
• ACRX_DXF_DEFINE_MEMBERS
• ACRX_DEFINE_MEMBERS
• ACRX_NO_CONS_DEFINE_MEMBERS

The hard part is overriding all the functions

Derive from Existing Class

There are three classes to derive from that are used


most frequently
• AcDbObject
• AcDbEntity
• AcDbCurve

32
Why not use existing objects?

There is little you can do to improve these objects


themselves
They already work! You want to make new objects.

Save and Load

Not only do you have to define how to manipulate


and draw the objects you must also define how to
save and load the object.

File storage is important - this where you


• Set up group codes for the data
• Define how the object is drawn if your program is
not available to control them

33
Save and Load

dwgOutFields - get data from the properties and


output them with group codes.
• writeItem
dwgInFields - get data from file and put them in the
properties of the custom object.
• readItem

Draw the Object

WorldDraw - draw in world view


ViewportDraw - draw in a view port
saveAs - draw when saving to a file
• This is what object will look like when your
ObjectARX program is NOT loaded.

AcGi function library is used to draw the objects

34
Proxy objects

Proxies occur when your ObjectARX program is not


loaded.
• These used to be called Zombies - a much more
descriptive term!
• worldDraw or SaveAs is used to define what the
object will look like - this information is saved in
the DWG outside of your control.

Creating a simple ObjectARX project


From the File pull down menu of Visual C++ .NET,
select New and Project....
Click on the VC++ Projects node in the Project Types
tree on the New Project dialog that appears.
Select Win32 Project in the list of templates.
Enter the desired project name in the Name edit box.
Set the location to the folder where you want your
project to be stored, then click OK. This will invoke the
Win 32 Application Wizard dialog.
Select Application Settings tab on the wizard. Select
DLL for the Application type option.
Click on Finish to create the project.

35
Creating a new ObjectARX project
Right click on the project node in the Solution explorer and select
the Properties in the right-click menu. This brings up the property
pages dialog for the project.
In the Configuration drop-down list, select All Configurations.
This will ensure that the changes we make are applied to all the
configurations.
Select the node C/C++ -> General and set Detect 64-Bit
Portability Issues to No. Click Apply button to apply the changes.
Select the node C/C++ -> Code Generation. Select the item
Runtime Library in the list. Assign the property Multi-threaded
DLL (/MD), by selecting the property from the drop-down list.
Select the node Linker -> Input. In the Additional Dependencies
item, add the following libraries: "rxapi.lib acdb16.lib acge16.lib
acad.lib acedapi.lib"
Next, select the node Linker -> General. In the Output File item,
change the extension of the output file from ".dll" to ".arx".

Create the definition (.DEF) file


Used to provide linkage to AutoCAD’s ObjectARX handling system

From the Project pull down menu, select Add New Item
In the Add New Item dialog, select item Def File (.def).
Enter the name of your project in the Name edit box.
Click "Open"
Add the following information to an EXPORTS section in the new
file. All ObjectARX applications have to export at least two
functions

EXPORTS
acrxEntryPoint PRIVATE
acrxGetApiVersion PRIVATE

36
Header Files

Include necessary header files

#include <aced.h>
#include <rxregsvc.h>

Add header files as needed by ObjectARX classes and


functions that you use in your application
See your SDK help to determine which headers are
needed

Add Init and Unload functions

These will be referenced by acrxEntryPoint()

initApp()
• Called by AutoCAD when our application is loaded

unloadApp()
• Called when our application is unloaded.

37
Add Init and Unload functions
void initApp();
void unloadApp();

void initApp()
{
// register a command with the AutoCAD command mechanism
acedRegCmds->addCommand("HELLOWORLD_COMMANDS",
"Hello",
"Bonjour",
ACRX_CMD_TRANSPARENT,
helloWorld);
}

void unloadApp()
{
acedRegCmds->removeGroup("HELLOWORLD_COMMANDS");
}

Add the main function body


This function simply prints a message at the AutoCAD
command line
void helloWorld();

void helloWorld()
{
acutPrintf("\nHello World!");
}

38
acrxEntryPoint()

This is the main program module


AutoCAD expects to find one in every ARX app
Messages are sent directly to your application
Set up and shut down control handled here

extern "C" AcRx::AppRetCode


acrxEntryPoint(AcRx::AppMsgCode msg, void* appId)
{
switch(msg) {
case AcRx::kInitAppMsg:
// Allow application to be unloaded. Without this statement, AutoCAD will
// not allow the application to be unloaded except on AutoCAD exit.
//
acrxUnlockApplication(appId);
// Register application as MDI aware. Without this statement, AutoCAD
// will switch to SDI mode when loading the application.
//
acrxRegisterAppMDIAware(appId);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
case AcRx::kLoadDwgMsg:
// initialize lisp functions here
break;
case AcRx::kUnloadDwgMsg:
// remove lisp functions here
break;
}
return AcRx::kRetOK;
}

39
Macros to simplify common operations
Consolidate several lines of code into one
Add these to a header file in your project.

Check if the Acad::ErrorStatus is eOk


inline int
EOK(Acad::ErrorStatus arg)
{
return arg == Acad::eOk;
}

Usage
Acad::ErrorStatus es;
es = acdbOpenObject(pBlockRef, blkRefIds[i], AcDb::kForWrite);
if (!EOK(es))
break;

Macros to simplify common operations


Same as above only display an alert dialog when things aren’t eOk

#define EOKM(arg) \
((arg == Acad::eOk) ? true : Mutter(__FILE__, __LINE__, arg))

inline bool
Mutter (char *file, int line, Acad::ErrorStatus arg)
{
char buf[1024];
wsprintf(buf, "!%s@%d: %s", file, line, acadErrorStatusText(arg));
acedAlert(buf);
return false;
}

Usage

Acad::ErrorStatus es;
es = acdbOpenObject(pBlockRef, blkRefIds[i], AcDb::kForWrite);
if (!EOKM(es))
break;

40
Macros to simplify common operations

Get the working database without all that typing

inline AcDbDatabase *
CURDB()
{
return acdbHostApplicationServices()->workingDatabase();
}

Usage:
AcDbBlockTablePointer pBlockTable(CURDB(), AcDb::kForRead);

You get the idea!

ObjectARX Summary

It is not difficult to program in ObjectARX


Opens a wide world of possibilities

The next step...

41
The next step

Learn C/C++?

More information?

Learn by doing

Thank You

Turn in your session evaluation forms as you leave


Email: tom.stoeckel@autodesk.com

42
43

You might also like