I made a program of which, for simplicity, I extracted and modified a part that I report below.
Purpose of the example (see DWG):
1 - extract some entities from the main blocks (some will be transformed into a block)
> entities on the "RED" layer and arcs with radius > 200 on the "CENTER" layer
2 - extract some entities from the nested blocks
> entities on the "HIDDEN" layer and arcs with radius > 200 on the "CENTER" layer
&&
Question 1:
I've used the Explode method but it's very slow so I'll have to use another approach.
Is it better to use vla-CopyObjects or entmakex to clone entities?
Question 2:
To insert the nested blocks I calculated the insertion point with (trans (DXF 10 (entget <Entity name>)) <Entity name> 1)
My blocks are always in scale 1, will I have to use vla-transformby?
For the eventual calculation I have seen these functions:
LM:Ref->Def LM:WCS->Geom LM:ApplyMatrixTransformation LM:WCS->Geom (Lee Mac)
gc: EnameMatrix (gile)
what do you recommend?
(defun C:Test ( / Ss_Tmp Countr VlaObj EntNam Dxf BksInf); not all locals needed are in the list
(defun Dxf (DxfCod EntDat) (cdr (assoc DxfCod EntDat)))
(if (setq Ss_Tmp (ssget "_X" (list '(0 . "INSERT") (cons 8 "RED"))))
(repeat (setq Countr (sslength Ss_Tmp))
(setq VlaObj (vlax-ename->vla-object (setq EntNam (ssname Ss_Tmp (setq Countr (1- Countr))))))
(setq BksInf
(cons
(list
(strcase (vla-get-Name VlaObj)) (strcase (vla-get-Layer VlaObj))
(strcase (DXF 410 (entget EntNam))) VlaObj
)
BksInf
)
)
)
); (("MAIN" "RED" "MODEL" #<VLA-OBJECT IAcadBlockReference 0000000034376448>) ...)
(foreach ForElm BksInf
(setq
BlkObj (cadddr ForElm) BlkEnt (vlax-vla-object->ename BlkObj)
FlgPln nil FlgHod nil BlkNam (strcat "ZZ_" (car ForElm))
Ss_Blk (ssadd) BlkIns (trans (DXF 10 (entget BlkEnt)) BlkEnt 1)
DorLst nil
)
(vl-cmdf "_.COPY" BlkEnt "" "_NONE" BlkIns "_NONE" BlkIns)
(setq EntNm0 (entlast))
(or
(vl-catch-all-error-p (setq ExpLst (vl-catch-all-apply (function (lambda () (vlax-invoke (vlax-ename->vla-object EntNm0) 'Explode))))))
(foreach ObjFor ExpLst
(setq ObjNam (vla-get-ObjectName ObjFor))
(cond
( (= ObjNam "AcDbHatch") (vla-delete ObjFor) )
( (= ObjNam "AcDbBlockReference") (setq BksTop (cons ObjFor BksTop)) )
( (= (setq TmpLyr (strcase (vla-get-Layer ObjFor))) "RED")
(ssadd (vlax-vla-object->ename ObjFor) Ss_Blk)
)
( (and (= ObjNam "AcDbArc") (> (vla-get-Radius ObjFor) 200) (= TmpLyr "CENTER"))
(setq DorLst (cons ObjFor DorLst)) ; I need this list to do something
)
( T (vla-delete ObjFor) )
)
)
)
(vl-cmdf "_.ERASE" EntNm0 "")
(or (tblsearch "BLOCK" BlkNam) (vl-cmdf "_.BLOCK" BlkNam "_NONE" BlkIns Ss_Blk ""))
(vl-cmdf "_.-INSERT" BlkNam "_NONE" BlkIns 1 1 0)
(vl-cmdf "_.ERASE" Ss_Blk "")
)
(foreach ForElm BksTop
(setq
BlkEnt (vlax-vla-object->ename ForElm)
BlkNam (strcat "ZZ_" (vla-get-Name ForElm))
Ss_Blk (ssadd) BlkIns (trans (DXF 10 (entget BlkEnt)) BlkEnt 1)
DorLst nil
)
(or
(vl-catch-all-error-p (setq ExpLst (vl-catch-all-apply (function (lambda () (vlax-invoke ForElm 'Explode))))))
(foreach ObjFor ExpLst
(setq ObjNam (vla-get-ObjectName ObjFor))
(cond
( (= ObjNam "AcDbBlockReference") (vla-delete ObjFor) )
( (= (setq TmpLyr (strcase (vla-get-Layer ObjFor))) "HIDDEN") (strcase (vla-get-Layer ObjFor))
(ssadd (vlax-vla-object->ename ObjFor) Ss_Blk)
)
( (and (= ObjNam "AcDbArc") (> (vla-get-Radius ObjFor) 200) (= TmpLyr "CENTER"))
(setq DorLst (cons ObjFor DorLst)) ; I need this list to do something
)
( T (vla-delete ObjFor) )
)
)
)
(or (tblsearch "BLOCK" BlkNam) (vl-cmdf "_.BLOCK" BlkNam "_NONE" BlkIns Ss_Blk ""))
(vl-cmdf "_.-INSERT" BlkNam "_NONE" BlkIns 1 1 0)
(vl-cmdf "_.ERASE" Ss_Blk "")
(vl-cmdf "_.ERASE" BlkEnt "")
)
)