Lisp Routine That Automatically Adds MTEXT of AEC Door and Window Sizes

Lisp Routine That Automatically Adds MTEXT of AEC Door and Window Sizes

jeff_Moskovciak
Enthusiast Enthusiast
685 Views
8 Replies
Message 1 of 9

Lisp Routine That Automatically Adds MTEXT of AEC Door and Window Sizes

jeff_Moskovciak
Enthusiast
Enthusiast

Hi, I am trying to write a routine that will automatically add door and window tags with the sizes, that is also edit-able if I need to revise to say "Per Elevation", for example. Here is what I have and I cannot get it to work:

 

(defun c:AddWindowDoorSizes (/ doc modelSpace windows doors windowObj doorObj width height insertPoint mtextObj sizeText)
  ;; Get the active document
  (setq doc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
 
  ;; Get ModelSpace
  (setq modelSpace (vla-get-ModelSpace doc))
 
  ;; Loop through all entities in ModelSpace
  (vlax-for obj modelSpace
    (setq entityType (cdr (assoc 0 (entget (vlax-vla-object->ename obj)))))
   
    ;; Check for AEC windows
    (if (equal entityType "AEC_WINDOW")
      (progn
        (setq windowObj (vlax-vla-object->vla-object obj))
       
        ;; Get width and height
        (setq width (vla-get-Width windowObj))
        (setq height (vla-get-Height windowObj))
       
        ;; Ensure width and height are valid
        (if (and (numberp width) (numberp height))
          (progn
            ;; Get insertion point
            (setq insertPoint (vlax-get windowObj 'InsertionPoint))
            ;; Create the size text
            (setq sizeText (strcat (rtos width 2 0) " x " (rtos height 2 0)))
            ;; Add MText to ModelSpace
            (setq mtextObj (vla-AddMText modelSpace
                                          (vlax-3d-point (car insertPoint) (+ (cadr insertPoint) 100) 0)  ;; Offset above the window
                                          0  ;; Automatic width
                                          sizeText))  ;; Size text
            ;; Set MText properties
            (vla-put-Height mtextObj 2.5)  ;; Height of MText
            (vla-put-Justification mtextObj acMTextCenter)  ;; Center justification
            (vla-put-Layer mtextObj "0")  ;; Set layer (adjust if necessary)
          )
        )
      )
    )
   
    ;; Check for AEC doors
    (if (equal entityType "AEC_DOOR")
      (progn
        (setq doorObj (vlax-vla-object->vla-object obj))
       
        ;; Get width and height
        (setq width (vla-get-Width doorObj))
        (setq height (vla-get-Height doorObj))
       
        ;; Ensure width and height are valid
        (if (and (numberp width) (numberp height))
          (progn
            ;; Get insertion point
            (setq insertPoint (vlax-get doorObj 'InsertionPoint))
            ;; Create the size text
            (setq sizeText (strcat (rtos width 2 0) " x " (rtos height 2 0)))
            ;; Add MText to ModelSpace
            (setq mtextObj (vla-AddMText modelSpace
                                          (vlax-3d-point (car insertPoint) (+ (cadr insertPoint) 100) 0)  ;; Offset above the door
                                          0  ;; Automatic width
                                          sizeText))  ;; Size text
            ;; Set MText properties
            (vla-put-Height mtextObj 2.5)  ;; Height of MText
            (vla-put-Justification mtextObj acMTextCenter)  ;; Center justification
            (vla-put-Layer mtextObj "0")  ;; Set layer (adjust if necessary)
          )
        )
      )
    )
  )
 
  (princ "\nWindow and Door sizes added as text.")
  (princ)
)

(princ "\nType 'AddWindowDoorSizes' to add size labels to all AEC windows and doors.")
(princ)
 
 
Thank you. 
0 Likes
686 Views
8 Replies
Replies (8)
Message 2 of 9

MrJSmith
Advocate
Advocate

I've not messed with such objects, but it appears to be fine if it works? Not sure what isn't working. However, the ways you attempted to solve the problem seem a little odd. Could have just used an SSGET of AEC_WINDOW and skipped the whole translating to entity.

 

I'd recommend picking one, LISP or ActiveX, and writing the code only in that. It is usually possible in 95% of cases and this one appears basic enough.

0 Likes
Message 3 of 9

Sea-Haven
Mentor
Mentor

It looks like the code is just repeated for either a door or window, so why not use 

(if (or (equal entityType "AEC_DOOR")(equal entityType "AEC_WINDOW"))

As mentioned using VL it will return a vl name of object eg AcDbLIne.

 (vlax-get obj 'objectname)
0 Likes
Message 4 of 9

jeff_Moskovciak
Enthusiast
Enthusiast

I will try that. The problem is I can't get the MText to be created. It says in the command line that it is finished, but the text doesn't display. Here is a revised version of the code:

 

(defun c:AddWindowDoorSizes (/ doc modelSpace obj entityType windowObj doorObj width height insertPoint mtextObj sizeText)
;; Get the active document
(setq doc (vla-get-ActiveDocument (vlax-get-Acad-Object)))

;; Get ModelSpace
(setq modelSpace (vla-get-ModelSpace doc))

;; Loop through all entities in ModelSpace
(vlax-for obj modelSpace
(setq entityType (vla-get-ObjectName obj))

;; Check for AEC windows
(if (equal entityType "AEC_WINDOW")
(progn
(setq windowObj obj)

;; Get width and height
(setq width (vla-get-Width windowObj))
(setq height (vla-get-Height windowObj))

;; Ensure width and height are valid
(if (and (numberp width) (numberp height))
(progn
;; Get insertion point
(setq insertPoint (vlax-get windowObj 'InsertionPoint))
;; Create the size text
(setq sizeText (strcat (rtos width 2 0) " x " (rtos height 2 0)))
;; Add MText to ModelSpace
(setq mtextObj (vla-AddMText modelSpace
(vlax-3d-point (car insertPoint) (+ (cadr insertPoint) 100) 0) ;; Offset above the window
0 ;; Automatic width
sizeText)) ;; Size text
;; Set MText properties
(vla-put-Height mtextObj 2.5) ;; Height of MText
(vla-put-Justification mtextObj acMTextCenter) ;; Center justification
(vla-put-Layer mtextObj "0") ;; Set layer (adjust if necessary)
)
)
)
)

;; Check for AEC doors
(if (equal entityType "AEC_DOOR")
(progn
(setq doorObj obj)

;; Get width and height
(setq width (vla-get-Width doorObj))
(setq height (vla-get-Height doorObj))

;; Ensure width and height are valid
(if (and (numberp width) (numberp height))
(progn
;; Get insertion point
(setq insertPoint (vlax-get doorObj 'InsertionPoint))
;; Create the size text
(setq sizeText (strcat (rtos width 2 0) " x " (rtos height 2 0)))
;; Add MText to ModelSpace
(setq mtextObj (vla-AddMText modelSpace
(vlax-3d-point (car insertPoint) (+ (cadr insertPoint) 100) 0) ;; Offset above the door
0 ;; Automatic width
sizeText)) ;; Size text
;; Set MText properties
(vla-put-Height mtextObj 2.5) ;; Height of MText
(vla-put-Justification mtextObj acMTextCenter) ;; Center justification
(vla-put-Layer mtextObj "0") ;; Set layer (adjust if necessary)
)
)
)
)
)

(princ "\nWindow and Door sizes added as text.")
(princ)
)

(princ "\nType 'AddWindowDoorSizes' to add size labels to all AEC windows and doors.")
(princ)

0 Likes
Message 5 of 9

ronjonp
Mentor
Mentor

@jeff_Moskovciak 

One issue I see is in this line: (vla-put-justification mtextobj acmtextcenter) Mtext does not have this property and 'acmtextcenter' does not exist.

 

Try this instead:  (vla-put-attachmentpoint mtextobj acattachmentpointmiddlecenter)

 

You could also use WCMATCH to check for doors and windows at once to remove the duplicated code:

 

 

(defun c:addwindowdoorsizes
       (/ doc entitytype height insertpoint modelspace mtextobj sizetext width windowobj)
  ;; Get the active document
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  ;; Get ModelSpace
  (setq modelspace (vla-get-modelspace doc))
  ;; Loop through all entities in ModelSpace
  (vlax-for obj	modelspace
    (setq entitytype (vla-get-objectname obj))
    ;; Check for AEC windows
    (if	(wcmatch entitytype "AEC_WINDOW,AEC_DOOR")
      (progn (setq windowobj obj)
	     ;; Get width and height
	     (setq width (vla-get-width windowobj))
	     (setq height (vla-get-height windowobj))
	     ;; Ensure width and height are valid
	     (if (and (numberp width) (numberp height))
	       (progn ;; Get insertion point
		      (setq insertpoint (vlax-get windowobj 'insertionpoint))
		      ;; Create the size text
		      (setq sizetext (strcat (rtos width 2 0) " x " (rtos height 2 0)))
		      ;; Add MText to ModelSpace
		      (setq mtextobj (vla-addmtext
				       modelspace
				       (vlax-3d-point (car insertpoint) (+ (cadr insertpoint) 100) 0)
				       ;; Offset above the window
				       0
				       ;; Automatic width
				       sizetext
				     )
		      )
		      ;; Size text
		      ;; Set MText properties
		      (vla-put-height mtextobj 2.5)
		      ;; Height of MText
		      (vla-put-attachmentpoint mtextobj acattachmentpointmiddlecenter)
		      ;; Center justification
		      (vla-put-layer mtextobj "0")
		      ;; Set layer (adjust if necessary)
	       )
	     )
      )
    )
  )
  (princ "\nWindow and Door sizes added as text.")
  (princ)
)

(princ "\nType 'AddWindowDoorSizes' to add size labels to all AEC windows and doors.")
(princ)

 

0 Likes
Message 6 of 9

jeff_Moskovciak
Enthusiast
Enthusiast

That was a good suggestion. Unfortunately, it still doesn't create the Mtext and it completes the program saying it was added.

0 Likes
Message 7 of 9

ronjonp
Mentor
Mentor

@jeff_Moskovciak wrote:

That was a good suggestion. Unfortunately, it still doesn't create the Mtext and it completes the program saying it was added.


Weird .. When I hardcode the values in and run it on a block the mtext is created 100 units above the block:

ronjonp_0-1728493064912.png

 

				     ;; Maybe change this:
				     (vlax-3d-point (car insertpoint) (+ (cadr insertpoint) 100) 0)
				     ;; To this?
				     (vlax-3d-point (car insertpoint) (+ (cadr insertpoint) height) 0)

 

 

0 Likes
Message 8 of 9

jeff_Moskovciak
Enthusiast
Enthusiast

Can you test the code on an AEC wall or window and see what result you get?

0 Likes
Message 9 of 9

ronjonp
Mentor
Mentor

@jeff_Moskovciak wrote:

Can you test the code on an AEC wall or window and see what result you get?


I'm running vanilla AutoCAD so I can't test.

 

You might also try this ..

 

 

    ;; Change this
    (setq entitytype (vla-get-objectname obj))
    ;; To this
    (setq entitytype (cdr (assoc 0 (entget (vlax-vla-object->ename obj)))))

 

 

Use this code to dump the VLA properties of your windows and doors. This way you can make sure you're using the correct functions:

 

(defun c:vlaxprop (/ e)
  (if (setq e (car (entsel "\nSelect object to show data: ")))
    (vlax-dump-object (vlax-ename->vla-object e) t)
  )
  (textscr)
)

 

Did you see this?

 

 

0 Likes