Author Topic: Freezing/Thawing Layers by Wildcard Match.  (Read 12734 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Freezing/Thawing Layers by Wildcard Match.
« on: November 10, 2014, 08:10:01 AM »

I'm looking at a project that has about 320 Layers including XRef layers.

I need to Freeze / thaw layers depending on  wildcard matches (multiple combinations of course).
There are about 40 wildcard matches that have to be satisfied.

I've tried entity dxf mods, ActiveX mods and a dot.net plug-in to change the Layer states according to the wildcard strings.

All the above methods require the iteration of the Layer table  and wcmatching the layer name against a ( or several) filters.

I am unable to find any method that is faster than a simple vl-cmdf or command-s command call and pass the multiple filters comma seperated.
ie:
(vl-cmdf "_.layer" "_ON" dataThawList "_thaw" dataThawList "")
(vl-cmdf "_.layer" "_f" "XR*02)*,XR*cotes*" "")

.. and the bonus is the command does not require a regen of the viewport.

Has anyone come across a code solution that is faster than vl-cmdf or command-s for handling complex wildcard nominations.

The command method is actually reasonably fast, but I want to satisfy due diligence.

Regards,
Kerry
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #1 on: November 10, 2014, 08:54:16 AM »
Hello Kerry!  :-)

Publish here an example of your file for testing.
I have a lot of different codes for solving the problem,
 but never did serious research.

 I'm curious!
 :-D

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #2 on: November 10, 2014, 12:10:00 PM »
Thanks for pointing this out, I had never tested before and I thought that without command was faster...
Code: [Select]
Comando: (length (ALE_GetTableNames    "LAYER")) >>> 407

Benchmark.lsp | © 2005 Michael Puckett | All Rights Reserved

Elapsed milliseconds / relative speed for 128 iteration(s):
    (CMDF_LAYERON)......1763 / 8.57 <fastest>
    (ALE_LAYERON)......15101 / 1 <slowest>

Elapsed milliseconds / relative speed for 64 iteration(s):
    (CMDF_LAYERON).....1685 / 3.08 <fastest>
    (ALE_LAYERON)......5195 / 1 <slowest>

Elapsed milliseconds / relative speed for 64 iteration(s):
    (CMDF_LAYERON).....1653 / 4.62 <fastest>
    (ALE_LAYERON)......7629 / 1 <slowest>

lapsed milliseconds / relative speed for 128 iteration(s):
    (CMDF_LAYERON)......1981 / 6.51 <fastest>
    (CMDF_LAYERON)......2637 / 4.89
    (CMDF_LAYERON)......3073 / 4.2
    (ALE_LAYERON).......9375 / 1.38
    (ALE_LAYERON)......11793 / 1.09
    (ALE_LAYERON)......12902 / 1 <slowest>


Code: [Select]
(defun cmdf_LayerON ( )
 (vl-cmdf "_.layer" "_Off" "*$???_*" "_Y" "")
 (vl-cmdf "_.layer" "_ON" "*$???_*" "")
)
(defun ALE_LayerON ( )
 (ALE_Layer_PutOnAll *AcAcDwg* *AcLayrs* '(("_ON" . "*$???_*")))
 (ALE_Layer_PutOnAll *AcAcDwg* *AcLayrs* '(("_Off" . "*$???_*")))
)

; Function: ALE_Layer_PutOnAll
;
; Version 1.00 - 16/11/2006

; Description:
;   Put Layers On or Off
;
; Arguments:
;   VlaDoc: IAcadDocument: An AutoCAD drawing or IAxDbDocument: Interface
;   LrsCol: Layer Collection
;   ChgLst: list of dotted pairs Layers commands and names in reverse order
;           (used reverse order because I use cons to build the list rather than append), example:
;           (("_OFF" . "*_Abc*") ("_ON" . "*Com_*") ("_ON" . "~*$*") ("_ON" . "*Xyz_*") ("_OFF" . "*|$*,$*"))
;           first  element = command      > "_ON" or "_OFF"  case insensitive
;           second element = layers names > see WcMatch      case insensitive
;
; Examples:
;   (or *AcadApp* (setq *AcadApp* (vlax-get-Acad-Object)            ))
;   (or *AcAcDwg* (setq *AcAcDwg* (vla-get-ActiveDocument *AcadApp*)))
;   (or *AcLayrs* (setq *AcLayrs* (vla-get-Layers         *AcAcDwg*)))
;
;   (ALE_Layer_PutOnAll *AcAcDwg* *AcLayrs* '(("_OFF" . "*_Abc*") ("_ON" . "*Com_*")))
;   ==> On Layers "*COM_*" than Off Layers "*_ABC*"
;
;   (ALE_Layer_PutOnAll *AcAcDwg* *AcLayrs* '(("_ON" . "*")))
;   ==> On all layers
;
; Return Values: VLA-OBJECT IAcadLayers 
;
(defun ALE_Layer_PutOnAll (VlaDoc LrsCol ChgLst / LyrNam BitVal)
  (setq ChgLst (reverse (read (strcase (vl-prin1-to-string ChgLst)))))
  (vlax-map-Collection
    LrsCol
   '(lambda (LmbDat)
      (setq
        BitVal nil
        LyrNam (strcase (vla-get-Name LmbDat))
      )
      (foreach ForElm ChgLst
        (if (wcmatch LyrNam (cdr ForElm))
          (if (= (car ForElm) "_ON") (setq BitVal 1) (setq BitVal 0))
        )
      )
      (and
        BitVal
        (if (zerop BitVal)
          (vl-catch-all-apply 'vla-put-LayerOn (list LmbDat :vlax-false))
          (vl-catch-all-apply 'vla-put-LayerOn (list LmbDat :vlax-true ))
        )
      )
    )
  )
)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #3 on: November 10, 2014, 01:43:11 PM »
@ Marc'Antonio Alessi:
Maybe the vl-catch-all-apply stucture is slowing things down? I am not sure why you use it.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #4 on: November 10, 2014, 03:40:21 PM »
Hello Kerry!  :-)

Publish here an example of your file for testing.
I have a lot of different codes for solving the problem,
 but never did serious research.

 I'm curious!
 :-D

Hi Evgeniy,
I don't have a generic sample drawing available at the moment, and I can't publish my clients drawings and xrefs.
I'll attempt to post an example later today.

Hi Marc'Antonio Alessi,
Those are the sort of execution time  relationships I'm seeing as well,


// ----------------

Regards,
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

BlackBox

  • King Gator
  • Posts: 3770
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #5 on: November 10, 2014, 04:00:22 PM »
.. and the bonus is the command does not require a regen of the viewport.

Has anyone come across a code solution that is faster than vl-cmdf or command-s for handling complex wildcard nominations.

The command method is actually reasonably fast, but I want to satisfy due diligence.

This has been my finding as well; I'm not adept at ARX, CRX, etc. but presumably one of them was used to write the Layer Commands, just not sure if those APIs are exposed, even if proficient at that language (if that makes sense?).



Only loosely related, Autodesk has exposed 'more' in terms of the Bindable Object Layer (BOL), but BOL is used more for near-instant event handling when Layers are created, modified, or deleted, and only really capable of limited modification of same, so not useful for your specific task.

Cheers
« Last Edit: November 10, 2014, 04:09:29 PM by BlackBox »
"How we think determines what we do, and what we do determines what we get."

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #6 on: November 10, 2014, 04:07:13 PM »
@ Marc'Antonio Alessi:
Maybe the vl-catch-all-apply stucture is slowing things down? I am not sure why you use it.
It is to avoid problems when I process many files, I think the difference is very small:
Code: [Select]
Elapsed milliseconds / relative speed for 256 iteration(s):
    (CMDF_LAYERON)......2122 / 5.77 <fastest>
    (ALE_LAYERON2).....11606 / 1.06
    (ALE_LAYERON)......12246 / 1 <slowest>

Elapsed milliseconds / relative speed for 256 iteration(s):
    (CMDF_LAYERON)......2012 / 7.75 <fastest>
    (ALE_LAYERON)......12855 / 1.21
    (ALE_LAYERON2).....15600 / 1 <slowest>
Code: [Select]
(defun ALE_Layer_PutOnAll2 (VlaDoc LrsCol ChgLst / LyrNam BitVal)
  (setq ChgLst (reverse (read (strcase (vl-prin1-to-string ChgLst)))))
  (vlax-map-Collection
    LrsCol
   '(lambda (LmbDat)
      (setq
        BitVal nil
        LyrNam (strcase (vla-get-Name LmbDat))
      )
      (foreach ForElm ChgLst
        (if (wcmatch LyrNam (cdr ForElm))
          (if (= (car ForElm) "_ON") (setq BitVal 1) (setq BitVal 0))
        )
      )
      (and
        BitVal
        (if (zerop BitVal)
          (vla-put-LayerOn LmbDat :vlax-false)
          (vla-put-LayerOn LmbDat :vlax-true)
        )
      )
    )
  )
)
Here is my sample.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #7 on: November 10, 2014, 04:28:06 PM »
Thanks for the drawing example Marc'Antonio Alessi,

For an even playing field ;

Layers that match the WildCard filter list are to be turned ON and THAWED,
All other Layers are to be turned FROZEN

With the exception of '0' and 'defpoints' which are to stay ON and THAWED.

I'll be extremely surprised if any solution is faster and less error prone than vl-cmdf or command-s

Thanks for the input.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #8 on: November 10, 2014, 08:15:36 PM »
Dunno how fast it is but quickly coded and posted for fun / your consideration:

Did blind, absolutely painful edit on an iPad, hopefully works.

Code: [Select]
(defun _ThawLayers ( filter invert_filter / @Match @Main )

    ;;  Thaw and turn on layers that match the filter,
    ;;  otherwise freeze and turn off, with special
    ;;  treatment of layer "0" and "Defpoints".
    ;;
    ;;  Syntax:
    ;;
    ;;      Thaw layers matching the filter:
    ;;
    ;;          (_ThawLayers "*support*,*e" nil)
    ;;
    ;;      Thaw layers NOT matching the filter (read another
    ;;      way -- freeze layers matching the filter):
    ;;
    ;;          (_thawlayers "*weld*,*gaskets*,*bolts*" t)

    (vl-load-com)

    (if invert_filter
        (defun @Match ( x ) (not (wcmatch x filter))) ;; filter is a
        (defun @Match ( x ) (wcmatch x filter))       ;; lexical global
    )

    (defun @Main ( doc filter clayer / name off frozen)

        ;;  group existing states etc ...

        (vlax-for layer (vla-get-layers doc)

            (cond

                (   (eq clayer
                        (setq
                            off    (eq :vlax-false (vla-get-layeron layer))
                            frozen (eq :vlax-true (vla-get-freeze layer))
                            name   (strcase (vla-get-name layer))
                        )
                    )
                    (if (@Match name)
                        ;;  you can only feck the on state
                        ;;  for the active layer -- try to
                        ;;  change the freeze state and kaboom
                        (vla-put-layeron layer :vlax-true)
                    )
                )

                (   (member name '("0" "DEFPOINTS"))
                    (vla-put-freeze layer :vlax-false)
                    (vla-put-layeron layer :vlax-true)
                )

                (   off
                    (if frozen
                        (if (@Match name)
                            (progn
                                (vla-put-layeron layer :vlax-true)
                                (vla-put-freeze layer :vlax-false)
                            )
                        )
                        (if (@Match name)
                            (vla-put-layeron layer :vlax-true)
                            (vla-put-freeze layer :vlax-true)
                        )
                    )
                )

                (   (if frozen
                        (if (@Match name)
                            (vla-put-freeze layer :vlax-false)
                            (vla-put-layeron layer :vlax-false)
                        )
                        (if (not (@Match name))
                            (progn
                                (vla-put-layeron layer :vlax-false)
                                (vla-put-freeze layer :vlax-true)
                            )
                        )
                    )
                )
            )
        )

        (princ)

    )

    (@Main
        (vla-get-activedocument (vlax-get-acad-object))
        (strcase filter)
        (strcase (getvar 'clayer))
    )

)

Cheers.
« Last Edit: November 11, 2014, 11:15:48 AM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #9 on: November 10, 2014, 08:55:13 PM »

Thanks Michael,

I'll test it tonight, but from first glance that looks functionally equivalent to my ActiveX effort
... though mine is not as pretty :-)  .. and not as artistically documented

Regards,
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

BlackBox

  • King Gator
  • Posts: 3770
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #10 on: November 10, 2014, 11:52:30 PM »
Can you post a snippet / summary of your .NET code? Did you iterate via IEnumerable, or employ LINQ, etc?

Cheers
"How we think determines what we do, and what we do determines what we get."

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #11 on: November 11, 2014, 01:49:48 AM »

Thanks Michael,

I'll test it tonight, but from first glance that looks functionally equivalent to my ActiveX effort
... though mine is not as pretty :-)  .. and not as artistically documented

Regards,

Most welcome Kerry. Revised it (blind). Thinking it should be faster but it might chuck a wobbly. :dunno:
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #12 on: November 11, 2014, 03:16:38 AM »
Using BricsCAD the difference between the command and the Visual Lisp solutions is much smaller. And using vle-start-transaction and vle-end-transaction the speed of the VL solution can even be improved.

Tested with the dwg and original code from Marc'Antonio Alessi and:
Code: [Select]
(defun ALE_LayerON_Transaction ( )
  (vle-start-transaction)
  (ALE_Layer_PutOnAll *AcAcDwg* *AcLayrs* '(("_ON" . "*$???_*")))
  (ALE_Layer_PutOnAll *AcAcDwg* *AcLayrs* '(("_Off" . "*$???_*")))
  (vle-end-transaction)
)

Code: [Select]
Benchmarking .......... elapsed milliseconds / relative timing <64 iterations>

  (CMDF_LAYERON) ................ 1484 / 1.32 <fastest>
  (ALE_LAYERON_TRANSACTION) ..... 1766 / 1.11
  (ALE_LAYERON) ................. 1953 / 1.00 <slowest>

Note: The first speed test will be unreliable because all layers are ON in the drawing.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #13 on: November 11, 2014, 03:27:49 AM »
AutoCAD 2013, maybe this is not the right comparison:
Code: [Select]
(defun _ThawLayers_MP ( )
  (_ThawLayers '("*$???_*") nil)
  (_ThawLayers '("*$???_*") T)
)
Code: [Select]
Elapsed milliseconds / relative speed for 256 iteration(s):
    (CMDF_LAYERON)........1373 / 30.4 <fastest>
    (ALE_LAYERON)........20530 / 2.03
    (_THAWLAYERS_MP).....41746 / 1 <slowest>

stange behaviour on my All_layers.dwg:
 (_ThawLayers '("$???_*") t) => do not freeze "$FDT_NORM"

Now I try in Bricscad V15 with roy_43 suggestion...

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
Re: Freezing/Thawing Layers by Wildcard Match.
« Reply #14 on: November 11, 2014, 03:45:25 AM »
Code: [Select]
Bricscad V15 DWG with 3 layers:  0  $LAY_NORM   Defpoints   
Elapsed milliseconds / relative speed for 8192 iteration(s):
    (ALE_LAYERON).........1186 / 15.46 <fastest>
    (_THAWLAYERS_MP)......1809 / 10.13
    (CMDF_LAYERON).......18330 / 1 <slowest>
Code: [Select]
Bricscad V15 All_Layers.dwg:
Elapsed milliseconds / relative speed for 64 iteration(s):
    (ALE_LAYERON)....................1778 / 2.77 <fastest>
    (ALE_LAYERON_TRANSACTION)........2465 / 2
    (CMDF_LAYERON)...................3167 / 1.56
    (_THAWLAYERS_MP).................3307 / 1.49
    (_THAWLAYERS_MP_TRANSACTION).....4930 / 1 <slowest>
Code: [Select]
Bricscad V15 All_Layers.dwg 2° round:
Elapsed milliseconds / relative speed for 32 iteration(s):
    (ALE_LAYERON)....................1077 / 3.56 <fastest>
    (CMDF_LAYERON)...................1326 / 2.89
    (_THAWLAYERS_MP_TRANSACTION).....1747 / 2.2
    (ALE_LAYERON_TRANSACTION)........3089 / 1.24
    (_THAWLAYERS_MP).................3837 / 1 <slowest>