Author Topic: entmake a block  (Read 4161 times)

0 Members and 1 Guest are viewing this topic.

curmudgeon

  • Newt
  • Posts: 184
entmake a block
« on: November 07, 2013, 03:22:10 PM »
Several versions ago, I had written something to automate making some blocks based on location.
I found it useful.

Trying to make the code work in new version of Autocad, and it fails.

Code: [Select]
  (entmake (list (cons 0 "BLOCK")
(cons 2 (caar n))
(cons 70 0)
(cons 10 (cadr n))
   )
  )
  (while (< i count_them)
    (setq it (cdr (entget (ssname them i))))
    (entmake it)
    (setq i (+ i 1))
  )
  (entmake '((0 . "ENDBLK")))

The selection set is valid, and the list of entities IS created - it produces duplicates.
But the entmake for the ENDBLOCK returns nil.

To make something like this work, do I now need to write to the block table more directly?
Or what?

thanks
Never express yourself more clearly than you are able to think.

snownut2

  • Swamp Rat
  • Posts: 920
  • ADT 2004 - AutoCad 2011 Bricscad 15
Re: entmake a block
« Reply #1 on: November 07, 2013, 06:39:15 PM »
curmudgeon,

That's pretty much the same I am using works fine in Bricscad 14, have not tried in any thing newer than 2011 AutoCAD.

God helps those who helps themselves.
A little searching goes a long ways.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10283
Re: entmake a block
« Reply #2 on: November 07, 2013, 09:24:26 PM »
You might play around with some of these dxf codes.
Code: [Select]
    (entmake  (list '(0 . "BLOCK")            ; required
             '(100 . "AcDbEntity")     ; recommended
             '(100 . "AcDbBlockBegin") ; recommended
              (cons 2 blockname)       ; required
             '(8 . "0")                ; recommended
             '(70 . 2)                 ; required [NOTE 0 if no attributes]
             '(10 0.0 0.0 0.0)         ; required
      ))


Code: [Select]
    (entmake (list '(0 . "ENDBLK")         ; required
                   '(100 . "AcDbBlockEnd") ; recommended
                   '(8 . "0")              ; recommended
                   ))
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

roy_043

  • Water Moccasin
  • Posts: 1598
  • BricsCAD 18
Re: entmake a block
« Reply #3 on: November 08, 2013, 05:00:56 AM »
@curmudgeon:
This type of cloning is very risky.
For example if I use this code (Note: I use BricsCAD V14):
Code: [Select]
(entmake (entget (car (entsel))))to clone an entity with an extension dictionary, the clone references the same extension dictionary as the original which is 'illegal'.

To debug your problem I would replace the while loop with a single (entmake) from scratch. That way you will know if the problem is caused by the while loop or by the rest of the code.

Judging from CAB's post the problem is caused by (the entities in) the while loop.

Master_Shake

  • Swamp Rat
  • Posts: 1356
Re: entmake a block
« Reply #4 on: November 08, 2013, 03:41:41 PM »
Not sure if this will help but here is a lisp I have to prompt a part number and create a text block with said part number.

Code: [Select]
;**************************************
;CREATE PART NUMBER BLOCK
;**************************************
(defun C:partnogen (/ pt01)
(setq partnumber (getstring "\nEnter Part Number: "))
(entmake
(list
(cons 0 "BLOCK") ; entity
(cons 2 partnumber) ; block name
(cons 70 2) ; block type
(list 10 0.0 0.0 0.0) ; base point 
) ; end list
) ; end entmake
(entmake
(list
(cons 0 "TEXT") ; entity
(cons 8 "SYS-Bom_Part_Numbers") ; layer
(list 10 0.0 0.0 0.0) ; base point
(cons 40 0.035) ; text height
(cons 1 partnumber) ; text string
(cons 50 0)  ; text rotation
; (cons 7 "STANDARD")   ; text style
(cons 72 10) ; text justification
) ; end list
) ; end entmake text
;**************************************
;START ANNOTATIVE / NO EXPLODE SEQUENCE
;**************************************
(entmake
                (list
                    (cons 0 "ENDBLK")
                    (cons 8 "0")
                )
            )
            (
                (lambda ( lst )
                    (regapp "ACAD")
                    (regapp "AcadAnnotative")
                    (entmod
                        (append (subst (cons 70 1) (assoc 70 lst) lst)
                            (list
                               (list -3
                                   (list "ACAD"
                                       (cons 1000 "DesignCenter Data")
                                       (cons 1002 "{")
                                       (cons 1070 1)
                                       (cons 1070 1)
                                       (cons 1002 "}")
                                   )
                                   (list "AcadAnnotative"
                                       (cons 1000 "AnnotativeData")
                                       (cons 1002 "{")
                                       (cons 1070 1)
                                       (cons 1070 1)
                                       (cons 1002 "}")
                                   )
                               )
                           )
                        )
                    )
                )
               (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" partnumber)))))
            )
                 (vl-load-com)
          (setq BLOCKS
          (vla-get-Blocks
           (vla-get-activedocument
            (vlax-get-acad-object)
           )
          )
         BLK (vla-Item BLOCKS partnumber)
       )
      (vla-put-explodable (vla-Item BLOCKS partnumber) :vlax-false) 
 
    (princ)
) ; end function


curmudgeon

  • Newt
  • Posts: 184
Re: entmake a block
« Reply #5 on: November 12, 2013, 06:33:58 PM »
Charles:

I took some time to play with it, and it FAILS when the selection set includes a block with attributes.
This is a work around.
Code: [Select]
(while (< i count_them)
  (if (not (assoc 66 (setq it (cdr (entget (ssname them i))))))
    (entmake it)
  )
  (setq i (+ i 1))
)

I test "it" to see if attributes follow.

Now I can choose whether I want to not process those, or try to gather the attributes and the SEQEND.
Simpler to leave them out. I can always try to "fix" it more later.

THANKS.

Never express yourself more clearly than you are able to think.

Lee Mac

  • Seagull
  • Posts: 12000
  • AutoCAD 2015 Windows 7 London, England
Re: entmake a block
« Reply #6 on: November 12, 2013, 07:33:23 PM »
Here's an old program I found in my library, it may be of help:

Code - Auto/Visual Lisp: [Select]
  1. ;; Objects to Block  -  Lee Mac
  2. ;; Converts a selection of objects to a block reference.
  3.  
  4. (defun c:obj2blk ( / e i l n p s x )
  5.    (if
  6.        (and (setq s (ssget "_:L" '((-4 . "<NOT") (0 . "ATTDEF,VIEWPORT") (-4 . "NOT>"))))
  7.            (progn
  8.                (while
  9.                    (not
  10.                        (or (= "" (setq n (getstring t "\nSpecify Block Name <Anonymous>: ")))
  11.                            (and
  12.                                (snvalid n)
  13.                                (null (tblsearch "BLOCK" n))
  14.                            )
  15.                        )
  16.                    )
  17.                    (princ "\nBlock name invalid or already exists.")
  18.                )
  19.                (if (= "" n)
  20.                    (setq n "*U")
  21.                )
  22.                (setq p (getpoint "\nSpecify Base Point: "))
  23.            )
  24.        )
  25.        (progn
  26.            (entmake
  27.                (list
  28.                   '(0 . "BLOCK")
  29.                    (cons 10 (trans p 1 0))
  30.                    (cons 02 n)
  31.                    (cons 70 (if (wcmatch n "`**") 1 0))
  32.                )
  33.            )
  34.            (repeat (setq i (sslength s))
  35.                (entmake (entget (setq e (ssname s (setq i (1- i))))))
  36.                (if (= 1 (cdr (assoc 66 (entget e))))
  37.                    (progn
  38.                        (setq x (entnext e)
  39.                              l (entget  x)
  40.                        )
  41.                        (while (/= "SEQEND" (cdr (assoc 0 l)))
  42.                            (entmake l)
  43.                            (setq x (entnext x)
  44.                                  l (entget  x)
  45.                            )
  46.                        )
  47.                        (entmake l)
  48.                    )
  49.                )
  50.                (entdel e)
  51.            )
  52.            (if (setq n (entmake '((0 . "ENDBLK"))))
  53.                (entmake
  54.                    (list
  55.                       '(0 . "INSERT")
  56.                        (cons 02 n)
  57.                        (cons 10 (trans p 1 0))
  58.                    )
  59.                )
  60.            )
  61.        )
  62.    )
  63.    (princ)
  64. )

Lee Mac

  • Seagull
  • Posts: 12000
  • AutoCAD 2015 Windows 7 London, England
Re: entmake a block
« Reply #7 on: November 12, 2013, 07:45:10 PM »
Visual LISP makes things a lot easier in this case:

Code - Auto/Visual Lisp: [Select]
  1. ;; Objects to Block  -  Lee Mac
  2. ;; Converts a selection of objects to a block reference.
  3.  
  4. (defun c:obj2blk ( / b d l n p s )
  5.    (if
  6.        (and (ssget "_:L" '((0 . "~VIEWPORT")))
  7.            (progn
  8.                (while
  9.                    (not
  10.                        (or (= "" (setq n (getstring t "\nSpecify block name <anonymous>: ")))
  11.                            (and
  12.                                (snvalid n)
  13.                                (null (tblsearch "block" n))
  14.                            )
  15.                        )
  16.                    )
  17.                    (princ "\nBlock name invalid or already exists.")
  18.                )
  19.                (if (= "" n)
  20.                    (setq n "*U")
  21.                )
  22.                (setq p (getpoint "\nSpecify base point: "))
  23.            )
  24.        )
  25.        (progn
  26.            (vlax-for o (setq s (vla-get-activeselectionset d))
  27.                (setq l (cons o l))
  28.            )
  29.            (vla-delete s)
  30.            (vlax-invoke d 'copyobjects l (setq b (vlax-invoke (vla-get-blocks d) 'add (trans p 1 0) n)))
  31.            (vlax-invoke
  32.                (vlax-get-property d (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
  33.                'insertblock
  34.                (trans p 1 0)
  35.                (vla-get-name b) 1.0 1.0 1.0 0.0
  36.            )
  37.            (foreach o l (vla-delete o))
  38.        )
  39.    )
  40.    (princ)
  41. )

roy_043

  • Water Moccasin
  • Posts: 1598
  • BricsCAD 18
Re: entmake a block
« Reply #8 on: November 13, 2013, 04:34:18 AM »
The big question is of course: Why not use the BLOCK command?

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11653
  • class keyThumper<T>:ILazy<T>
Re: entmake a block
« Reply #9 on: November 13, 2013, 04:53:39 AM »

That wouldn't be any fun, now would it.

... but sometimes I ask myself the same question.


Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Lee Mac

  • Seagull
  • Posts: 12000
  • AutoCAD 2015 Windows 7 London, England
Re: entmake a block
« Reply #10 on: November 13, 2013, 06:16:27 AM »
The big question is of course: Why not use the BLOCK command?

The BLOCK command may indeed be sufficient for some cases, these are simply examples to offer alternative methods.  :-)

curmudgeon

  • Newt
  • Posts: 184
Re: entmake a block
« Reply #11 on: November 21, 2013, 02:54:52 PM »
Thank you Lee. FYI, I have some 20 blocks that I will want to update repeatedly.
I have made much use of the method in the past, but there were no attributes involved then.

Yes, the BLOCK command works, but not without many picks and selections.
Never express yourself more clearly than you are able to think.

RC

  • Guest
Re: entmake a block
« Reply #12 on: November 21, 2013, 03:18:28 PM »
The big question is of course: Why not use the BLOCK command?

run a routine that builds specific blocks based on look-up tables
routine checks to see if block exists already
if not it creates block with attributes already filled in and places it in desired location

This was out modus operandi for placing steel shapes into 3D models for years.