Author Topic: ObjectDBX to gather all entities  (Read 1800 times)

0 Members and 1 Guest are viewing this topic.

AARYAN

  • Newt
  • Posts: 72
ObjectDBX to gather all entities
« on: July 28, 2020, 07:11:09 AM »
Hello All,

Hope everyone is staying safe and healthy! Its been long since I worked on AutoLISP to create a program. I am trying to achieve the tasks given below using ObjectDBX.

1. Gather all entities from modelspace of all xrefs. Some xrefs may contain multiple xrefs (should go as deep as it could).
2. Skip the unloaded xrefs at any level.

Here's my try but this works way slow and I don't know anyway to skip the unloaded xref from the ObjectDBX document.

Code: [Select]
(DEFUN SF$GETNESTED (VBLOCK ISDBXOPEN / VITEM)
  (IF (= :VLAX-TRUE (VLA-GET-ISXREF (SETQ VITEM (VLA-ITEM (VLA-GET-BLOCKS (IF ISDBXOPEN SF$DBXDOCUMENT (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)))) (LM:EFFECTIVENAME VBLOCK)))))
    (PROGN
      (SETQ SF$SPATH (VLA-GET-PATH VBLOCK))
      (IF (NOT (VL-POSITION SF$SPATH (MAPCAR 'VLA-GET-NAME SF$LDBXDOCS)))
(PROGN
  (SETQ SF$DBXDOCUMENT (LM:ODBX SF$SPATH))
  (SETQ SF$LDBXDOCS (CONS SF$DBXDOCUMENT SF$LDBXDOCS))))
      (SETQ AXDBMODELSPACE (VLA-GET-MODELSPACE SF$DBXDOCUMENT))
      (VLAX-FOR AXDBOBJECT AXDBMODELSPACE
(IF (= (VLA-GET-OBJECTNAME AXDBOBJECT) "AcDbBlockReference")
  (SF$GETNESTED AXDBOBJECT T)
  (SETQ SF$LENTITY (CONS (LIST AXDBOBJECT (VLA-GET-PATH VBLOCK)) SF$LENTITY)))))
    (PROGN
      (IF (NOT ISDBXOPEN) (SETQ SF$DBXDOCUMENT (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT))))
      (VLAX-FOR AXDBOBJECT (VLA-ITEM (VLA-GET-BLOCKS SF$DBXDOCUMENT) (LM:EFFECTIVENAME VBLOCK))
       (IF (= (VLA-GET-OBJECTNAME AXDBOBJECT) "AcDbBlockReference")
(SF$GETNESTED AXDBOBJECT ISDBXOPEN)
(SETQ SF$LENTITY (CONS (LIST AXDBOBJECT (IF SF$SPATH SF$SPATH NIL)) SF$LENTITY))))))
  SF$LENTITY
)

Code: [Select]
(SETQ SSOBJECT (SSGET))
(SETQ I 0)
(SETQ LOBJECTS NIL)
(REPEAT (SSLENGTH SSOBJECT)
      (SETQ SF$LENTITY NIL)
      (SETQ SF$SPATH NIL)
      (SETQ AXDBMODELSPACE NIL)
      (SETQ SUBOBJS NIL)
      (SETQ VOBJECT (VLAX-ENAME->VLA-OBJECT (SSNAME SSOBJECT I)))
      (IF (= (VLA-GET-OBJECTNAME VOBJECT) "AcDbBlockReference")
(SETQ SUBOBJS (SF$GETNESTED VOBJECT NIL)))
      (IF SUBOBJS
(SETQ LOBJECTS (APPEND SUBOBJS LOBJECTS))
(SETQ LOBJECTS (CONS (LIST VOBJECT NIL) LOBJECTS)))
      (PRINC "\rGathering objects...")
      (SETQ I (1+ I)))

For effective block function : http://www.lee-mac.com/effectivename.html
For ObjectDBX function : http://www.lee-mac.com/lisp/html/ObjectDBXWrapperV1-2.html

This code goes on each file and collects the objects but its very slow and sometimes it throws an error as well (forgot about it).

I hope I have explained clear enough. Any help would be appreciated.

Thanks

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: ObjectDBX to gather all entities
« Reply #1 on: July 28, 2020, 10:23:34 AM »
Are you processing each master DWG separately?
If so, I suppose you don't need ObjectDBX...
I am asking this because I don't see anywhere you call for opening DWGs from some folder - ObjectDBX predominately serves for purposes of gathereing or changing data of multiple DWGs at a time...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

AARYAN

  • Newt
  • Posts: 72
Re: ObjectDBX to gather all entities
« Reply #2 on: July 28, 2020, 10:44:45 AM »
Thanks for your reply Ribarm!

I am trying to collect all the entities from current drawing and the current drawing contains the xrefs and those xrefs contains multiple xrefs.

I want the program to return the list of entities from the every drawing it processed e.g. (list (list vlaobject1 (if xref path ""))  (list vlaobject2 (if xref path ""))) etc. In case if the xref is unloaded/not found it should skip those.

Using DBX, I am trying to gather the enitites without having the xrefs open in the editor. Once collected I would process those entities and filter out unnecessary objects.

If it is faster to filter the objects it searches then I would add the filter as (OR (EQ "CADWorx_Plant_Component" OBJTYPENAME) (EQ "AcDbLine" OBJTYPENAME))

Hope that makes sense. Please suggest.

AARYAN

  • Newt
  • Posts: 72
Re: ObjectDBX to gather all entities
« Reply #3 on: July 28, 2020, 10:51:45 AM »
The expected return list should contain the lists of (Entities "and if those entities are a part of an xref then it should return its path" else "")

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: ObjectDBX to gather all entities
« Reply #4 on: July 28, 2020, 10:56:51 AM »
But VLA-OBJECTS names may vary and are dependable of each open DWG session... Maybe I am wrong, but why would there be differences from normal ENAMES... In that context I'd suggest that you collect handles strings with/out paths if xref dependable...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

AARYAN

  • Newt
  • Posts: 72
Re: ObjectDBX to gather all entities
« Reply #5 on: July 28, 2020, 11:04:32 AM »
I am OK without the paths but I am unsure about the handles.

I will set the Xdata once I collect and filter the objects from all xrefs and nested xrefs. Thats the reason I was expecting a list of vla-objects because the drawings opened with DBX may not allow us to use vanilla lisp functions to add xdata.

An example of what your suggestion is would be helpful.

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: ObjectDBX to gather all entities
« Reply #6 on: July 28, 2020, 11:13:19 AM »
I never used ObjectDBX in this context, but if it can help you somehow, I use to use this lisp for gathering Xrefs/Blocks from master DWG... And never had a need to assign XDATA to entities gathered at a time like you are trying to do.
Lisp collects all Xrefs/Blocks and print them in txt file along with path data/names for Xrefs nested to any level deep inside DWG database...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

T.Willey

  • Needs a day job
  • Posts: 5251
Re: ObjectDBX to gather all entities
« Reply #7 on: July 28, 2020, 03:51:34 PM »
Just because it has been awhile since I played with ObjectDBX, and I was on my lunch break.  Here is a quick and dirty example of how to do what the OP wants (I think).

Code - Auto/Visual Lisp: [Select]
  1. (defun c:Test ( / doc lst )
  2.    
  3.     (defun getModelSpaceObjects ( doc / *error* blks tmp blk xpath dbxApp oVer rlst lst )
  4.         (defun *error* (msg)
  5.             (if dbxApp (vlax-release-object dbxApp))
  6.             (setq dbxApp nil)
  7.             (if msg
  8.                 (if (= msg "Function cancelled")
  9.                     (prompt "\n Function cancelled.")
  10.                 )
  11.             )
  12.         )
  13.         ;------------------------------------------------------------------
  14.         (setq blks (vla-get-Blocks doc))
  15.         (vlax-for i (vla-get-ModelSpace doc)
  16.             (setq tmp (vla-get-ObjectName i))
  17.             (if
  18.                 (and
  19.                     (= tmp "AcDbBlockReference")
  20.                     (setq blk (vla-Item blks (vla-get-Name i)))
  21.                     (equal (vla-get-IsXref blk) :vlax-true)
  22.                     (setq xpath (vla-get-Path blk))
  23.                     (or
  24.                         dbxApp
  25.                         (setq dbxApp
  26.                             (if (< (atoi (setq oVer (substr (getvar "acadver") 1 2))) 16)
  27.                                 (vla-GetInterfaceObject (vlax-get-acad-object) "ObjectDBX.AxDbDocument")
  28.                                 (vla-GetInterfaceObject (vlax-get-acad-object) (strcat "ObjectDBX.AxDbDocument." oVer))
  29.                             )
  30.                         )
  31.                     )
  32.                     (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-Open (list dbxApp xpath))))
  33.                     (setq rlst (getModelSpaceObjects dbxApp))
  34.                 )
  35.                 (setq lst (cons (list (vla-get-Handle i) tmp xpath rlst) lst))
  36.                 (setq lst (cons (list (vla-get-Handle i) tmp) lst))
  37.             )
  38.         )
  39.         (*error* nil)
  40.         lst
  41.     )
  42.    
  43.     (setq lst (getModelSpaceObjects doc))
  44.     (foreach i lst (print i))
  45.     (princ)
  46. )
  47.  

Example output:
Quote
Command: TEST
("12C3" "AcDbMText")
("12C1" "AcDbLine")
("12C0" "AcDbCircle")
("126F" "AcDbBlockReference" "I:\\z-Temp\\xr04.dwg" (("1239" "AcDbBlockReference" "I:\\z-Temp\\xr01.dwg" (("10B5" "AcDbLine") ("10B4" "AcDbLine") ("10B3" "AcDbLine") ("10B2" "AcDbLine"))) ("11A4" "AcDbPolyline")))
("11D8" "AcDbBlockReference" "I:\\z-Temp\\xr03.dwg" (("1156" "AcDbPolyline") ("1155" "AcDbPolyline")))
("1145" "AcDbBlockReference" "I:\\z-Temp\\xr02.dwg" (("1107" "AcDbCircle") ("1106" "AcDbCircle")))


EDIT (John): Fixed code tag (added a missing dash in tag name).
« Last Edit: July 28, 2020, 04:08:10 PM by John Kaul (Se7en) »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.