LISP needed for closed areas

LISP needed for closed areas

JB-T
Enthusiast Enthusiast
2,700 Views
14 Replies
Message 1 of 15

LISP needed for closed areas

JB-T
Enthusiast
Enthusiast

Hello all,

 

This is my first post here but I come on the site weekly since the last 7 years to gather some tips or lisp files.

 

As part of my job, I often have to make the same manipulations several times in AutoCAD.

 

These operations consist in adding a perimeter to a closed area (Boundary command) and then using a random lisp file I found on your site to select this boundary and to annotate the area (square meters) of the closed area.

 

I wish I could find an AutoLISP file that would allow me, by clicking once in a closed area, to create the perimeter and at the same time to place a text indicating the area (square meters) of this closed area.

 

Can someone give me the link of such a file or guiding me through the construction of a Lisp that could fulfill my needs?

 

Thanks a lot and have a great day!

0 Likes
Accepted solutions (3)
2,701 Views
14 Replies
Replies (14)
Message 2 of 15

hmsilva
Mentor
Mentor

Hello JB-T and welcome to the Autodesk Community!

 

Quick and dirty, and as a strating point...

 

(vl-load-com)
(defun c:demo ( / area ent lst obj pt)
  (if (and (setq lst (entlast))
           (setq pt (getpoint "\nSpecify internal point: "))
           (vl-cmdf "_.-boundary" pt "")
           (setq ent (entlast))
           (not (eq lst ent))
      )
    (progn
      (setq obj  (vlax-ename->vla-object ent)
            area (vla-get-area obj)
      )
      (entmake (list
                 '(0 . "TEXT")
                 (cons 10 pt)
                 (cons 40 (getvar 'TEXTSIZE))
                 (cons 1 (strcat (rtos area 2 2) " m2"))
               )
      )
    )
  )
  (princ)
)

 

 

Hope this helps,
Henrique

EESignature

0 Likes
Message 3 of 15

JB-T
Enthusiast
Enthusiast

Hello!

 

This little script you gave me is truly awesome Henrique! Thanks alot!

 

I was wondering how we could simply modify this script so that the routine could stay in the command after I clicked in the first closed area, ready for another click. With this modification I would be able to "click-mouse pan-click [...]" without having to press enter each time before clicking.

 

Thanks alot for your help it is really appreciate!

0 Likes
Message 4 of 15

hmsilva
Mentor
Mentor
Accepted solution

@JB-T wrote:

Hello!

This little script you gave me is truly awesome Henrique! Thanks alot!

I was wondering how we could simply modify this script so that the routine could stay in the command after I clicked in the first closed area, ready for another click. With this modification I would be able to "click-mouse pan-click [...]" without having to press enter each time before clicking.

Thanks alot for your help it is really appreciate!


You're welcome, JB-T
Glad I could help!
Code revised...
(vl-load-com)
(defun c:demo (/ area ent lst obj pt)
  (while (and (setq lst (entlast))
              (setq pt (getpoint "\nSpecify internal point: "))
              (vl-cmdf "_.-boundary" pt "")
              (setq ent (entlast))
              (not (eq lst ent))
         )
    (setq obj  (vlax-ename->vla-object ent)
          area (vla-get-area obj)
    )
    (entmake (list
               '(0 . "TEXT")
               (cons 10 (trans pt 1 0))
               (cons 40 (getvar 'TEXTSIZE))
               (cons 1 (strcat (rtos area 2 2) " m2"))
               (cons 50 (angle '(0.0 0.0) (getvar 'UCSXDIR)))
             )
    )
  )
  (princ)
)
Henrique

 

EESignature

Message 5 of 15

JB-T
Enthusiast
Enthusiast

Hello!

 

After a few days of use, I can tell you that I saved a lot of time using this routine! Thanks to Henrique!

 

I noticed two points that I would like to adjust in order to improve the operation of this routine for the future.

 

First, it would be useful if the routine could ask for the text height that we want to use for the annotations, when we invoke the command.

 

Also, I found out that AutoCAD exits the routine if we click in a non-closed area or on an element such as a line, which can happen sometimes when I go fast. Surprisingly the first version of the script didn’t have this “issue”.

 

Are these improvements possible?

 

Thank you very much and have a good day!

0 Likes
Message 6 of 15

hmsilva
Mentor
Mentor
Accepted solution

Something like this, perhaps...

 

(vl-load-com)
(defun c:demo (/ area ent flag lst obj pt tmpH)
  (if (or (not *Hscl*) (/= (type *Hscl*) 'REAL))
    (setq *Hscl* (getvar 'TEXTSIZE))
  )
  (initget 6)
  (setq tmpH (getreal (strcat "\nSpecify Text Height: <" (rtos *Hscl*) ">: ")))
  (if (/= tmpH nil)
    (setq *Hscl* tmpH)
  )
  (while (null flag)
    (cond ((setq pt (getpoint "\nSpecify internal point <exit>: "))
           (if (and (setq lst (entlast))
                    (vl-cmdf "_.-boundary" pt "")
                    (setq ent (entlast))
                    (not (eq lst ent))
               )
             (progn
               (setq obj  (vlax-ename->vla-object ent)
                     area (vla-get-area obj)
               )
               (entmake (list
                          '(0 . "TEXT")
                          (cons 10 (trans pt 1 0))
                          (cons 40 *Hscl*)
                          (cons 1 (strcat (rtos area 2 2) " m2"))
                          (cons 50 (angle '(0.0 0.0) (getvar 'UCSXDIR)))
                        )
               )
             )
           )
          )
          (T
           (setq flag T)
          )
    )
  )
  (princ)
)

 

Hope this helps,
Henrique

EESignature

Message 7 of 15

JB-T
Enthusiast
Enthusiast

Hello,

 

Thank you Henrique for the last version! 

 

I have been using it during the past week and it works pretty well, saved me a lot of time.

 

I noted a couple of improvements that I would like to bring to this wonderful routine if it is possible :

 

1 - I would like the routine to disable Osnap when it starts. However, It would not Clear all the prefered Object Snap modes.

 

2 - I noticed that sometimes after using the routine, the Lasso selection method becomes enabled. Is there something in this Lisp that could explain a change in the selection mode? If yes, could it be modify to stop it to be enabled?

 

3 - I don't know it is possible, but I would like to have the insertion point of the text zone in its center instead of having it in the left down corner.

 

4 - Finally, I would like to know how I can modify the routine if I decide to use a comma instead of a point to separate the decimals and to remove the "m2" of the annotation.

 

Thank you again for your time, I really appreciate your help!

 

JBT

0 Likes
Message 8 of 15

hmsilva
Mentor
Mentor

Hi JBT,
you're welcome!

I'm with an old laptop and a very old AutoCAD version, so I can't test 'the Lasso selection method becomes enabled', only next week...but I can not understand why it becomes enabled...

 

(vl-load-com)
(defun c:demo (/ *error* area ent lst obj osm pt tmpH)

  (defun *error* (msg)
    (if osm
      (setvar 'OSMODE osm)
    )
    (cond ((not msg))
          ((member msg '("Function cancelled" "quit / exit abort")))
          ((princ (strcat "\n** Error: " msg " ** ")))
    )
    (princ)
  )

  (setq osm (getvar 'OSMODE))
  (setvar 'OSMODE (+ osm 16384))
  (if (or (not *Hscl*) (/= (type *Hscl*) 'REAL))
    (setq *Hscl* (getvar 'TEXTSIZE))
  )
  (initget 6)
  (setq tmpH (getreal (strcat "\nSpecify Text Height: <" (rtos *Hscl*) ">: ")))
  (if (/= tmpH nil)
    (setq *Hscl* tmpH)
  )
  (while (and (setq lst (entlast))
              (setq pt (getpoint "\nSpecify internal point: "))
              (vl-cmdf "_.-boundary" pt "")
              (setq ent (entlast))
              (not (eq lst ent))
         )
    (setq obj  (vlax-ename->vla-object ent)
          area (vla-get-area obj)
    )
    (entmake (list
               '(0 . "TEXT")
               '(10 0.0 0.0 0.0)
               (cons 40 *Hscl*)
               (cons 1 (strcat (rtos area 2 2) " m2"))
               (cons 50 (angle '(0.0 0.0) (getvar 'UCSXDIR)))
               '(72 . 1)
               (cons 11 (trans pt 1 0))
               '(73 . 2)
             )
    )
  )
  (*error* nil)
  (princ)
)

 

The text is justified to 'middle center', if you need to justify to 'center', change the (73 . 2) to (73 . 0)
To remove the "m2" of the annotation, just change the (cons 1 (strcat (rtos area 2 2) " m2")) to (cons 1 (rtos area 2 2))
To change the point to a comma, change the (cons 1 (rtos area 2 2)) to (cons 1 (vl-string-subst "," "." (rtos area 2 2)))

 

Hope this helps,
Henrique

EESignature

0 Likes
Message 9 of 15

JB-T
Enthusiast
Enthusiast

Hi,

 

I have been using this awesome routine for a year now and I have notice an issue with OSMODE.

 

 

Every now and then I receive this message, when I try to launch the routine by typing the command :

 

** Error : variable setting rejected : OSMODE 35361 **

 

The 5-digits number at the end varies all the time.

 

 

I noticed that when it happens, I just have to enable 2D OSNAP from my bottom bar and then it is possible for me to launch the routine properly.

 

 

Here is the code I use, with minor adjustements from hmsilva latest version.

 

(vl-load-com)
(defun c:plani (/ *error* area ent lst obj osm pt tmpH)
(defun *error* (msg)
(if osm
(setvar 'OSMODE osm)
)
(cond ((not msg))
((member msg '("Function cancelled" "quit / exit abort")))
((princ (strcat "\n** Error: " msg " ** ")))
)
(princ)
)
(setq osm (getvar 'OSMODE))
(setvar 'OSMODE (+ osm 16384))
(if (or (not *Hscl*) (/= (type *Hscl*) 'REAL))
(setq *Hscl* (getvar 'TEXTSIZE))
)
(initget 6)
(setq tmpH (getreal (strcat "\nSpecify Text Height: <" (rtos *Hscl*) ">: ")))
(if (/= tmpH nil)
(setq *Hscl* tmpH)
)
(while (and (setq lst (entlast))
(setq pt (getpoint "\nSpecify internal point: "))
(vl-cmdf "_.-boundary" pt "")
(setq ent (entlast))
(not (eq lst ent))
)
(setq obj (vlax-ename->vla-object ent)
area (vla-get-area obj)
)
(entmake (list
'(0 . "TEXT")
'(10 0.0 0.0 0.0)
(cons 40 *Hscl*)
(cons 1 (strcat (vl-string-subst "," "." (rtos area 2 2))))
(cons 50 (angle '(0.0 0.0) (getvar 'UCSXDIR)))
'(72 . 1)
(cons 11 (trans pt 1 0))
'(73 . 2)
)
)
)
(*error* nil)
(princ)
)

 

Can someone help me fix the problem?

 

 

Thank you for your time !

0 Likes
Message 10 of 15

pbejse
Mentor
Mentor

Look into  what the system variable OSOPTIONS  current value when the program is not showing the error. then include that on the routine, see if that error goes away.

 

 

(if	osm
      (mapcar 
	'setvar 
	  '("OSMODE" "OSOPTIONS")
	    (list osm oso )
	    )
    )

....

 (setq osm (getvar 'OSMODE)
        oso (getvar 'OSOPTIONS))
    
  (setvar 'OSMODE (+ osm 16384))
  (setvar 'OSOPTIONS 4) ;<-- your preferred value

...

Not  tested it as i can't seem to reproduce that same error on my pc.

 

HTH

 

 

Message 11 of 15

Ranjit_Singh
Advisor
Advisor
Accepted solution

when you pass (setvar 'OSMODE (+ osm 16384)), this will turn off object snap (similar to hitting F3 key).However, in the current code you posted there is no check done to see if object snap is already off (anytime the osmode variable is higher than 16384, it means 2D object snap is off).

 

Try replacing

(setvar 'OSMODE (+ osm 16384))

with

 

(if (< osm 16384) (setvar 'osmode (+ osm 16384)))
Message 12 of 15

pbejse
Mentor
Mentor

@Ranjit_Singh wrote:

....the osmode variable is higher than 16384, it means 2D object snap is off) ...

 


That makes a whole lot of sense. 

 

0 Likes
Message 13 of 15

JB-T
Enthusiast
Enthusiast

Thank you to both contributors, this fixed my problem.

 

Have a good day !

0 Likes
Message 14 of 15

JB-T
Enthusiast
Enthusiast

Hi,

I have been using the following routine alot in the last 6 years. It is trully awesome, I will never thank you guys enough for it, but I would like to modify a detail in order to gain productivity.

When I click in a "seem-to-be-closed-area",  and it happens that this area is not really closed, AutoCAD exits the command and I have to invoke it again.

Can you guys modify the routine in order that AutoCAD won't exit the command when I click in a non-closed area ?

Thanks alot !

 

(vl-load-com)
(defun c:planii (/ *error* area ent lst obj osm pt tmpH)

(defun *Erreur* (msg)
(if osm
(setvar 'OSMODE osm)
)
(cond ((not msg))
((member msg '("Fonction annulée" "quit / exit abort")))
((princ (strcat "\n** Erreur: " msg " ** ")))
)
(princ)
)

(setq osm (getvar 'OSMODE))
(if (< osm 16384) (setvar 'osmode (+ osm 16384)))
(if (or (not *Hscl*) (/= (type *Hscl*) 'REAL))
(setq *Hscl* (getvar 'TEXTSIZE))
)
(initget 6)
(setq tmpH (getreal (strcat "\nEntrer la hauteur de texte à utiliser <" (rtos *Hscl*) ">: ")))
(if (/= tmpH nil)
(setq *Hscl* tmpH)
)
(while (and (setq lst (entlast))
(setq pt (getpoint "\nCliquer dans la zone à mesurer "))
(vl-cmdf "_.-boundary" pt "")
(setq ent (entlast))
(not (eq lst ent))
)
(setq obj (vlax-ename->vla-object ent)
area (vla-get-area obj)
)
(entmake (list
'(0 . "TEXT")
'(10 0.0 0.0 0.0)
(cons 40 *Hscl*)
(cons 1 (strcat (vl-string-subst "," "." (rtos area 2 2))))
(cons 50 (angle '(0.0 0.0) (getvar 'UCSXDIR)))
'(72 . 1)
(cons 11 (trans pt 1 0))
'(73 . 2)
)
)
)
(*Erreur* nil)
(princ)
)

0 Likes
Message 15 of 15

marko_ribar
Advisor
Advisor

Comment this line :

 

(not (eq lst ent))

 

(just put ; in front)

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes