getting-started-with-objectarx
getting-started-with-objectarx
Tom Stoeckel
1
Getting Started with ObjectARX
2
Housekeeping
Class Materials
Breaks
Questions
Session Evaluation Form
My Objective
3
What is ObjectARX?
Advantages to ObjectARX
4
Downloading the ObjectARX SDK
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
Compiler Requirements
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
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
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
9
Messages
kInitAppMsg - initialize
kUnloadAppMsg - unload
kLoadDwgMsg - new drawing loaded
kUnloadDwgMsg - drawing unloaded
KInvkSubrMsg - from AutoLISP
KEndMsg - end
kQuitMsg - quit
Messages
10
Messages
11
Command Registration
acedDefun()
12
AcDbLibrary
AcDb Functions
• 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
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
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
17
Ending Object Query/Manipulation
When Finished
• close()
• cancel()
18
Memory Management - General
19
Memory Management - Strings
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
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
22
Iterator Protocol
Iterator Protocol
23
Navigating Through Symbol Tables
AcDbSymbolTableIterator
• AcDbLinetypeTableIterator
• AcDbBlockTableIterator
• AcDbBlockTableRecordIterator
• AcDbLayerTableIterator
• AcDbTextStyleIterator
Reacting to Events
24
Reactor
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
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.
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
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
30
“Undoing” an Event
Custom Objects
31
Custom Objects
32
Why not use existing objects?
33
Save and Load
34
Proxy objects
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".
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 <aced.h>
#include <rxregsvc.h>
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");
}
void helloWorld()
{
acutPrintf("\nHello World!");
}
38
acrxEntryPoint()
39
Macros to simplify common operations
Consolidate several lines of code into one
Add these to a header file in your project.
Usage
Acad::ErrorStatus es;
es = acdbOpenObject(pBlockRef, blkRefIds[i], AcDb::kForWrite);
if (!EOK(es))
break;
#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
inline AcDbDatabase *
CURDB()
{
return acdbHostApplicationServices()->workingDatabase();
}
Usage:
AcDbBlockTablePointer pBlockTable(CURDB(), AcDb::kForRead);
ObjectARX Summary
41
The next step
Learn C/C++?
More information?
Learn by doing
Thank You
42
43