They're not exactly direct children of the ModelSpace block, they're owned by a block reference which is a child of modelspace. But they're saved directly as children of modelspace. Maybe this could help ... you notice it best when working with DWF codes / Lisp. So here's an example. I've created a block (called test) with 2 attributes (ATTDEF):- Tag: TEST1, Prompt: Test, Default: Test1
- Tag: TEST2, Prompt: Test, Default: Test2
Then I inserted this block and changed TEST2's value to Custom. Now to inspect how it's saved in the drawing, I turn to LISP by typing at the command prompt: (setq en (entsel))
This calls the lisp function entsel (which asks the user to pick an entity), and then stores the result in a variable called en (my shorthand for entity name). This gives me a pointer to the entity's data. Result on command line looks like this:
Code:
Select object: (<Entity name: 7efaf090> (218.734 127.705 0.0))
Now to get its data, I type: (setq ed (entget (car en)))
This gets the entity's data from the 1st value in the list I've got saved into en, then it stores the result in a variable called ed (my shorthand for Entity Data). The result on the command line looks like this:
Code:
((-1 . <Entity name: 7efaf090>) (0 . "INSERT") (330 . <Entity name: 7efa7fa8>)
(5 . "8A") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 .
"AcDbBlockReference") (66 . 1) (2 . "test") (10 201.782 125.195 0.0) (41 . 1.0)
(42 . 1.0) (43 . 1.0) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210
0.0 0.0 1.0))
The (330 . ....) code points to the owner (or parent object), in this case it's the *ModelSpace* block. Notice, the data doesn't show anything regarding the attributes, except for the (66 . 1) which means "Attributes Follow". The entity type is (0 . "INSERT") - not block, it's an "Insert" ... or as per the ActiveX name (100 . "AcDbBlockReference").
So now I know there's attributes following the block. I start obtaining the next entity by typing (setq an (entnext (car en)))
This gets the next entity after the block reference I've picked, and saves this to an (Attribute Name). Then I get its data, (setq ad (entget an)), the result looks like:
Code:
((-1 . <Entity name: 7efaf0a0>) (0 . "ATTRIB") (330 . <Entity name: 7efaf090>)
(5 . "8C") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 .
"AcDbText") (10 204.02 130.643 0.0) (40 . 2.5) (1 . "Test1") (50 . 0.0) (41 .
1.0) (51 . 0.0) (7 . "Standard") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 0.0
0.0 1.0) (100 . "AcDbAttribute") (2 . "TEST1") (70 . 0) (73 . 0) (74 . 0) (280
. 1))
Notice this is a (0 . "ATTRIB") entity type. Also its owner is (330 . <Entity name: 7efaf090>), which is the same as the block's EName, from above (-1 . <Entity name: 7efaf090>).
Now for the next entity, (setq an (entnext an)), and its data (setq ad (entget an)), result:
Code:
((-1 . <Entity name: 7efaf0a8>) (0 . "ATTRIB") (330 . <Entity name: 7efaf090>)
(5 . "8D") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 .
"AcDbText") (10 204.02 126.643 0.0) (40 . 2.5) (1 . "Custom") (50 . 0.0) (41 .
1.0) (51 . 0.0) (7 . "Standard") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 0.0
0.0 1.0) (100 . "AcDbAttribute") (2 . "TEST2") (70 . 0) (73 . 0) (74 . 0) (280
. 1))
This is the 2nd attribute, now do it again, resulting in:
Code:
((-1 . <Entity name: 7efaf098>) (0 . "SEQEND") (330 . <Entity name: 7efaf090>)
(5 . "8B") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (-2 .
<Entity name: 7efaf090>))
This is a special non graphical entity, it's simply used to show that you're now at the end of a group of entities. But let's try again:
Code:
((-1 . <Entity name: 7efaf0e8>) (0 . "LINE") (330 . <Entity name: 7efa7fa8>) (5
. "95") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 .
"AcDbLine") (10 209.938 -21.2403 0.0) (11 467.613 160.073 0.0) (210 0.0 0.0
1.0))
Now this is a line, and it's owner is the Model Space, same as that of the INSERT entity: (330 . <Entity name: 7efa7fa8>).
The block itself has a polyline rectangle surrounding the attributes ... this is only saved inside the block's definition ... not directly inside the ModelSpace block. To proove this I get the block's definition out of the table structure AutoCAD uses to store block defs. Type (setq bn (tblobjname "BLOCK" "test")), this gets the entity name of the block named "test" out of the "BLOCK" table and saves to bn. Now (setq bd (entget bn)), resulting:
Code:
((-1 . <Entity name: 7efaf068>) (0 . "BLOCK") (330 . <Entity name: 7efaf060>)
(5 . "85") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70
. 2) (10 0.0 0.0 0.0) (-2 . <Entity name: 7efaf078>) (2 . "test") (1 . ""))
The owner (330 . <...>) is a "BLOCK_RECORD" entity, which has an owner which is a "TABLE" entity, it's owner is (330 . <Entity name: 0>) - which is the drawing itself.
Notice the (-2 . <Entity name: 7efaf078>), from the DXF help this is the 1st entity inside the block. So (setq en (cdr (assoc -2 bd))), which gives the 2nd portion of the group starting with -2 from bd. Then it's data, (setq ed (entget en)), resulting:
Code:
((-1 . <Entity name: 7efaf078>) (0 . "LWPOLYLINE") (330 . <Entity name:
7efaf060>) (5 . "87") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 .
"AcDbPolyline") (90 . 4) (70 . 1) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 0.0 0.0)
(40 . 0.0) (41 . 0.0) (42 . 0.0) (10 17.0774 0.0) (40 . 0.0) (41 . 0.0) (42 .
0.0) (10 17.0774 9.53743) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 0.0 9.53743) (40
. 0.0) (41 . 0.0) (42 . 0.0) (210 0.0 0.0 1.0))
Then (setq en (entnext en) ed (entget en)), just doing both in one step, result:
Code:
((-1 . <Entity name: 7efaf080>) (0 . "ATTDEF") (330 . <Entity name: 7efaf060>)
(5 . "88") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbText") (10
2.23834 5.44841 0.0) (40 . 2.5) (1 . "Test1") (50 . 0.0) (41 . 1.0) (51 . 0.0)
(7 . "Standard") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 .
"AcDbAttributeDefinition") (3 . "Test") (2 . "TEST1") (70 . 0) (73 . 0) (74 .
0) (280 . 1))
This is the 1st attribute definition, then again:
Code:
((-1 . <Entity name: 7efaf088>) (0 . "ATTDEF") (330 . <Entity name: 7efaf060>)
(5 . "89") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbText") (10
2.23834 1.44841 0.0) (40 . 2.5) (1 . "Test2") (50 . 0.0) (41 . 1.0) (51 . 0.0)
(7 . "Standard") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 .
"AcDbAttributeDefinition") (3 . "Test") (2 . "TEST2") (70 . 0) (73 . 0) (74 .
0) (280 . 1))
2nd attribute, do it again:
Code:
; error: bad argument type: lentityp nil
This means that there's no more entities inside the block.
A redefine of a block, only changes these entities inside the block itself. It does absolutely noting to the INSERT or ATTRIB entities which already exists. The ATTSYNC (or BATTMAN->Sync) commands run through all the INSERTS and change their following ATTRIB's to reflect what's inside the BLOCK entity.