Lisp - extracting subentities from a block
Hello there,
I'm currently working on a AutoLisp program to extract the DXF-Information (Group code) from sub entities (lines, circls, polylines and so on) contained in an Insert/Block and write it to a file. I did quite well extracting Entities from a drawing but for this issue I only have a rough idea.
variables used:
cntr (Counter)
oSubEnt (old subentity)
nSubEnt (new subentity)
subEntList (list of all subentities)
(setq subEntList(list))
(setq oSubEnt "")
(while (< cntr(sslength [set of all sub-entities]))
(setq nSubEnt (entget(entnext(cdr(car oSubEnt)))))
[add nSubEnt to subEntList]
(setq oSubEnt nSubEnt)
(setq cntr (+ cntr 1))
)
Practically I need help with everything within the square braces. I developed the basic idea from reading Jeffery P. Sanders tutorial. If it actually told how I could solve this problem I ether overred it or simply didn't understand.
I'd be very thankfull for every kind of help.
Please note my actual mothertongue is german so i ask you to excouse my possible typos and grammar misstakes.
Comments
-
Hi Stefen,
use the following routine to display the DXF codes in the Text Window (F2)
or to write them to a file....you can select any entity
For subentities of Blocks you will have to read the block definition of the INSERT
the command is listDXF
Here is the code
I hope this helps !
[code]
(defun print_elist (elist flag / filenam fp )
(if flag
(progn
(setq filenam (getfiled "TXT Datei erstellen" "" "txt" 1))
(setq fp (open filenam "a"))
(foreach idx elist
(print idx fp)
)
(close fp)
)
(progn
(foreach idx elist
(print idx)
)
(princ)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun atr_pop (en / lst AtrList )
(setq AtrList (list "ATR" ))
(while (not (equal (cdr (assoc 0 lst)) "SEQEND"))
(setq en (entnext en)
lst (entget en)
AtrList (append AtrList lst)
)
)
(cdr AtrList)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:listDXF ( / en elist flagFile)
(prompt "Select an Entity :\n")
(setq en (car(entsel))
elist (entget en)
)
(if (AND (= (cdr (assoc 0 elist)) "INSERT") ; if Block Insert
(= (cdr (assoc 66 elist)) 1) ; if attributes exist
)
(setq elist (append elist (atr_pop en)))
)
(setq flagFile (getstring "\nWrite to a file : "))
(if (OR (equal (strcase flagFile) "Y")
(equal (strcase flagFile) "YE")
(equal (strcase flagFile) "YES")
)
(print_elist elist T)
(print_elist elist nil)
)
(princ)
)
[/code]
0 -
@ Steven:
[code]; Return value: List of enames.
(defun Block_EnameListNested (blockName / ename ret)
(if (setq ename (tblobjname "block" blockName))
(reverse
(while (setq ename (entnext ename))
(setq ret (cons ename ret))
)
)
)
)[/code]
To manipulate the list look into the Lisp functions foreach, append and cons.
You should be aware that certain group codes in the entget-list (e.g. the ones with enames) make no sense when written to a text file. So you need a way to filter out those group codes.0 -
First of all thank you to the two of you!
@Konstantin:
Your code didn't exactly do what I was looking for (yet it wasallready executable). But it helps me a lot understanding Lisp.... At least I think so!@Roy:
Your code PROPABLY does the Job. All I need to do now is to figure out a way to crochet it into my existing code properly.A little confession: This is my second day of learning Lisp and working with it and I feel like a total noob asking These questions.
0 -
Stefen,
i have integrated the code from Roy with minor changes into my code...
So now you get everything from a block...
All the DXF data from the Block Table (Block definition, Nested Entities+ ATTDEF )
and from the Entities Section (Block Insert, Attributes if exist)
You can choose to dump everything to the text screen or write it to a file !
...command listDXF
Here is the code
[code]
(defun print_elist (elist flag / filenam fp )
(if flag
(progn
(setq filenam (getfiled "TXT Datei erstellen" "" "txt" 1))
(setq fp (open filenam "a"))
(foreach idx elist
(print idx fp)
)
(close fp)
)
(progn
(foreach idx elist
(print idx)
)
(princ)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun atr_pop (en / lst AtrList )
(setq AtrList (list "ATR" ))
(while (not (equal (cdr (assoc 0 lst)) "SEQEND"))
(setq en (entnext en)
lst (entget en)
AtrList (append AtrList lst)
)
)
(cdr AtrList)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:listDXF ( / en elist flagFile)
(prompt "Select an Entity :\n")
(setq en (car(entsel))
elist (entget en)
)
(if (= (cdr (assoc 0 elist)) "INSERT") ; if Block Insert
(setq elist (append (Block_EnameListNested (cdr (assoc 2 elist))) elist ) )
)
(if (AND (= (cdr (assoc 0 (entget en))) "INSERT") ; if Block Insert
(= (cdr (assoc 66 (entget en))) 1) ; if attributes exist
)
(setq elist (append elist (atr_pop en)))
)
(setq flagFile (getstring "\nWrite to a file : "))
(if (OR (equal (strcase flagFile) "Y")
(equal (strcase flagFile) "YE")
(equal (strcase flagFile) "YES")
)
(print_elist elist T)
(print_elist elist nil)
)
(princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Return value: List of enames of block nested entities from Block Definition
(defun Block_EnameListNested (blockName / ename ret)
(setq ename (tblobjname "block" blockName)
ret (entget ename)
)
(if ename
(while (setq ename (entnext ename))
(setq ret (append ret (entget ename) ))
)
)
)
[/code]0 -
A thousand thanks!
Thats exactly what I needed. I'll emedietly beginn to fit your solution into my code.
Thanks Roy and thanks Konstantin!0