LISP to select all doors and change swing angle

LISP to select all doors and change swing angle

jose.paredes9CU28
Contributor Contributor
1,419 Views
10 Replies
Message 1 of 11

LISP to select all doors and change swing angle

jose.paredes9CU28
Contributor
Contributor

Hi guys,

 

I'm looking for a LISP routine to select all doors (dynamic AEC objects in AutoCAD Architecture) in an open drawing, and then change their swing angle to 30°. Is this possible?

0 Likes
Accepted solutions (1)
1,420 Views
10 Replies
Replies (10)
Message 2 of 11

dbroad
Mentor
Mentor

Would this be worth the effort over just selecting the doors and using the property palette?  How often would this need to be done?

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 3 of 11

David_W_Koch
Mentor
Mentor

I agree with @dbroad with regard to simply selecting all of the Doors and using the Properties palette to set the value of all of them at once, if this is a semi-occasional thing and is an independent action.  But if this on one step in a multi-step process that you apply when converting, say, a new-work file to an existing-conditions file, for use in later renovation work, and you are trying to automate the entire process, then I can see the value in such a routine.

 

Unfortunately, it is not as simple as grabbing all of the Doors and changing the SwingAngle property.  It appears that Doors of any Door Types have that property and it is not marked as being read-only or otherwise not editable, but attempting to set the value on all but five of the twenty types results in an error.  Sorting those out will require more time than I have at the moment.  (The Door Type is a property of the Door Style, not the Door object.)

 

If using the Properties palette works for your purposes, let us know (and give Doug the solution credit), and I will put this on my pile of interesting things to do when I finally get some free time.  If not, let me know and I will try to find time to work on it - no promises on a completion time, though.


David Koch
AutoCAD Architecture and Revit User
Blog | LinkedIn
EESignature

0 Likes
Message 4 of 11

David_W_Koch
Mentor
Mentor
Accepted solution

After taking a quick look at what would have to be done, it turned out to not be all that difficult, and I decided to just finish this effort now.  Keep in mind that only the Single, Double, Double Opposing, Uneven and Uneven Opposing types of Doors will be affected.  It makes sense to me that non-swinging types would not make use of the SwingAngle property; I was surprised to find that the "Dhung" types (Single-Dhung, Double-Dhung, Uneven-Dhung) and the Communicating type do not support SwingAngle, as these are swinging doors.  Those four types do support Opening percent, so perhaps the below could be extended to modify that property for those types of Doors.

 

Anyway, here is the code, as it stands, that will modify the SwingAngle property for the five supported Door Types:

(defun C:DRSW (                         ; No arguments.
               /
                iCount                  ; Loop counter [integer].
                iDType                  ; Door Type [integer].
                iMax                    ; Total number of Doors in file [integer].
                iProc                   ; Number of Doors processed [integer].
                objDoor                 ; Door object being processed.
                objDStyle               ; Door Style of the object being processed.
                ss1                     ; All Doors in the file [selection set].
              ) ;_ End arguments and local variables.
  (vl-load-com)
  (setq        ss1 (ssget "_X" '((0 . "AEC_DOOR"))))
  (cond
    ((not ss1)                          ; No Doors in drawing.
     (alert "Drawing file has no Door objects.\nNothing to do!")
    ) ;_ End condition A1.
    (T                                  ; Else, continue.
     (setq iMax          (sslength ss1)
           iCount 0
           iProc  0
     ) ;_ End setq.
     (while (< iCount iMax)
       (setq objDoor    (vlax-ename->vla-object (ssname ss1 iCount))
	     objDStyle	(vlax-get-property objDoor 'Style)
	     iDType	(vlax-get-property objDStyle 'Type)
       ) ;_ End setq.
       (if (or
	     (= iDType 1)
	     (= iDType 2)
	     (= iDType 5)
	     (= iDType 6)
	     (= iDType 8)
	   ) ;_ End or.
	 (progn
	   (vlax-put-property objDoor 'SwingAngle 30.0)
	   (setq iProc (1+ iProc))
	 ) ;_ End progn.
       ) ;_ End if.
       (setq iCount (1+ iCount))
     ) ;_ End while.
    ) ;_ End condition A2.
  ) ;_ End cond A.
  (prompt
    (strcat
      "\nDRSW function completed:  "
      (itoa iProc)
      " Door(s) of "
      (itoa iCount)
      " total Door(s) processed. "
    ) ;_ End strcat.
  ) ;_ End prompt.
  (prin1)
) ;_ End C:DRSW.

 

I hope that helps.


David Koch
AutoCAD Architecture and Revit User
Blog | LinkedIn
EESignature

0 Likes
Message 5 of 11

David_W_Koch
Mentor
Mentor

Just in case there was any question as to whether or not I have a life, here is an amended version that will also process the three Dhung types and the Communicating types by changing the OpenPercent value to 16 (which is close to 30 degrees).

(defun C:DRSW (                         ; No arguments.
               /
                iCount                  ; Loop counter [integer].
                iDType                  ; Door Type [integer].
                iMax                    ; Total number of Doors in file [integer].
                iProc                   ; Number of Doors processed [integer].
                objDoor                 ; Door object being processed.
                objDStyle               ; Door Style of the object being processed.
                ss1                     ; All Doors in the file [selection set].
              ) ;_ End arguments and local variables.
  (vl-load-com)
  (setq        ss1 (ssget "_X" '((0 . "AEC_DOOR"))))
  (cond
    ((not ss1)                          ; No Doors in drawing.
     (alert "Drawing file has no Door objects.\nNothing to do!")
    ) ;_ End condition A1.
    (T                                  ; Else, continue.
     (setq iMax          (sslength ss1)
           iCount 0
           iProc  0
     ) ;_ End setq.
     (while (< iCount iMax)
       (setq objDoor    (vlax-ename->vla-object (ssname ss1 iCount))
	     objDStyle	(vlax-get-property objDoor 'Style)
	     iDType	(vlax-get-property objDStyle 'Type)
       ) ;_ End setq.
       (if (or
	     (= iDType 1)
	     (= iDType 2)
	     (= iDType 5)
	     (= iDType 6)
	     (= iDType 8)
	   ) ;_ End or.
	 (progn
	   (vlax-put-property objDoor 'SwingAngle 30)
	   (setq iProc (1+ iProc))
	 ) ;_ End progn.
	 (if (or
	     (= iDType 3)
	     (= iDType 4)
	     (= iDType 7)
	     (= iDType 20)
	   ) ;_ End or.
	   (progn
	     (vlax-put-property objDoor 'OpenPercent 16)
	     (setq iProc (1+ iProc))
	   ) ;_ End progn.
	 ) ;_ End if.
       ) ;_ End if.
       (setq iCount (1+ iCount))
     ) ;_ End while.
    ) ;_ End condition A2.
  ) ;_ End cond A.
  (prompt
    (strcat
      "\nDRSW function completed:  "
      (itoa iProc)
      " Door(s) of "
      (itoa iCount)
      " total Door(s) processed. "
    ) ;_ End strcat.
  ) ;_ End prompt.
  (prin1)
) ;_ End C:DRSW.

David Koch
AutoCAD Architecture and Revit User
Blog | LinkedIn
EESignature

Message 6 of 11

dbroad
Mentor
Mentor

David,

You need to get out more. I spent the weekend with children and grandchildren.  Beat's coding.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 7 of 11

jose.paredes9CU28
Contributor
Contributor

Hi David. It works as a charm! Thank you for your effort.

0 Likes
Message 8 of 11

dbroad
Mentor
Mentor

Not that it's important, David, but instead of selecting by idtype, you could just determine if the property is available before setting it.

 

(if (vlax-property-available-p objDoor 'SwingAngle)

  (vlax-put objDoor 'SwingAngle 30))

 

and the similar with 'OpeningPercent.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 9 of 11

David_W_Koch
Mentor
Mentor

@dbroad 

I tried that first.  The SwingAngle property is available on all types.  I even included a "T" at the end for the check-modify argument, in which case it should return nil if the property is available but not modifiable.  As soon as one of the non-swing doors was included, I got an unspecified automation error.  (OpeningPercent is also available on all types, but I only wanted to change it on the swinging Door Types that did not accept a SwingAngle value.)


David Koch
AutoCAD Architecture and Revit User
Blog | LinkedIn
EESignature

0 Likes
Message 10 of 11

dbroad
Mentor
Mentor

Then your way is certainly the best.  Alternatively a Q&D approach in the loop might be to ignore the errors.

(vl-catch-all-apply
  '(lambda (obj) (vlax-put-property obj 'swingangle 30))
  (list objdoor))
(vl-catch-all-apply
  '(lambda (obj) (vlax-put-property obj 'openpercent 16))
  (list objdoor))

or define a function to safely put properties that might cause errors.

(defun safeputproperty (object property value)
  (vl-catch-all-apply
  'vlax-put-property (list object property value)))

and then call it as necessary in the loop

(safeputproperty doorobj 'swingangle 30) 

(safeputproperty doorobj 'openpercent 16)

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 11 of 11

David_W_Koch
Mentor
Mentor

@dbroad 

Interesting, and thanks for the examples.  Error handling is not an area with which I have a lot of experience in AutoLISP in general, and in the VLAX functions particularly (other than writing the routine to avoid the error conditions, of course).


David Koch
AutoCAD Architecture and Revit User
Blog | LinkedIn
EESignature

0 Likes