Author Topic: Clone entities from blocks also nested  (Read 1404 times)

0 Members and 1 Guest are viewing this topic.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Clone entities from blocks also nested
« on: August 15, 2018, 04:07:03 AM »
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?

Code: [Select]
(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 "")
  )
)