Author Topic: LISP to draw circle and make block  (Read 3420 times)

0 Members and 1 Guest are viewing this topic.

like_citrus

  • Newt
  • Posts: 114
LISP to draw circle and make block
« 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)
)

mhupp

  • Bull Frog
  • Posts: 250
Re: LISP to draw circle and make block
« Reply #1 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.


like_citrus

  • Newt
  • Posts: 114
Re: LISP to draw circle and make block
« Reply #2 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.

mhupp

  • Bull Frog
  • Posts: 250
Re: LISP to draw circle and make block
« Reply #3 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
« Last Edit: May 22, 2022, 12:37:10 AM by mhupp »

like_citrus

  • Newt
  • Posts: 114
Re: LISP to draw circle and make block
« Reply #4 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.

mhupp

  • Bull Frog
  • Posts: 250
Re: LISP to draw circle and make block
« Reply #5 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.

« Last Edit: May 22, 2022, 10:12:33 PM by mhupp »

like_citrus

  • Newt
  • Posts: 114
Re: LISP to draw circle and make block
« Reply #6 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.

mhupp

  • Bull Frog
  • Posts: 250
Re: LISP to draw circle and make block
« Reply #7 on: May 23, 2022, 08:43:20 AM »
How are you loading the lisp?

appload

like_citrus

  • Newt
  • Posts: 114
Re: LISP to draw circle and make block
« Reply #8 on: May 23, 2022, 07:40:46 PM »
Yes, with appload.

mhupp

  • Bull Frog
  • Posts: 250
Re: LISP to draw circle and make block
« Reply #9 on: May 24, 2022, 07:31:24 AM »
IDK should be able to run. double check your loading the right file.

like_citrus

  • Newt
  • Posts: 114
Re: LISP to draw circle and make block
« Reply #10 on: May 24, 2022, 07:51:27 PM »
Yes, I definitely have the right files as I have tested both with "while" and "if".

BIGAL

  • Swamp Rat
  • Posts: 1411
  • 40 + years of using Autocad
Re: LISP to draw circle and make block
« Reply #11 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.
A man who never made a mistake never made anything

ronjonp

  • Needs a day job
  • Posts: 7529
Re: LISP to draw circle and make block
« Reply #12 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.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

like_citrus

  • Newt
  • Posts: 114
Re: LISP to draw circle and make block
« Reply #13 on: May 25, 2022, 08:37:46 PM »
Would this resolve the issue of Escape after block is inserted?

like_citrus

  • Newt
  • Posts: 114
Re: LISP to draw circle and make block
« Reply #14 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?

mhupp

  • Bull Frog
  • Posts: 250
Re: LISP to draw circle and make block
« Reply #15 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. )
« Last Edit: May 26, 2022, 12:52:14 PM by mhupp »

ronjonp

  • Needs a day job
  • Posts: 7529
Re: LISP to draw circle and make block
« Reply #16 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. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ronjonp

  • Needs a day job
  • Posts: 7529
Re: LISP to draw circle and make block
« Reply #17 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?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

mhupp

  • Bull Frog
  • Posts: 250
Re: LISP to draw circle and make block
« Reply #18 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. 

¯\_(ツ)_/¯
« Last Edit: May 26, 2022, 12:49:49 PM by mhupp »

like_citrus

  • Newt
  • Posts: 114
Re: LISP to draw circle and make block
« Reply #19 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.