Monday, July 6, 2009

Accessing the AutoCAD Civil 3D Object Model with AutoLISP

I was grubbing around today for my cheat sheet on talking to the AutoCAD Civil object model using AutoLISP, and I found out it isn't that easy to find. So, time for a post. I remember I got my first hint at the Ontario Civil 3D blog, where it talks about accessing the model with Visual Basic. And doing the same with AutoLISP is almost the same process.

First, you have to understand that accessing the model is largely a matter of drilling down into the model tree until you find what you want. It may take some guess-work, but it isn't all that hard. Here. I'll show you what I mean.

First start the Visual LISP editor using the VLISP command. Then paste either or both of the following bits of code into the Visual LISP Console window:

Snippet 1 (AutoCAD)

(SETQ ACADAPP (VLAX-GET-ACAD-OBJECT))
(VLAX-DUMP-OBJECT (VLAX-GET-PROPERTY ACADAPP
'PREFERENCES) T)


Snippet 2 (AutoCAD Civil 2010)

(setq aeccapp (vla-getinterfaceobject ACADAPP "AeccXUiLand.AeccApplication.7.0"))
(VLAX-DUMP-OBJECT AECCAPP T)


I got the following output when I pasted both:


#
; IAcadPreferences: This object specifies the current AutoCAD settings
; Property values:
; Application (RO) = #
; Display (RO) = #
; Drafting (RO) = #
; Files (RO) = #
; OpenSave (RO) = #
; Output (RO) = #
; Profiles (RO) = #
; Selection (RO) = #
; System (RO) = #
; User (RO) = #
; No methods
T
#
; IAeccApplication: interface IAeccApplication
; Property values:
; ActiveDocument = #
; Application (RO) = #
; Caption (RO) = "AutoCAD Civil 2010 - [turntest.dwg]"
; Documents (RO) = #
; FullName (RO) = "C:\\Program Files (x86)\\AutoCAD Civil 2010\\acad.exe"
; Height = 1036
; HWND (RO) = 1903218
; LocaleId (RO) = 1033
; MenuBar (RO) = #
; MenuGroups (RO) = #
; Name (RO) = "AutoCAD Civil 2010"
; Path (RO) = "C:\\Program Files (x86)\\AutoCAD Civil 2010"
; Preferences (RO) = #
; StatusId (RO) = ...Indexed contents not shown...
; VBE (RO) = #
; Version (RO) = "18.0s (LMS Tech)"
; Visible = -1
; Width = 1696
; WindowLeft = -8
; WindowState = 3
; WindowTop = -8
; Methods supported:
; Eval (1)
; GetAcadState ()
; GetInterfaceObject (1)
; Init (1)
; ListArx ()
; LoadArx (1)
; LoadDVB (1)
; Quit ()
; RunMacro (1)
; UnloadArx (1)
; UnloadDVB (1)
; Update ()
; ZoomAll ()
; ZoomCenter (2)
; ZoomExtents ()
; ZoomPickWindow ()
; ZoomPrevious ()
; ZoomScaled (2)
; ZoomWindow (2)
T


AutoCAD dumped for me the Preferences collection of the AutoCAD (IAcadApplication) object model, then the top level of the AutoCAD Civil (IAeccApplication) object model.

With the dump lists, I can either use/invoke/run one of the listed methods (guessing or researching or relying on error messages to guide me) or explore further into one of the properties. Let's see what we can find in the Civil active document.


(VLAX-DUMP-OBJECT (vlax-get-property AECCAPP
'ActiveDocument) T)


Wow! That worked and I got another long list. Let's try it again.


(VLAX-DUMP-OBJECT (vlax-get-property
(vlax-get-property AECCAPP 'ActiveDocument) 'ModelSpace) T)


Okay. Now I see a method called AddCircle. Let's try it out.

(VLAX-DUMP-OBJECT (vla-AddCircle
(vlax-get-property (vlax-get-property AECCAPP 'ActiveDocument) 'ModelSpace) '(0 0 0) 1) T)


Hmm. An error.


; error: lisp value has no coercion to VARIANT with this type: (0 0 0)


We probably have to turn the LISP point into a VB type point. *read help*
Okay. I found something. Let's try this: (vlax-3D-point list) or (vlax-3D-point x y [z])

(VLAX-DUMP-OBJECT (vla-AddCircle (vlax-get-property (vlax-get-property AECCAPP 'ActiveDocument) 'ModelSpace) (vlax-3D-point 0 0 0) 1) T)


Whoa! It drew a circle. Not bad.

So, even though the ModelSpace property of the ActiveDocument was read only (RO), there were things we could do inside it. Lots of things! The rest is all exploration and experimentation with the help file. Now to do the same thing with Python. I better go check my Python install download.

No comments: