TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: like_citrus on May 20, 2022, 10:36:49 AM

Title: LISP to draw circle and make block
Post by: like_citrus on May 20, 2022, 10:36:49 AM
I wanted to make this into a LISP:
- 1. Draw a circle (ask user for Diameter or Radius).
- 2. Place in a layer called "Fulcrum", the layer already exists.
- 3. Make it as a block using something similar to the code (mostly by others) below. The block goes in the currently used layer, typically "0".
- 4. Place the block by clicking the cursor at any point the screen. Prefer to snap to something if possible.

Understand it's a lot of work for a simple thing, but I typically draw this way, starting a block with a circle as an anchor point, and then editing in place.

Code: [Select]
(defun c:MakeBlock (/ bkn eee i ndx nm ssst st)
(if (and (setq ssst (ssget)) (setq st (getpoint "\nPick Base Point: ")))
(progn (setq ndx 0)
(setq time (rtos (getvar "CDATE") 2 6)) ; Format YYYYMMDD.HHMMSS
(setq year (substr time 3 2)) ; Two digits instead of four
(setq month (substr time 5 2))
(setq day (substr time 7 2))
(setq hour (substr time 10 2)) ; Increment of 3 from day to account for "." character
(setq minutes (substr time 12 2))
(setq seconds (substr time 14 2))
(while (tblobjname "block" (setq nm (strcat "Block-" year month day hour minutes seconds))))
(entmake (list '(0 . "BLOCK")
'(100 . "AcDbEntity")
'(67 . 0)
'(8 . "0")
'(100 . "AcDbBlockReference")
(cons 2 nm)
(cons 10 st)
'(70 . 0)
       )
)
(repeat (sslength ssst)
(entmake (cdr (entget (ssname ssst ndx))))
(entdel (ssname ssst ndx))
(setq ndx (+ 1 ndx))
)
(entmake '((0 . "ENDBLK") (100 . "AcDbBlockEnd") (8 . "0")))
(entmake (list (cons 0 "INSERT")
(cons 2 nm)
(cons 6 (getvar "CELTYPE"))
(cons 8 (getvar "CLAYER"))
(cons 66 0)
(cons 10 st)
(cons 41 1)
(cons 42 1)
(cons 43 1)
(cons 50 0)
(cons 71 0)
(cons 44 0)
(cons 45 0)
       )
)
)
)
(princ)
)
Title: Re: LISP to draw circle and make block
Post by: mhupp on May 20, 2022, 09:53:13 PM
You want to have multiple unique blocks? because that code is generating a random name every time its run.
why not just make a dynamic block that has the radius constrained when you insert it will ask for radius.

Title: Re: LISP to draw circle and make block
Post by: like_citrus on May 20, 2022, 10:25:24 PM
Quote
You want to have multiple unique blocks?
Yes they are all unique. That's the reason for the date stamp, may not be the best method but it works for me.

Quote
why not just make a dynamic block
A regular block is better, as I edit by "Edit block in place" command, and can see other objects in the background.
Title: Re: LISP to draw circle and make block
Post by: mhupp on May 22, 2022, 12:21:36 AM
Just making sure you wanted all unique blocks. This will ask for radius and center point. make the circle on Fulcrum layer. and then the block is created on the current layer.
this command runs until canceled either hit esc or skipping input on the radius or point.

Code - Auto/Visual Lisp: [Select]
  1. ;;----------------------------------------------------------------------;;
  2. ;; CREATE CIRCLE BLOCKS WITH UNIQUE NAME
  3. (defun c:CirBlock (/ rad pt blkname)
  4.   (setvar 'cmdecho 0)
  5.   (while (and (setq rad (getreal "\nCircle Radius: ")) (setq pt (getpoint "\nPick Center Point of Circle: ")))
  6.     (entmake (list '(0 . "CIRCLE") '(8 . "Fulcrum") (cons 10 pt) (cons 40 rad)))
  7.     (setq blkname (strcat "Block-" (menucmd "M=$(edtime, $(getvar,date),YYMODDHHMMSS)")))
  8.     (vl-cmdf "_.Block" blkname "_non" pt (entlast) "")
  9.     (vl-cmdf "_.Insert" blkname "_non" pt 1 1 0)
  10.     (prompt (strcat "\nBlock [" blkname "] Created"))
  11.   )
  12.   (setvar 'cmdecho 1)
  13.   (princ)
  14. )

--edit
if you just want to run once change the while to if
Title: Re: LISP to draw circle and make block
Post by: like_citrus on May 22, 2022, 08:19:27 PM
Hi, thanks this is getting close.

- How do you make it Escape automatically so it only runs once.
Is this what the "If" is supposed to do? If I change "While" to "If", it doesn't work, it says Unknown command.

- Also how do you place circle inside the block in the layer named Fulcrum. The block is in then in the current layer.
Title: Re: LISP to draw circle and make block
Post by: mhupp on May 22, 2022, 10:07:03 PM
Hi, thanks this is getting close.

- How do you make it Escape automatically so it only runs once.
Is this what the "If" is supposed to do? If I change "While" to "If", it doesn't work, it says Unknown command.

(if (and
only runs once if conditions are met
if you have more then one line of code you have to wrap it with (progn sorry forgot to mention that.
         

(while (and
run as long as conditions are met (inputs for radius and center point)
think of it as a if loop

Code - Auto/Visual Lisp: [Select]
  1. ;;----------------------------------------------------------------------;;
  2. ;; CREATE CIRCLE BLOCKS WITH UNIQE NAME
  3. (defun c:CirBlock (/ rad pt blkname)
  4.   (setvar 'cmdecho 0)
  5.   (if (and (setq rad (getreal "\nCircle Radius: ")) (setq pt (getpoint "\nPick Center Point of Circle: ")))
  6.     (progn
  7.       (entmake (list '(0 . "CIRCLE") '(8 . "Fulcrum") (cons 10 pt) (cons 40 rad)))
  8.       (setq blkname (strcat "Block-" (menucmd "M=$(edtime, $(getvar,date),YYMODDHHMMSS)")))
  9.       (vl-cmdf "_.Block" blkname "_non" pt (entlast) "")
  10.       (vl-cmdf "_.Insert" blkname "_non" pt 1 1 0)
  11.       (prompt (strcat "\nBlock [" blkname "] Created"))
  12.     )
  13.   )
  14.   (setvar 'cmdecho 1)
  15.   (princ)
  16. )


- Also how do you place circle inside the block in the layer named Fulcrum. The block is in then in the current layer.

The lisp is making the circle on that layer on line 7
when the block is inserted on line 10 its to the current layer.

Title: Re: LISP to draw circle and make block
Post by: like_citrus on May 22, 2022, 10:14:39 PM
Thanks, and apologies for not reading the code for the Fulcrum layer, as I didn't have it in the drawing I tested.

With the code above, for running once, I still get an error message:
Command: CirBlock
Unknown command "CIRBLOCK".  Press F1 for help.
Title: Re: LISP to draw circle and make block
Post by: mhupp on May 23, 2022, 08:43:20 AM
How are you loading the lisp?

appload
Title: Re: LISP to draw circle and make block
Post by: like_citrus on May 23, 2022, 07:40:46 PM
Yes, with appload.
Title: Re: LISP to draw circle and make block
Post by: mhupp on May 24, 2022, 07:31:24 AM
IDK should be able to run. double check your loading the right file.
Title: Re: LISP to draw circle and make block
Post by: like_citrus on May 24, 2022, 07:51:27 PM
Yes, I definitely have the right files as I have tested both with "while" and "if".
Title: Re: LISP to draw circle and make block
Post by: BIGAL on May 24, 2022, 11:48:52 PM
Just a side comment why not just make a block with a circle rad 1 then use scale to change.
Title: Re: LISP to draw circle and make block
Post by: ronjonp on May 25, 2022, 12:20:13 PM
Just a side comment why not just make a block with a circle rad 1 then use scale to change.
Agreed .. and make it scale uniformly.
Title: Re: LISP to draw circle and make block
Post by: like_citrus on May 25, 2022, 08:37:46 PM
Would this resolve the issue of Escape after block is inserted?
Title: Re: LISP to draw circle and make block
Post by: like_citrus on May 26, 2022, 02:05:26 AM
This is finally working, I don't know why it wasn't before as LSP file was saved after changes.

Was there a way to use diameter as well as another option?
Title: Re: LISP to draw circle and make block
Post by: mhupp on May 26, 2022, 11:08:47 AM
Was there a way to use diameter as well as another option?

CBR for radius
CBD for diameter

Code - Auto/Visual Lisp: [Select]
  1. ;;----------------------------------------------------------------------;;
  2. ;; CREATE CIRCLE BLOCKS WITH UNIQE NAME RAD
  3. (defun c:CBR (/ rad pt blkname)
  4.   (setvar 'cmdecho 0)
  5.   (if (and (setq rad (getdist "\nCircle Radius: ")) (setq pt (getpoint "\nPick Center Point of Circle: ")))
  6.     (progn
  7.       (entmake (list '(0 . "CIRCLE") '(8 . "Fulcrum") (cons 10 pt) (cons 40 rad)))
  8.       (setq blkname (strcat "Block-" (menucmd "M=$(edtime, $(getvar,date),YYMODDHHMMSS)")))
  9.       (vl-cmdf "_.Block" blkname "_non" pt (entlast) "")
  10.       (vl-cmdf "_.Insert" blkname "_non" pt 1 1 0)
  11.       (prompt (strcat "\nBlock [" blkname "] Created"))
  12.     )
  13.   )
  14.   (setvar 'cmdecho 1)
  15.   (princ)
  16. )
  17.  
  18. ;;----------------------------------------------------------------------;;
  19. ;; CREATE CIRCLE BLOCKS WITH UNIQE NAME
  20. (defun c:CBD (/ dia pt blkname)
  21.   (setvar 'cmdecho 0)
  22.   (if (and (setq dia (getdist "\nCircle Diameter: ")) (setq pt (getpoint "\nPick Center Point of Circle: ")))
  23.     (progn
  24.       (entmake (list '(0 . "CIRCLE") '(8 . "Fulcrum") (cons 10 pt) (cons 40 (/ dia 2))))
  25.       (setq blkname (strcat "Block-" (menucmd "M=$(edtime, $(getvar,date),YYMODDHHMMSS)")))
  26.       (vl-cmdf "_.Block" blkname "_non" pt (entlast) "")
  27.       (vl-cmdf "_.Insert" blkname "_non" pt 1 1 0)
  28.       (prompt (strcat "\nBlock [" blkname "] Created"))
  29.     )
  30.   )
  31.   (setvar 'cmdecho 1)
  32.   (princ)
  33. )
Title: Re: LISP to draw circle and make block
Post by: ronjonp on May 26, 2022, 12:09:19 PM
Was there a way to use diameter as well as another option?

CBR for radius
CBD for diameter

Code - Auto/Visual Lisp: [Select]
  1. ;;----------------------------------------------------------------------;;
  2. ...
  3.  
  4. ;;----------------------------------------------------------------------;;
  5. ;; CREATE CIRCLE BLOCKS WITH UNIQE NAME DIA
  6. (defun c:CBD (/ rad pt blkname)
  7.   (setvar 'cmdecho 0)
  8.   (if (and (setq rad (/ (getreal "\nCircle Diameter: ") 2)) (setq pt (getpoint "\nPick Center Point of Circle: ")))
  9.     (progn
  10.       (entmake (list '(0 . "CIRCLE") '(8 . "Fulcrum") (cons 10 pt) (cons 40 rad)))
  11.       (setq blkname (strcat "Block-" (menucmd "M=$(edtime, $(getvar,date),YYMODDHHMMSS)")))
  12.       (vl-cmdf "_.Block" blkname "_non" pt (entlast) "")
  13.       (vl-cmdf "_.Insert" blkname "_non" pt 1 1 0)
  14.       (prompt (strcat "\nBlock [" blkname "] Created"))
  15.     )
  16.   )
  17.   (setvar 'cmdecho 1)
  18.   (princ)
  19. )
@mhupp
FWIW, you should check the existence of the number before dividing otherwise it'll throw an error. I also like to use GETDIST for these types of inputs since you can enter a number as well as pick two points :)
Code - Auto/Visual Lisp: [Select]
  1. (and (setq rad (getdist "\nCircle Diameter: "))
  2.      (setq rad (/ rad 2))
  3.      (setq pt (getpoint "\nPick Center Point of Circle: "))
  4. )
Title: Re: LISP to draw circle and make block
Post by: ronjonp on May 26, 2022, 12:11:43 PM
This is finally working, I don't know why it wasn't before as LSP file was saved after changes.

Was there a way to use diameter as well as another option?
What do you use these for? Have you thought about using a circle block ( as mentioned above ) then changing the scale to get the correct size? Then you wouldn't have a bunch of blocks with different names that look the same but only have a different radius.

Then thinking about it further, why is this a block not just circles?
Title: Re: LISP to draw circle and make block
Post by: mhupp on May 26, 2022, 12:25:50 PM
@mhupp
FWIW, you should check the existence of the number before dividing otherwise it'll throw an error. I also like to use GETDIST for these types of inputs since you can enter a number as well as pick two points :)
Code - Auto/Visual Lisp: [Select]
  1. (and (setq rad (getdist "\nCircle Diameter: "))
  2.      (setq rad (/ rad 2))
  3.      (setq pt (getpoint "\nPick Center Point of Circle: "))
  4. )

It is checking when asking for the number. if it isn't inputted then the if statement fails. NM i see what your talking about.
added it to the entmake just to be different  :whistling:

Code - Auto/Visual Lisp: [Select]
  1. (entmake (list '(0 . "CIRCLE") '(8 . "Fulcrum") (cons 10 pt) (cons 40 (/ rad 2))))

Usually use getdist for those reason and you can also input fractions like 1-3/4 for 1.750 or use 100' for 1200.
I also brought up using a dynamic block but they said they wanted unique blocks with the time stamp. 

¯\_(ツ)_/¯
Title: Re: LISP to draw circle and make block
Post by: like_citrus on May 26, 2022, 08:22:53 PM
Hi, this is working now for the diameter, thanks and much appreciate it.

Quote
What do you use these for? Have you thought about using a circle block ( as mentioned above ) then changing the scale to get the correct size? Then you wouldn't have a bunch of blocks with different names that look the same but only have a different radius.
What I often do is create blocks from scratch. As a base point, I draw a circle and place it in a layer that is not printed (in this case Fulcrum). Then make it into a block manually.
The timestamp is to differentiate blocks, so each block will in the end be different.
It's the way that I'm used to working, it may not be the right way but it makes it easier for me.