Accessing Civil 3D objects with autolisp

I have been working with the Civil 3D 2010 API in visual lisp recently, and I thought I would share an example of working with an alignment object. This example has plenty of comments, but basically it shows you how to find a point near the alignment based on a station and offset. Then it does the opposite and shows you how to determine the station and offset, given a point. For clarity, I have left out most of the error checking.

; standard entity selection
(setq sel (entsel "\nSelect Alignment: "))
; get the entity name
(setq ent (car sel))
; get the entity list
(setq lst (entget ent))
; check to make sure the selection was the expected type
(if (eq "AECC_ALIGNMENT" (cdr (assoc 0 lst)))
  ; if so, convert the entity into a VLA-OBJECT
  (setq obj (vlax-ename->vla-object ent))
)
(if obj
  (progn
    ; get the name of the alignment
    (setq nam (vlax-get-property obj 'Name))
    ; get the start station
    (setq sta1 (vlax-get-property obj 'StartingStation))
    ; get the end station
    (setq sta2 (vlax-get-property obj 'EndingStation))
    ; set a couple of variables
    (setq sta 100.0 off 10.0)
    ; using the above variables, find this point on the alignment
    (vlax-invoke-method obj 'PointLocation sta off 'x 'y)
    ; create an AutoCAD point at this location
    (entmake (list (cons 0 "POINT")(cons 10 (list x y))))
    ; ask the user to pick a point
    (setq pt1 (getpoint "\nSelect point: "))
    ; find the station and offset for this point
    (vlax-invoke-method obj 'StationOffset (car pt1) (cadr pt1) 'sta 'off)
    ; inform the user
    (alert (strcat
            "The station is "
            (rtos sta 2 2)
            "\nThe offset is "
            (rtos off 2 2)))
  )
)

Comments

Simple.Very nice. Can you retrieve the profile elevation at that station as simple?

Adjusted to show elevation as well:

(defun c:test ()
(vl-load-com)
(setq sel (entsel "\nSelect Alignment: "))
(setq sel2 (entsel "\nSelect Profile: "))
(setq ent (car sel))
(setq lst (entget ent))
(if (eq "AECC_ALIGNMENT" (cdr (assoc 0 lst)))
(setq obj (vlax-ename->vla-object ent)))
(setq ent2 (car sel2))
(setq lst2 (entget ent2))
(setq obj2 (vlax-ename->vla-object ent2))
(if obj
  (progn
    (setq nam (vlax-get-property obj 'Name))
    (setq sta1 (vlax-get-property obj 'StartingStation))
    (setq sta2 (vlax-get-property obj 'EndingStation))
    (setq sta 100.0 off 10.0)
    (vlax-invoke-method obj 'PointLocation sta off 'x 'y)
    (entmake (list (cons 0 "POINT")(cons 10 (list x y))))
    (setq pt1 (getpoint "\nSelect point: "))
    (vlax-invoke-method obj 'StationOffset (car pt1) (cadr pt1) 'sta 'off)
(setq elev (vlax-invoke-method obj2 "ElevationAt" sta))
    (alert (strcat
        "The Elevation is "
            (rtos elev 2 2)
            "\nThe Station is "
            (rtos sta 2 2)
            "\nThe Offset is "
            (rtos off 2 2)))
  )
)
(princ));;; 

Can you tell me how I can create a new surface in Vlisp?

I know I can use something like this:

(vlax-invoke-method obj 'AddTinSurface )

But I don't know the exact format of the required (5) entries of the variant. I know it includes Name, Description, Layer, BaseLayer and Style (or StyleName).
How do I build this variant in Vlisp?

....somewhere, but I can't locate it now.

This is in VBA, but it may provide enough clues:
http://www.theswamp.org/index.php?topic=19980.0

I've found some working VisualLisp code over here: http://www.theswamp.org/index.php?topic=38301.0;all

(vl-load-com)
(setq prod (vlax-product-key))
(setq verstr (cond ((vl-string-search "\\R18.0\\" prod)
		    "7.0"
		   )
		   ;;2010
		   ((vl-string-search "\\R18.1\\" prod)
		    "8.0"
		   )
		   ;;2011
		   ((vl-string-search "\\R18.2\\" prod)
		    "9.0"
		   )
		   ;;2012
	     )
)
(setq prodStr (strcat "AeccXUiLand.AeccApplication." verstr))
(setq datastr (strcat "AeccXLand.AeccTinCreationData." verstr))

(if (and (setq *acad* (vlax-get-acad-object))
	(setq C3D (vla-getinterfaceobject *acad* prodStr))
	(setq C3Ddoc (vla-get-activedocument C3D))
	(setq surfs (vlax-get C3Ddoc 'surfaces))
	(setq tincreationdata 
          (vla-getinterfaceobject *acad* datastr)
         )
    )
  (progn
    (vlax-put tincreationdata 'baselayer "0")
    (vlax-put tincreationdata 'layer "0")
    (vlax-put tincreationdata 'description 
              "Surface from Lisp")
    (vlax-put tincreationdata 'name "Lisp EG")

     ;;style must exist!
    (vlax-put tincreationdata 'style "Border Only")

    (setq surf (vlax-invoke-method surfs 
               'addtinsurface tincreationdata))
    ;; do whatever else is needed
    (vlax-release-object tincreationdata)
    (vlax-release-object surf)
    (vlax-release-object surfs)
    (vlax-release-object c3ddoc)
  )
)

Did you want to get the elevation from the profile for a certain reason?
I was thinking you could just retrieve it from the surface....

How can I use the vlisp functions (like vlax-ename->vla-object) in Civil 3D 2011?

The sample code posted works in C3D 2011 also.

 


All content is copyright © CAD PANACEA 2005-2013 unless otherwise noted and may not be reproduced. All comments posted to this blog are the sole responsibility of the person making the comment.

Google, as a third party vendor, uses cookies to serve ads on this site. Google's use of their cookies enables it to serve ads to users based on their visit to your sites and other sites on the Internet. You may opt out of the use of these cookies by visiting the Google ad and content network privacy policy.

Powered by Drupal