I'm lost. how could tree be included in condition 1?
(("house"
(("couch" ("pillow" "pillow"))
("dinnerset"
("chair" "chair" "chair" "chair" "dinnertable") )
("couch" ("pillow" "pillow"))
)
)
"Tree"
"Tree"
)
Hope you dont mind telling us how did you end up with that kind if a list in the first place? I would suggest modifying the source rather rebuilding the list...
It's not that difficult. The primary goal is to count all items in the list, but when an item does have subitems, the subitem(s) replace the parent. Take "dinnerset" for example. When creating a list with all items I don't want to see this on the list, because I do have a list with the items in it already ("chair" and "dinnertable"). If both are on the order list created from this drawing, I'll order 1 "dinnerset", 4 "chair" and 1 "dinnertable". Which is wrong because I'll end up with 8x "chair" and 2x "dinnertable".
"Tree" is in the list because it does not contain subitems.
I think you are right about not rebuilding the list, but to create the correct list directly. My attempts started with this code of Leeben:
http://www.theswamp.org/index.php?topic=28043.msg336595#msg336595Which generates the list as described in my first post.
I also tried to modify the code of T.Wiley
http://www.theswamp.org/index.php?topic=31524.15Where the function Countlist does the job, but it's not perfect because:
1. the code is called multiple times with a "foreach loop" where Clist keeps track of the result, giving the result list back multiple times, but only correct when called the last time. Not very elegant I guess.
2. if an object is on multiple levels (when "chair" is member of "dinnerset", but member of "house" too) it will appear twice in the list, so another loop is necessary to total the result.
;By T.Wiley
;Modified by Woabow
(defun c:Subcalc (/ *error* ActDoc BlkCol Sel EntData BlkName NestList CList)
(defun *error* ( msg ))
;------------------------------
(defun GetBlockBlocks ( blkObj doc / BlkCol BlkCntList tempList tempName )
(setq BlkCol (vla-get-Blocks doc))
(vlax-for obj blkObj
(if (= (vla-get-ObjectName obj) "AcDbBlockReference")
(setq BlkCntList
(if (setq tempList (assoc (setq tempName (vla-get-Name obj)) BlkCntList))
(subst (list tempName (1+ (cadr tempList)) (caddr tempList)) tempList BlkCntList)
(cons (list tempName 1(GetBlockBlocks (vla-Item BlkCol tempName) doc)) BlkCntList)
)
)
)
)
BlkCntList
)
;-------------------------------------
(defun CountList ( lst multipl )
(if (atom (caddr lst))
(progn
(setq CList (cons (cons (car lst) (* (cadr lst) multipl)) CList ))
)
)
(setq multipl (* multipl (cadr lst)))
(foreach i (caddr lst)
(CountList i multipl)
)
CList
)
;-------------------------------------
(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(setq BlkCol (vla-get-Blocks ActDoc))
(if
(and
(setq Sel (entsel "\n Select block to get nesting block list: "))
(setq EntData (entget (car Sel)))
(= (cdr (assoc 0 EntData)) "INSERT")
(setq BlkName (cdr (assoc 2 EntData)))
(setq NestList (GetBlockBlocks (vla-Item BlkCol BlkName) ActDoc))
)
(progn
(prompt (strcat "\nReport for: " BlkName))
(setq p (list))
(foreach lst NestList
(setq p (CountList lst 1))
; (print "- ")
)
(foreach ip p
(print ip)
)
)
)
(princ)
)
If I have correctly understood the request, try my 'Nested Block Counter' program
Almost
It does also show items that contain subitems. And when running it on a big drawing with many blocks Bricscad responds with "error: LISP recursion stack limit exceeded " and Autocad with "internal stack limit reached (simulated)".
Here is the drawing.
http://dl.dropbox.com/u/2190289/s6.rarIt's does not have very deep levels of blocks, which will occur often also, but I have no example drawing that I can post right now.