Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to create an unnamed block with lisp?

1,055 views
Skip to first unread message

Joe Sam

unread,
Nov 8, 1998, 3:00:00 AM11/8/98
to
in Lisp

how do you create an unnamed block?

I actually can create it with entmake and and ananomous block name starting
with *n , it created the block but there is no way to insert it.

can any lispers help me out there , if so send me an email

joe...@home.com


Ian A. White

unread,
Nov 8, 1998, 3:00:00 AM11/8/98
to
On Sun, 08 Nov 1998 04:55:27 GMT, "Joe Sam" <joe...@home.com> wrote:

> in Lisp
>
> how do you create an unnamed block?
>
> I actually can create it with entmake and and ananomous block name starting
> with *n , it created the block but there is no way to insert it.

The placement of a block is an INSERT, so after creating the block
definition with (entmake), similarly create its placement or INSERT.


--

Ian A. White, CPEng
WAI Engineering
Sydney 2000
Australia

Ph: +61 418 203 229
Fax: +61 2 9622 0450

Junk e-mail will be returned, as is, to the sender's host system.

Steve Baker

unread,
Nov 9, 1998, 3:00:00 AM11/9/98
to
In article <3v912.1662$Bn1.1...@news.rdc1.on.wave.home.com>,
joe...@home.com says...

> in Lisp
>
> how do you create an unnamed block?
>
> I actually can create it with entmake and and ananomous block name starting
> with *n , it created the block but there is no way to insert it.
>
> can any lispers help me out there , if so send me an email
>
> joe...@home.com
>
>
>
>
There is a good little lisp at www.cadalog.com that makes an anonymous
block very quickly. All I do is load it in the acad.lsp and then type
"mb" enter and pick a spot to call an insert point then pick the objects.
Then it re-inserts it in a fraction of a nano-second (with a P200 anyway)
so you never know that it actually made a block. That took about 100
times more time than the lisp does.
Here's something you might find interesting. It show some ways to go
about making anonymous blocks. If I was at work I'd send you mine but...

************ Begin Insertion ************

AutoLISP Anonymous Blocks
Lesson Six in the CADalyst/University of Wisconsin Advanced AutoLISP
Programming course shows you how to create anonymous blocks and
introduces extended entity data.
by
Anthony Hotchkiss, Ph.D, P.Eng.


-------------------------------------------------------------------------
-------

About this course.


Advanced AutoLISP Programming is an eight-lesson independent study
course, originally published in monthly installments in CADalyst
magazine. Before you begin this course, it is assumed that you have
reached a basic level of AutoLISP programming, equivalent to completing
the preceding 'Introduction to AutoLISP Programming' course which was
originally published in CADalyst, and is now available as an independent
study course from the University of Wisconsin-Madison. On successfully
completing an intermediate and a final mail-in project, registered
students will receive certificates of completion and 5.0 CEU's
(continuing education units).

For further information, contact:

Steve Bialek
Engineering Professional Development
University of Wisconsin-Madison
432 North Lake Street
Madison, Wisconsin 53706
(608) 262-1735


-------------------------------------------------------------------------
-------

LESSON SIX - AUTOCAD ANONYMOUS BLOCKS


In this lesson, you will learn how to make 'anonymous' complex entities
that are inserted but not given names in the block list. You will learn
some new naming conventions for anonymous blocks, and you will be
introduced to the concept of 'extended entity data' that allows you to
attach intelligent attributes to your geometry. Programming examples will
be used to show you how to apply the functions, and homework assignments
will test your understanding of the lesson.


THE STRUCTURE OF ANONYMOUS BLOCKS


In lesson two of this series, we listed the DXF group codes of a block
that was a dimension. The DXF list was:

(0 . "BLOCK")
(2 . "*D0")
(70 . 65)
(10 0.0 0.0 0.0)
(-2 . <Entity name: 4000001e>)
We noted that the use of the asterisk in the name of the block was a
convention for naming anonymous blocks. The 'D' in the name signifies
that this anonymous block is a Dimension (actually an associative
dimension). Another type of anonymous block is the hatch pattern, which
has a name of the form *Xnnn, where nnn is a number. The anonymous blocks
that we are concerned with here are the 'User' anonymous blocks that take
names of the form *Unnn, where nnn is a number that is assigned
automatically by AutoCAD.

Anonymous blocks can be used to create groups of entities that don't get
recorded as named blocks in the drawing block list, and they are
automatically purged from the drawing if they are not referenced
(inserted). For this reason, the number portion of the anonymous block
name can change between drawing sessions, just like the names of any
other entity, but you can attach 'handles' to them if you want a constant
identifier.


The use of the asterisk as the first character of the name usually has
the effect of exploding inserted blocks. You can not insert anonymous
blocks with the INSERT command, because AutoCAD will assume you intend to
insert and explode a block with the name of Unnn. Instead, you need to
use (entmake) to create the INSERT entity.


Another aspect of using anonymous blocks is that you can attach extended
entity data (xdata) to them, as you can with any entity or complex
entity. The extended entity data has dxf codes that can relate distances
and positions to the parent object (that is the object to which the xdata
are attached), so if the parent object is scaled, the extended entity
data are automatically scaled with it. You can use this property to
attach 'smart' attributes to entities in a much more flexible way than
you can by using the regular attributes of AutoCAD. If anonymous blocks
are used to attach the intelligent attributes via xdata, you don't have
to create standard blocks that need to be purged if they are not used.


The dxf list of an anonymous block is obtained from (tblsearch) thus;

Command: (foreach x (tblsearch "block" "*U1") (print x))
(0 . "BLOCK")
(2 . "*U1")
(70 . 65)
(10 8.38609 6.1413 0.0)
(-2 . <Entity name: 40000d00>)
The program LISTBLK.LSP from the previous lesson (five) of this series
can be used to expand the list of sub entities in the anonymous block
with (entnext), just as you can with regular block and insert entities.
Two things are different from regular blocks in this list; the name
begins with the asterisk-U, and the flag bit code 70 has a '1' in it to
signify the anonymous block. In this case the '1' has been added to the
flag bit code '64', which means that the block definition is referenced.

The listing from (entget) of the INSERT looks like:

(-1 . <Entity name: 600000ee>)
(0 . "INSERT")
(8 . "1")
(2 . "*U1")
(10 4.25287 9.20652 0.0)
(41 . 1.0)
(42 . 1.0)
(50 . 0.0)
(43 . 1.0)
(70 . 0)
(71 . 0)
(44 . 0.0)
(45 . 0.0)
(210 0.0 0.0 1.0)
The dxf group codes are the same as those for regular blocks

CREATING ANONYMOUS BLOCKS


If you have a new drawing, the first anonymous block name will be "*U0",
so it would be safe to type in the following to create a simple anonymous
block using (entmake):

(entmake '((0 . "BLOCK") (2 . "*U0") (70 . 64) (10 4.0 5.0 0.0)))
(entmake '((0 . "CIRCLE") (10 4.0 4.0 0.0) (40 . 1.0)))
(entmake '((0 . "CIRCLE") (10 4.0 4.0 0.0) (40 . 2.0)))
(entmake '((0 . "CIRCLE") (10 4.0 4.0 0.0) (40 . 3.0)))
(entmake '((0 . "ENDBLK")))
The number '0' in the name *U0 is actually ignored by AutoCAD, so you
could equally well write "*U" in the group code '2' instead.

Now, in order to insert the new anonymous block, you must use (entmake),
and not the command 'INSERT'. The (entmake) statement to insert the block
at coordinates 6,6 is:


(entmake '((0 . "INSERT") (2 . "*U0") (10 6.0 6.0 0.0)))


As this is the first anonymous block created in your drawing, it is safe
to assume that the name has been assigned to be *U0, but if you created
an anonymous block in a drawing that already had some anonymous blocks,
you would need to know the number of the last anonymous block so that you
can insert the one that you just created, and not another one.


Without proper care, it is also possible to redefine existing anonymous
blocks by giving them the same name as an existing block, just as you can
with conventional blocks. (entmake) automatically returns the block name
if the entity type is "ENDBLK", so you can make use of this when
inserting the block.


ABLOCK.LSP is a program for creating anonymous blocks by selecting
objects just like you would for conventional blocks.

;;; ABLOCK2.LSP A program to make and insert anonymous blocks
;;; Program by Tony Hotchkiss
(defun C:ABLOCK2 (/ ins_pt num ss1 i n)
;(defun test () ; ** this line is used for development only
(setq ins_pt (getpoint "\nInsertion point: "))
(entmake (list '(0 . "BLOCK")'(2 . "*U")'(70 . 1)(cons 10 ins_pt)))
(prompt "\nSelect entities")
(setq ss1 (ssget) i (sslength ss1) n (- 1))
(repeat i
(entmake (cdr (entget (ssname ss1 (setq n (1+ n))))))
)
(setq num (entmake '((0 . "ENDBLK")) ))
;*************** Insert the anonymous block ******
(entmake (list '(0 . "INSERT")(cons 2 num)(cons 10 ins_pt)))
(command "move" "L" "" ins_pt pause "redraw")
(princ)
); ablock2
The program starts by getting the insertion point of the block, which is
used in the (entmake) statement for the block header as (entmake (list
'(0 . "BLOCK")'(2 . "*U")'(70 . 1)(cons 10 ins_pt))). The list for
entmake contains a combination of quoted and unquoted expressions,
because the variable ins_pt must be evaluated when the list is supplied
to (entmake). The block name is supplied as "*U" because AutoCAD will use
its own numbers. If you really want to redefine an existing user block,
you can supply the appropriate number.

Entity selection is made in the simplest way with the general form of
(ssget). The number of entities selected is recorded as 'i', to be used
for the following repeat loop count, and the value of 'n' is set to -1.
The entities of the block are made with the single (entmake) statement of
the repeat loop, in which each entity of the selected set is in turn
listed with (entget). Note how the counter 'n' is automatically
incremented by 1 as it is used.


After all entities have been made, the "ENDBLK" entity is included to
signal the end of the anonymous block, which is now ready to be inserted.
The block name is assigned to 'num'.


The "INSERT" entity is created with (entmake) as shown, using the block
name variable and the previous insertion point. I didn't erase the
entities that make up the anonymous block, implying that the "INSERT"
entity will be inserted exactly over the old entities, so I included the
'MOVE' command with a base point at the insertion point. The block is
attached to the cursor and can be placed at any desired positions, as
shown in figure 6-1.

EXTENDED ENTITY DATA - AN INTRODUCTION


Extended entity data (Xdata) are values associated with dxf group codes
currently in the range 1000 to 1071. Unlike the regular dxf codes, the
xdata group codes may appear many times, so organization of data is
important. Sets of extended entity data are associated and grouped by an
'application' name. Application names are stored in a symbol table called
'APPID'.


Before you attach extended entity data, it is necessary to provide the
appid (application name/identifier) associated with group code 1001. For
a single set of xdata (a single appid), the dxf code 1001 does not
actually appear in the xdata list. The appid must be 'registered' using
the function (regapp) as follows:


(regapp namestring)


For instance, type (regapp "myapp"), followed by (tblsearch "appid"
"myapp"), and you will see the symbol table entry for the APPID as


((0 . "APPID") (2 . "MYAPP") (70 . 0))


The group code 70 is a flag that is common to the other symbol tables to
flag the reference status.


EXTENDED ENTITY DATA GROUP CODES


The xdata group codes are shown in table 6-1.

-------------------------------------------------------------------------
-------

TABLE 6-1 XDATA GROUP CODES


CODE ENTITY TYPE AND DESCRIPTION
1000 String. Up to 255 bytes long plus a reserved null character.
1001 Application name; a string up to 31 bytes long (plus a null
character).
1002 A special control string; can be either "{" or "}", used for
conveniently grouping data.
1003 Layer name associated with the xdata.
1004 Binary data - hexadecimal digits, used by ADS, not AutoLISP.
1005 Handles of AutoCAD entities.
1010 3 real values, stored as X, Y, Z. In a DXFout list, each real is
associated with
1010, 1020, and 1030 respectively.
1011 1011, 1021, 1031 A world space position. These coordinates are
moved, scaled
mirrored, rotated and stretched with the 'parent'
entity.
1012 1012, 1022, 1032 Another 3D point that is scaled, rotated and
mirrored with the
parent entity, but not moved or stretched.
1013 1013, 1023, 1033 Another 3D point that is only rotated and
mirrored with the parent.
1040 A real value.
1041 A distance (a real value that is scaled with the parent entity).
1042 A scale factor (also a real value that is scaled with the parent
entity).
1070 An integer. A '16-bit' integer that can be signed (plus/minus)
1071 A 'long-integer'. A 32-bit integer, used by ADS, not AutoLISP


-------------------------------------------------------------------------
-------

As with the regular group codes, the 3D points can have each coordinate
grouped separately, or as a single code. For instance, a group 10 point
can be (10 2.0, 3.0, 0.0) or (10 . 2.0) (20 . 3.0) (30 . 0.0), and the
same is true for groups 1010 thru 1013. A DXFOUT listing always makes the
separate code format.


The significance of having values scaled etc. with the parent entity (the
entity to which the xdata are attached) will become clear with a very
simple example that you can try.


A SIMPLE XDATA EXAMPLE


For this example, we will use a 'fastener' application, in which we can
imagine that there are some mechanical fasteners such as nuts and bolts.
We represent a bolt by drawing a circle, and we will attach some xdata to
the circle to represent the bolt type, thread form, and the bolt length
and diameter. This example shows the 'intelligence' of these xdata as
compared with regular attributes. Extended entity data is all grouped
under the dxf code -3, and this is followed by the subgroup under the
registered application name, (the APPID). The rest of the data is grouped
in dotted pairs with the xdata group codes.


First make sure that you have a circle (I used a radius of 0.375),
register the application with (regapp "fasteners"), and get the regular
dxf group listing of your circle as shown in this command/prompt
sequence, which assigns the circle dxf list to the symbol 'elist':

Command: (regapp "fasteners")
"FASTENERS"
Command: (setq elist (entget (car (entsel))))
Select object: ((-1 . <Entity name: 6000001a>) (0 . "CIRCLE") (8 .
"1")
(10 3.71912 1.87589 0.0) (40 . 0.375) (210 0.0 0.0 1.0)
Command:
Now let's make some xdata with (setq...) as in this sequence (don't worry
about the prompt for missing parentheses, shown as 3>, just enter the
data as shown here):
Command: (setq xdat '(-3 ("fasteners" (1000 . "socket-head") (1000 .
"16-UNF")
3> (1002 . "{") (1041 . 0.75) (1041 . 1.5) (1002 . "}"))))
Remember that the 3> is a prompt of the AutoLISP interpreter, not data to
be entered, and use the quoted format for the list. AutoCAD will then
display the xdat list as it is returned by (setq). In this example, we
use the numbers 0.75 and 1.5 associated with group code 1041 to represent
the diameter and the length of the bolt respectively. We will show in the
next lesson that you can precede each of these numbers with strings
associated with group code 1000 for more clarity and organization.

Now, add the xdata to the entity list and modify the AutoCAD data base as
in the next sequence:

Command: (setq exdata (append elist (list xdat)))
Command: (entmod exdata)
Your screen will look like that of figure 6-2, and the xdata will be
attached to the circle.

In order to show the extended entity data list, you need to add the
registered application name as an argument to (entget), for instance as
in:


(setq elist2 (assoc -3 (entget (entlast) '("fasteners"))))


This will return the list associated with code -3 (the extended entity
data), as follows.


(-3 ("FASTENERS" (1000 . "socket-head") (1000 . "16-UNF") (1002 . "{")
(1041 . 0.75) (1041 . 1.5) (1002 . "}")))


Note how the APPID argument of (entget) is shown as the the quoted list
of a string.


Now here's the best part! Copy the circle and scale the new entity with
the xdata by a factor of 2, then get the dxf list of the new entity with
(entget) as we did before, and you will see:


(-3 ("FASTENERS" (1000 . "socket-head") (1000 . "16-UNF") (1002 . "{")
(1041 . 1.5) (1041 . 3.0) (1002 . "}")))


Notice how the xdata is transferred to the new entity, and the numbers in
group code 1041 representing the diameter and length have doubled,
because they are scaled with the parent entity. This means that you can
have much better representation of attributes with these intelligent
extended entity data than you can with AutoCAD's regular attributes.


The question of how to handle data when the group codes are repeated is
an organizational matter that needs to be discussed further. In our next
lesson (seven), we will use programs to organize and create the xdata
with an example that attaches intelligent attributes to groups of
entities.


-------------------------------------------------------------------------
-------

Homework:


1. Why can't we scan the drawing for inserted anonymous blocks instead of
examining the block table when looking for the name of the last created
anonymous block?


2. Using the program ABLOCK.LSP, create some anonymous blocks in a new
drawing. Undo everything in the drawing and make some more anonymous
blocks. Use (entget (entlast)) occasionally as you create the blocks, and
examine the names of the blocks. After a number of 'Undo/Back' commands,
what is the effect on the names of the anonymous blocks?


3. After you have been through some cycles of creating anonymous blocks
and using 'Undo/Back', record the name of the last anonymous block that
you created. Save your drawing, and then exit the drawing session and
return to the saved drawing. Now examine the name of the same anonymous
block that you looked at previously (you can do this with (entget (car
(entsel)))....). What has happened to the block name?


4. Repeat the process of question 3 with entity handles enabled, then
examine the dxf lists of the anonymous blocks to observe the handles (dxf
group code 5).


5. Write a program to select an anonymous block by using its handle as a
selection criterion. Note that filter lists in (ssget) do not recognize
handles (group code 5).


-------------------------------------------------------------------------
-------

In lesson seven of this series, "Extended Entity Data", you will learn
more about extended entity data. You will learn how to attach intelligent
attributes to your geometry, using the XDATA DXF group codes. Programming
examples will be used to show you how to create and append XDATA, and
homework assignments will test your understanding of the lesson.


-------------------------------------------------------------------------
-------

If you need additional help with this course, please contact Tony
Hotchkiss at HOTC...@SNYBUFAA.CS.SNYBUF.EDU or Steve Bialek at 608-262-
1735 or i...@epd.engr.wisc.edu.

-------------------------------------------------------------------------
-------

0 new messages