Author Topic: freeze/thaw xref layer from text file  (Read 3114 times)

0 Members and 1 Guest are viewing this topic.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
freeze/thaw xref layer from text file
« on: February 08, 2013, 12:46:32 PM »
I have searched everywhere, and I cant find an example that will work.  What I want to do is freeze and thaw layers based on a text file.  I have that code, which works perfectly.
 
Code: [Select]
(DEFUN LAYERTHAW (LAYNAME)
(COMMAND "-LAYER" "THAW" LAYNAME "")
  )

(defun readcond ()
  (if (setq f (open "s:/TEPDotNet/conduit.ini" "r"))
    (progn
      (while (setq txtLine (read-line f))
 (layerthaw txtLine)
      )
      (close f)
    )
    (princ "\n Error - File was not opened.")
  )
)

What I cant find anywhere is how to search XREF layers for same string value.  I cant find an INSTR type function
« Last Edit: February 08, 2013, 05:22:31 PM by CAB »
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: freeze/thaw xref layer from textr file
« Reply #1 on: February 08, 2013, 12:48:55 PM »
ib4 "wcmatch"
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: freeze/thaw xref layer from text file
« Reply #2 on: February 08, 2013, 12:49:53 PM »
Thanks MP, now to go read up on that
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: freeze/thaw xref layer from text file
« Reply #3 on: February 08, 2013, 12:50:55 PM »
guess I should also ask if there is an easy way to read the layer collection
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)


irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: freeze/thaw xref layer from text file
« Reply #5 on: February 09, 2013, 01:30:57 AM »
What you have there is the command scripting method - i.e. sending commands to ACad. Note the -LAYER command uses the same wildcards as the wcmatch function does, but fortunately it's case insensitive so no need to worry about capital / lower case letters. So you can prefix the layer names with "*|" (use strcat to concatenate 2 or more strings together) to catch all the XRef layer names which match the current name read from the file. E.g. change your LayerThaw function to something like this:
Code - Auto/Visual Lisp: [Select]
  1. (defun XRefLayerThaw (Name)
  2.   (command "_.Layer" "_Thaw" (strcat "*|" Name) ""))

This is good to start off with, but it's limited since your program doesn't have much feedback about what's inside the DWG or what is happening. You either need to mix it with portions from the stuff below, or rather use one of the next 2 ideas. Going this route you have lots more control over what's happening, and also your program runs faster most of the time. Not to mention you don't clutter your command line with needless sends from the command function and messages from the commands.

(1) Original AutoLisp would be tblnext to step through tables - the layers are stored in a "table" (same as block definitions). That's a data-table structure inside the DWG (non-visual), not to be confused with a table entity which is a new entity type only available in later acads. (2) Or you could use the vlax/vla functions to step through the ActiveX layers collection of the active document, but then you need to convert the VBA samples to vla code (not too difficult once you get the hang of it).

I'm going to explain the original lisp method (I'll leave ActiveX for another time, or for you to try on your own):

Next, the returned value of tblnext gives a DXF data-list. Check the help for which code means what. Then you use assoc and cdr to extract the layer's name to check through the wcmatch. Note wcmatch is case sensitive so "Layer1" is not equal to "LAYER1" - you can convert text to upper/lower case using strcase. To include wildcard characters like "*" into the search string, you use strcat.

To change something through DXF codes you need its ename. But the list returned by tblnext does not include this. For that you need tblobjname, and you can then send that to entget to get the full DXF list. Then to change an item in a list you use subst to substitute a new item for an old one, the new one you generate using cons. And then finally you send the modified DXF list to entmod to actually modify the "entity" (in this case it's the layer).

Now in both ideas (DXF/ActiveX/even through command calls) it might be faster to read the entire file into a wcmatch pattern using strcat. Then remember to convert to upper case for in case the layer name is saved slightly different. Note a wc pattern can be separated by commas for multiple patterns in one. Here's what I mean:
Code - Auto/Visual Lisp: [Select]
  1. (defun XRefLayerThawFromFile  (FileName / file line pattern LayData)
  2.   (if (setq file (open FileName "r"))
  3.     (progn (setq pattern "") ;Initialize the pattern to an empty string
  4.            (while (setq str (read-line file)) ;Step through each line in the file
  5.              (setq pattern (strcat pattern ",*|" (strcase str)))) ;Add to the pattern with wildcard prefix
  6.            (close file) ;Always close files as soon as possible
  7.            (setq pattern (substr pattern 2)) ;Remove the 1st comma from the pattern
  8.            ;; Run through all layers in the DWG
  9.            (while (setq LayData (tblnext "LAYER" (not LayData)))
  10.              (if (wcmatch (strcase (cdr (assoc 2 LayData))) pattern) ;Check if current layer matches
  11.                ;; Modify the entity
  12.                (entmod (subst (cons 70 (logand (+ 2 4 16 32 64) (cdr (assoc 70 LayData)))) ;Construct the new dxf code 70 by removing the 1st bit
  13.                               (assoc 70 LayData) ;Get the old dxf code 70 from the list
  14.                               (entget (tblobjname "LAYER" (cdr (assoc 2 LayData)))) ;Get the full DXF list to modify
  15.                               )))))))
Note each standard function has a link to a page describing it. I've also added some comments so you can understand better.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

bchapman

  • Guest
Re: freeze/thaw xref layer from text file
« Reply #6 on: February 09, 2013, 02:20:23 AM »
Layerstate not a good application for what you are doing? Perhaps these tools will help (though I've not tested):

http://erecad.wikispaces.com/AutoCAD+layer+state+files

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: freeze/thaw xref layer from text file
« Reply #7 on: February 09, 2013, 05:55:42 AM »
Great post Irne - I can appreciate the time that you invested to thoroughly explain each method, complete with links to the documentation for every function mentioned, well done.

A minor suggestion:
Code - Auto/Visual Lisp: [Select]
  1. (logand (+ 2 4 16 32 64) (cdr (assoc 70 LayData)))
This of course assumes that only bits 0-6 will ever be used; I know that its incredibly unlikely that Autodesk will add more options to the Layer Group 70 code, but nevertheless, I would always opt for a general solution if possible.

I would use either:
Code - Auto/Visual Lisp: [Select]
  1. (boole 4 1 (cdr (assoc 70 LayData)))

Or, for readability of intent:
Code - Auto/Visual Lisp: [Select]
  1. (logand (~ 1) (cdr (assoc 70 LayData)))


David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: freeze/thaw xref layer from text file
« Reply #8 on: February 11, 2013, 08:28:41 AM »
thanks everyone!  It works great.  A little slow, but I can live with that till I can make time to improve it.
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: freeze/thaw xref layer from text file
« Reply #9 on: February 11, 2013, 09:02:11 AM »
Next question, I am getting an error when it tries to freeze the current layer.  Is there an easy way to pass this through?
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: freeze/thaw xref layer from text file
« Reply #10 on: February 11, 2013, 09:07:53 AM »
Next question, I am getting an error when it tries to freeze the current layer.  Is there an easy way to pass this through?

Building on Irneb's code:
Code: [Select]
(defun XRefLayerThawFromFile ( filename / clayer file line pattern laydata layname )
    (if (setq file (open filename "r"))
        (progn
            (setq pattern "")
            (while (setq str (read-line file))
                (setq pattern (strcat pattern ",*|" (strcase str)))
            )
            (close file)
            (setq pattern (substr pattern 2)
                  clayer  (strcase (getvar 'clayer))
            )
            (while (setq laydata (tblnext "LAYER" (not laydata)))
                (setq layname (strcase (cdr (assoc 2 laydata))))
                (if (and (wcmatch layname pattern) (/= layname clayer))
                    (entmod
                        (subst
                            (cons  70 (logand (~ 1) (cdr (assoc 70 laydata))))
                            (assoc 70 laydata)
                            (entget (tblobjname "LAYER" layname))
                        )
                    )
                )
            )
        )
    )
)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: freeze/thaw xref layer from text file
« Reply #11 on: February 11, 2013, 10:16:02 AM »
Everything is working, thanks guys.  I am having a regen issue though.  I have tried regen and regenall, and neither will make the layers appear UNTIL i switch to Layout space and back.  Then a regen will make the layers show.


Here is what I have so far
Code: [Select]
(defun XRefLayerThawFromFile (FileName / file line pattern LayData)
  (command "-layer" "thaw" "0" "on" "0" "set" "0" "")
  (while
    (setq laydata (tblnext "LAYER" (not laydata)))
     (setq layname (strcase (cdr (assoc 2 laydata))))
     (if (/= layname (strcase (getvar 'clayer)))
       (command "-layer" "freeze" layname "")

     )
  )
(if (setq file (open FileName "r"))
    (progn
      (setq pattern "")         ;Initialize the pattern to an empty string
      (while (setq str (read-line file));Step through each line in the file
   (setq pattern (strcat pattern "," (strcase str)))
      )               ;Add to the pattern with wildcard prefix
      (close file)         ;Always close files as soon as possible
      (setq pattern (substr pattern 2))   ;Remove the 1st comma from the pattern
      ;; Run through all layers in the DWG
      (while (setq LayData (tblnext "LAYER" (not LayData)))
   (if (wcmatch (strcase (cdr (assoc 2 LayData))) pattern)
               ;Check if current layer matches
     ;; Modify the entity
     (entmod
       (subst
         (cons 70
          (logand (+ 2 4 16 32 64) (cdr (assoc 70 LayData)))
         )            ;Construct the new dxf code 70 by removing the 1st bit
         (assoc 70 LayData)   ;Get the old dxf code 70 from the list
         (entget (tblobjname "LAYER" (cdr (assoc 2 LayData))))
               ;Get the full DXF list to modify
       )
     )
   )
      )
    )
  )
 
  (if (setq file (open FileName "r"))
    (progn
      (setq pattern "")         ;Initialize the pattern to an empty string
      (while (setq str (read-line file));Step through each line in the file
   (setq pattern (strcat pattern ",*|" (strcase str)))
      )               ;Add to the pattern with wildcard prefix
      (close file)         ;Always close files as soon as possible
      (setq pattern (substr pattern 2))   ;Remove the 1st comma from the pattern
      ;; Run through all layers in the DWG
      (while (setq LayData (tblnext "LAYER" (not LayData)))
   (if (wcmatch (strcase (cdr (assoc 2 LayData))) pattern)
               ;Check if current layer matches
     ;; Modify the entity
     (entmod
       (subst
         (cons 70
          (logand (+ 2 4 16 32 64) (cdr (assoc 70 LayData)))
         )            ;Construct the new dxf code 70 by removing the 1st bit
         (assoc 70 LayData)   ;Get the old dxf code 70 from the list
         (entget (tblobjname "LAYER" (cdr (assoc 2 LayData))))
               ;Get the full DXF list to modify
       )
     )
   )
      )
    )
  )
)
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: freeze/thaw xref layer from text file
« Reply #12 on: February 11, 2013, 10:19:15 AM »
You may notice I am running the file twice, I could not get the wildcards to work for local layer names as well as XREF layer names in 1 pass
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)