Author Topic: How to find nested non-graphical data associated with blocks  (Read 11537 times)

0 Members and 1 Guest are viewing this topic.

T.Willey

  • Needs a day job
  • Posts: 5251
Say you have a block that only has layers, text styles and dimension styles.  How do you know what is associated with that block?

I had a drawing with some layers that I couldn't purge, and I couldn't find associated with anything in the drawing, so I assumed they were associated with a block some how, but I didn't know how to check for it.  Is there a way?

Thanks in advance.

Edit: This is the routine I'm using to find the layers.
Edit:  Maybe it's not in blocks, and if so, then where else could it be?  I check viewports, not froze within there either.  Not sub-entities of old fashion polylines, or 'endblk' or 'seqend' entities.
« Last Edit: July 12, 2007, 12:28:37 PM by T.Willey »
Tim

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

Please think about donating if this post helped you.

jbuzbee

  • Swamp Rat
  • Posts: 851
Re: How to find nested non-graphical data associated with blocks
« Reply #1 on: July 12, 2007, 12:56:29 PM »
1. Blocks can only contain graphical objects.
2. Any vertical dictionaries?  AEC Walls etc.
3. APPID
4. Invisible graphical objects?
James Buzbee
Windows 8

Chuck Gabriel

  • Guest
Re: How to find nested non-graphical data associated with blocks
« Reply #2 on: July 12, 2007, 01:01:16 PM »
1. Blocks can only contain graphical objects.

You sure about that?  Build a drawing with some layers but no graphical entities.  Now insert that drawing into a new drawing.  You now have a block, that contains no graphical entities, in the host drawing, and all the layers from the drawing you inserted are contained in the host drawing.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: How to find nested non-graphical data associated with blocks
« Reply #3 on: July 12, 2007, 01:14:56 PM »
2. Any vertical dictionaries?  AEC Walls etc.
Quote from: Acad drawing
AEC_CLASSIFICATION_SYSTEM_DEFS
AEC_DISP_REPS
AEC_DISPLAY_PROPS_DEFAULTS
AEC_MASS_ELEM_STYLES
AEC_MATERIAL_DEFS
AEC_PROFILE_DEFS
AEC_PROPERTY_FORMAT_DEFS
AEC_PROPERTY_SET_DEFS
AEC_SLAB_STYLES
AEC_SLABEDGE_STYLES
AEC_WINDOW_STYLES
AECB_CIRCUITS
AECB_VOLTAGEDEFINITIONS
ASE_INDEX_DICTIONARY
I noticed in your post, in the other thread about my chase layer routine, you said something about these.  I will see if I can find anything in them.

3. APPID
How to check these?  I don't think I have ever worked with them.

4. Invisible graphical objects?
Nope.  I have a routine that looks for these, and none were found.


Thanks James.
Tim

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

Please think about donating if this post helped you.

Cathy

  • Guest
Re: How to find nested non-graphical data associated with blocks
« Reply #4 on: July 12, 2007, 02:48:49 PM »
Did you purge the blocks -- is it perhaps in a block with no block reference to it in the drawing? 

T.Willey

  • Needs a day job
  • Posts: 5251
Re: How to find nested non-graphical data associated with blocks
« Reply #5 on: July 12, 2007, 03:00:34 PM »
Did you purge the blocks -- is it perhaps in a block with no block reference to it in the drawing? 
I purged everything I could, and the layers were still there.
Tim

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

Please think about donating if this post helped you.

Cathy

  • Guest
Re: How to find nested non-graphical data associated with blocks
« Reply #6 on: July 12, 2007, 03:28:29 PM »
As a last resort, you can save it as a .dxf and then open the .dxf with a text editor and search for the layer name. 

T.Willey

  • Needs a day job
  • Posts: 5251
Re: How to find nested non-graphical data associated with blocks
« Reply #7 on: July 12, 2007, 03:49:14 PM »
2. Any vertical dictionaries?  AEC Walls etc.
How can I check these dictionaries?  When I look at them, their entries they are all AcDbZombieObjects (proxy objects).
Tim

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

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: How to find nested non-graphical data associated with blocks
« Reply #8 on: July 12, 2007, 05:34:23 PM »
I'm intrigued Tim, any chance you send me the file?

Promise to keep the contents confidential.

Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: How to find nested non-graphical data associated with blocks
« Reply #9 on: July 14, 2007, 03:07:44 PM »
_FindRefs

Code: [Select]
(defun _FindRefs ( handles / _FileToList _IndexDxfData _SortHandles _Princ _Main )

    ;;==========================================================================
    ;;
    ;;  _FindRefs.lsp
    ;;
    ;;  Written by Michael Puckett (MP) for Tim Willey.
    ;;
    ;;--------------------------------------------------------------------------
    ;;
    ;;  Version 1.0  2007/07/14  Original code.  MP.
    ;;
    ;;--------------------------------------------------------------------------
    ;;
    ;;  Uses a sledge hammer technique to find all references to
    ;;  the handles passed to the function.
    ;;
    ;;  For every handle passed will return the handle plus any
    ;;  entities / objects that reference it as handles. If no
    ;;  references are found for a handle it will be listed solo.
    ;;
    ;;  For example --
    ;;
    ;;      (_FindRefs '( "BOGUS" "9409" "940B" "940A" "9408" ))
    ;;
    ;;  Might return this --
    ;;
    ;;      (
    ;;          ( "BOGUS" ) ;; no references found.
    ;;          ( "9409" "1E1B1" "1E01F" "1E023" ...)
    ;;          ( "940B" "1E1B5" "1E559" "1DFA5" ...)
    ;;          ( "940A" "1E1B3" "1E559" "1DFA5" ...)           
    ;;          ( "9408" "1E1AF" "1DFFA" "1DFFC" ... )
    ;;      )
    ;;
    ;;==========================================================================
                   
    (defun _FileToList ( fullName / handle result stream )

        (cond
            (   (setq handle (open fullName "r"))
                (while (setq stream (read-line handle))
                    (setq result
                        (cons
                            stream
                            result
                        )
                    )
                )
                (close handle)
            )
        )

        (reverse result)

    )

    (defun _IndexDxfData ( dxfData / i handle reference owner result )

        (setq i 0)

        (foreach entry dxfData

            (cond
                (   (eq "  5" entry)
                    (setq handle (nth (1+ i) dxfData))
                )
                (   (and
                        (member entry '( "320" "330" "340" "350" "360" "1005"))
                        (/= "0" (setq reference (nth (1+ i) dxfData)))
                    )
                    (setq result
                        (if (eq handle (car (setq owner (car result))))
                            (cons
                                (append owner (list reference))
                                (cdr result)
                            )
                            (cons
                                (list handle reference)
                                result
                            )
                        )
                    )
                )
            )

            (setq i (1+ i))

        )

        (reverse result)

    )
   
    (defun _SortHandles ( handles )
   
        ;;  Caller's responsibility to pass valid data. Normalizes
        ;;  handles to same string length by padding with leading
        ;;  zeros so sorts properly.
   
        (if (and handles (< 1 (length handles)))
       
            (   (lambda ( / len )
                   
                    (setq len
                        (apply 'max
                            (mapcar 'strlen handles)
                        )
                    )
                   
                    (acad_strlsort
                        (mapcar
                           '(lambda ( handle )
                                (while (< (strlen handle) len)
                                    (setq handle (strcat "0" handle))
                                )
                                handle
                            )                       
                            handles                       
                        )
                    )   
                )
            )   
       
            handles
       
        )   

    )

    (defun _Princ ( x )

        (princ x)

        (princ) ;; empties the print queue immediately as well as make quiet

    )

    (defun _Main ( handles / tempfile index result cmdecho )
   
        (cond

            ;;  Do sanity checks on the argument passed to the
            ;;  function (something I normally don't do but in
            ;;  the public's interest) ...
           
            (   (or
           
                    (null handles)                  ;;  duh
                   
                    (not (listp handles))           ;;  duh
                   
                    (null (vl-list-length handles)) ;;  catch dotted pair
                   
                    (not                            ;;  not a list of strings
                        (apply 'and
                            (mapcar
                               '(lambda ( handle ) (eq 'str (type handle)))
                                handles
                            )
                        )
                    )
                )   
               
                (princ
                    (strcat
                        "Invalid call: "
                        "(_FindRefs " (vl-prin1-to-string handles) ")\n"
                        "Syntax: (_FindRefs listOfHandles)\n"
                        "Example: (_FindRefs '(\"1\" \"2\" \"3\"))\n"
                    )
                )
               
                nil
                               
            )   
           
            ;;  Rock and roll ...

            (   t
           
                ;;  write out a dxf file offor the current drawing,
                ;;  consume it, index it, then nuke the bastard
       
                (_Princ "Creating dxf index ... ")
               
                (setq cmdecho (getvar "cmdecho"))
               
                (setvar "cmdecho" 0)
               
                (vl-cmdf
                    ".dxfout"
                    (setq tempfile (vl-filename-mktemp "myapp.dxf"))
                    ""
                )
               
                (setvar "cmdecho" cmdecho)
       
                (setq index (_IndexDxfData (_FileToList tempfile)))
               
                (vl-file-delete tempfile)
       
                (princ "[done].\n")
       
                (_Princ "Scanning dxf index ... ")
       
                (setq result
                    (mapcar
                       '(lambda ( handle )
                            (cons handle
                                (_SortHandles
                                    (mapcar 'car
                                        (vl-remove-if-not
                                           '(lambda ( entry )
                                                (member handle (cdr entry))
                                            )
                                            index
                                        )
                                    )
                                )                             
                            )
                        )
                        (mapcar 'strcase handles)
                    )
                )
       
                (_Princ "[done].\n")
               
                result
       
            )           
        )   

    )

    (_Main handles)

)

c:Test

Code: [Select]
(defun c:Test ( / _Type _MsgHasRefs _MsgRef _MsgNoRefs _Main )

    (defun _Type ( handle / ename )
        (if (setq ename (handent handle))
            (cdr (assoc 0 (entget ename)))
            "NUL"
        )
    )

    (defun _MsgHasRefs ( handle )
        (princ
            (strcat
                "Entity / Object ["
                handle
                "] <"
                (_Type handle)
                "> is referenced by these Entities/Objects:\n\n"
            )
        )       
    )

    (defun _MsgRef ( handle )
        (princ
            (strcat
                "\t\t\t"
                handle
                " <"
                (_Type handle)
                ">\n"
            )
        )
    )

    (defun _MsgNoRefs ( handle )
        (princ
            (strcat
                "Entity / Object ["
                handle
                "] <"
                (_Type handle)
                "> is not referenced by any Entities/Objects.\n\n"
            )
        )
    )

    (defun _Main ( / references )

        (foreach x

            (_FindRefs
                (vl-remove-if-not
                   '(lambda ( handle ) (eq 'str (type handle)))
                    (mapcar
                       '(lambda ( layer / ename )
                            (if (setq ename (tblobjname "layer" layer))
                                (cdr (assoc 5 (entget ename)))
                            )
                        )
                       '(
                            "UnwantedLayer1"
                            "UnwantedLayer2"
                            "UnwantedLayer3"
                            "UnwantedLayer4"
                        )
                    )
                )
            )

            (cond
                (   (setq references (cdr x))
                    (_MsgHasRefs (car x))
                    (mapcar '_MsgRef references)
                    (princ "\n")
                )
                (   (_MsgNoRefs (car x))
                )
            )
        )

        (princ)

    )

    (_Main)

)

Output might be ...

Entity / Object [A50A] <LAYER> is referenced by these Entities/Objects:

    2F06F <ACAD_PROXY_OBJECT>
    2F070 <ACAD_PROXY_OBJECT>
    ...

Entity / Object [A51C] <LAYER> is referenced by these Entities/Objects:

    2F069 <ACAD_PROXY_OBJECT>
    2F06A <ACAD_PROXY_OBJECT>
    ...

Entity / Object [A51B] <LAYER> is referenced by these Entities/Objects:

    2F069 <ACAD_PROXY_OBJECT>
    2F06A <ACAD_PROXY_OBJECT>
    ...

Entity / Object [A519] <LAYER> is referenced by these Entities/Objects:

    2F10B <ACAD_PROXY_OBJECT>
    2F10D <ACAD_PROXY_OBJECT>
    ...


Hope it helps / let me know of any problems.

:)



Edits:
Forced handles to uppercase before search.
Implemented _SortHandles function.
Added missing 360 code to _IndexDxfData.
Added sample output.
« Last Edit: July 16, 2007, 11:25:21 AM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

jbuzbee

  • Swamp Rat
  • Posts: 851
Re: How to find nested non-graphical data associated with blocks
« Reply #10 on: July 15, 2007, 08:46:02 AM »
1. Blocks can only contain graphical objects.

You sure about that?  Build a drawing with some layers but no graphical entities.  Now insert that drawing into a new drawing.  You now have a block, that contains no graphical entities, in the host drawing, and all the layers from the drawing you inserted are contained in the host drawing.

The Layers aren't "in" the block - they would still be purgable.
James Buzbee
Windows 8

jbuzbee

  • Swamp Rat
  • Posts: 851
Re: How to find nested non-graphical data associated with blocks
« Reply #11 on: July 15, 2007, 08:55:10 AM »
Tim,
Using ADT 2006 when a drawing is "exported to AutoCAD" all AEC objects are converted to simple AutoCAD entities, and all AEC dictionaries are deleted as well (just tried this).  This might be a drawing from an earlier release, or converted some other way, because it created the proxy objects.  I'm wondering if you could just delete the AEC dictionaries?  That would be my next step.

Hope this helps.

jb
James Buzbee
Windows 8

Chuck Gabriel

  • Guest
Re: How to find nested non-graphical data associated with blocks
« Reply #12 on: July 15, 2007, 09:29:40 AM »
1. Blocks can only contain graphical objects.

You sure about that?  Build a drawing with some layers but no graphical entities.  Now insert that drawing into a new drawing.  You now have a block, that contains no graphical entities, in the host drawing, and all the layers from the drawing you inserted are contained in the host drawing.

The Layers aren't "in" the block - they would still be purgable.

Interesting.  I never realized that, but I guess it makes sense, because the layers still are not referenced by any graphical entities.  Thanks.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: How to find nested non-graphical data associated with blocks
« Reply #13 on: July 16, 2007, 11:29:23 AM »
Michael,

  Thanks for the code.  I will try and look at it today, but real work has been pushed on me, so not sure when I will get a minute to check it out.

James,

  I can try and erase the dictionaries and see what happens.  Thanks for the insight.  I'm not sure what version, or even what product our consultants are using, so I don't know if it's an older version than mine.
Tim

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

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: How to find nested non-graphical data associated with blocks
« Reply #14 on: July 16, 2007, 12:11:28 PM »
Hi Tim.

I can almost guarantee that if you delete the references to the layers as found by the _FindRefs function that you will be able to purge said layers. Of course you should use some caution when performing said deletion and make sure candidate entities to be nuked meet your criteria, which at this point I'm not privy to.

If it's ok to delete proxies (i.e. you've considered the ramifications of doing so and are ok with it) then try the following minimalist code on a copy of the offending model and see what happens.

Make sure you edit the layer names embedded in the code below as applicable, noting that it does nominal sanity checking on said layer names.

Code: [Select]
(defun c:Test2 ( / _NukeIfMeetsCriteria )

    (defun _NukeIfMeetsCriteria ( handle / ename )
   
        (vl-catch-all-apply
       
           '(lambda ( )
   
                (if
                    (eq "ACAD_PROXY_OBJECT" ;; what else?
                        (cdr
                            (assoc 0
                                (entget
                                    (setq ename
                                        (handent handle)
                                    )
                                )
                            )
                        )
                    )
                   
                    (entdel ename)           
                )
               
                (if (null (entget ename))     
                    (princ
                        (strcat
                            handle
                            " nuked.\n"
                        )
                    )
                )
            )           
        )                       
    )

    (foreach x
   
        (_FindRefs
            (mapcar
               '(lambda ( layer / ename )
                    (if (setq ename (tblobjname "layer" layer))
                        (cdr (assoc 5 (entget ename)))
                    )
                )
               '(
                    "StubbornLayer1" ;; edit me and my friends below
                    "StubbornLayer2"
                    "StubbornLayer3"
                    "StubbornLayer4"
                )
            )
        )
       
        (foreach handle (cdr x)
       
            (_NukeIfMeetsCriteria handle)
           
        )   
   
    )
   
    (setvar "cmdecho" 0)
   
    (command ".purge" "_la" "*" "_No") ;; will echo names of layers purged
   
    (princ)
   
)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst