Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Unlocking layers is painfully slow.

11 REPLIES 11
SOLVED
Reply
Message 1 of 12
iwafb
1317 Views, 11 Replies

Unlocking layers is painfully slow.

HI All,

 

I have a suite of routines that rely on entities being on locked layers. In essence, everytime you need to work with one of those entities, the programs unlock all the possible layers and the user is able to manipulate the objects. Once finished, the layers get locked up again. These routines never had problems, untill the modeless layer dialogue was introduced (back in 2008??). Now it takes about 10+ seconds for the program to go through the lock or unlock process (the layerdlgmode variable didn't make any difference either):

 

   (setq pind 0)
 (repeat (length pdpurlinlist)
    (command "_.-layer" "unlock" (nth pind pdpurlinlist) "")
    (setq pind (+ 1 pind))
 )

 

Curious thing is that if the layers are already unlocked, the code gets executed almost instantly. If the layer were locked and the program has to unlock them, then it takes about 10 seconds to unlock 4 layers.

 

Has anyone else found a similar problem and is there an alternative way to lock/unlock layers in lisp which might process a bit quicker?

 

Thanks in advance.

John

11 REPLIES 11
Message 2 of 12
Kent1Cooper
in reply to: iwafb


@iwafb wrote:

....  the programs unlock all the possible layers and the user is able to manipulate the objects. Once finished, the layers get locked up again. ....it takes about 10+ seconds for the program to go through the lock or unlock process.... 

....is there an alternative way to lock/unlock layers in lisp which might process a bit quicker?

....


Try something like this:

(setq layUlist ; list of locked layers among those in pdpurlinlist
  (vl-remove-if-not
    '(lambda (lay)
      (= (logand (cdr (assoc 70 (tblsearch "layer" lay))) 4) 4)
    ); end lambda
    pdpurlinlist
  ); end vl-remove-if-not
); end setq
(foreach lay layUlist ; unlock those layers
  (setq
    laydata (entget (tblobjname "layer" lay))
    laydata 
      (subst
        (cons 70 (- (cdr (assoc 70 laydata)) 4))
        (assoc 70 laydata)
        laydata
      ); end subst
  ); end setq
  (entmod laydata)
); end foreach
;;;;..........do your thing to the objects..........
(foreach lay layUlist ; re-lock those layers
  (setq
    laydata (entget (tblobjname "layer" lay))
    laydata 
      (subst
        (cons 70 (+ (cdr (assoc 70 laydata)) 4))
        (assoc 70 laydata)
        laydata
      ); end subst
  ); end setq
  (entmod laydata)
); end foreach
Kent Cooper, AIA
Message 3 of 12
Kent1Cooper
in reply to: iwafb


@iwafb wrote:

....

   (setq pind 0)
 (repeat (length pdpurlinlist)
    (command "_.-layer" "unlock" (nth pind pdpurlinlist) "")
    (setq pind (+ 1 pind))
 )

....


By the way, though it may not save any time if the (command) approach is the cause of the delay, there is a simpler way to do this, when it's a list you're working on [not, for example, a selection set]:

 

(foreach lay pdpurlinlist

  (command "_.layer" "unlock" lay "")
)

 

But that still invokes the (command) function for every Layer involved, which is likely the biggest time-consumer.  It probably would save time, even if using (command), to use it only once:

 

(setq layUlist ""); initial empty string

(foreach lay pdpurlinlist (setq layUlist (strcat layUlist lay ","))); comma-delimited string of Layer names

(command "_.layer" "_unlock" layUlist "")

 

Your original and these other approaches would unlock all Layers in the list.  But your original message suggests that you would need to know which are locked when you start, so you can lock them again later, without also locking Layers that were not locked when you started.  That made me think maybe your pdpurlinlist was already a list of only locked Layers, but that doesn't jive with your statement that "if the layers are already unlocked, the code gets executed almost instantly."  I don't know how you've been doing the re-locking [maybe you've been locking Layers that were unlocked before], but my earlier suggestion makes such a pared-down list, so you can use it again later to re-lock only the Layers that were locked.

Kent Cooper, AIA
Message 4 of 12
dgorsman
in reply to: Kent1Cooper

Might the faded color feature of locked layers have something to do with the delay?  Seems that as each layer is locked/unlocked the screen would be updated, which could account for the extra time involved.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 5 of 12
iwafb
in reply to: iwafb

Thanks to all for your suggestions.

 

I was not aware of Kent's approach in staying away from using the command method. I will definitely give that a try.

 

Just to clarify, pdpurlinlist is a list of all locked layers. I only noticed the difference in time because while I was running testing I couldn't figure out why sometimes the program stepped through those lines in no time, and sometimes it hang. Under normal circumstances, the layers would always be locked before execution. Sorry about the confusion.

 

Also, I turned fading off for locked layers as I didn't like it. Still, this program never seemed to hang prior to about Acad2007. So there might be some merit in dgorsman's thinking??

 

Thanks again

John

 

BTW - I've actually gained two "nuggets of wisdom" from this post, as I've never really used the foreach approach given that I didn't really understand the advantages. Will consider a lot more in the future...

Message 6 of 12
Kent1Cooper
in reply to: iwafb


@iwafb wrote:

.... 

Just to clarify, pdpurlinlist is a list of all locked layers. ....


In that case, you could eliminate my initial (setq) function entirely, and just substitute pdpurlinlist in place of layUlist in both (foreach) functions.

Kent Cooper, AIA
Message 7 of 12
iwafb
in reply to: Kent1Cooper

Done and it works absolutely perfect!!! Routine now has no lag at all.

 

Can you maybe shed some light on this though?

 

The only difference I can see in the two function is the + or - in the cons line. I kind of assumed this would be the switch to lock/unlock the layer, which seems to be the case witht he - (unlock). However, the + (lock) seems to work more as a toggle? That is if the layer is locked it will unlock it and viceversa. Is that the way it works?

 

Thanks

John

Message 8 of 12
Kent1Cooper
in reply to: iwafb


@iwafb wrote:

....

The only difference I can see in the two function is the + or - in the cons line. I kind of assumed this would be the switch to lock/unlock the layer, which seems to be the case witht he - (unlock). However, the + (lock) seems to work more as a toggle? That is if the layer is locked it will unlock it and viceversa. Is that the way it works?

....


The information about a Layer that you get from either

(tblsearch "layer" "YourLayerName")

or

(entget (tblobjname "layer" "YourLayerName"))

contains an entry that looks like this:

(70 . 0)

except that the second number isn't always a 0.  It's a binary-bit code that holds information about a couple of things.  If it's 0, the Layer is thawed and unlocked.  If the Layer is frozen, that second number includes the 1 binary bit.  If it's locked, it includes the 4 bit.  If it's frozen but not locked, it will be 1; if it's locked but not frozen, it will be 4; and if it's both locked and frozen, it will be 5 [the sum of the other two].  I'm not sure whether other binary-bit numbers [2, 8, 16, etc.] are used, but knowing that the 4 bit is about locking is all that's necessary here.

 

If a Layer is locked, the number paired with the 70 will be 4 or 5 [or if 2 is used for something I'm not aware of, possibly 6 or 7, etc., but always something whose makeup as a sum of power-of-2 integers includes a 4] -- subtracting 4 from whatever it is will unlock the Layer.  If it's unlocked, that number will be 0 or 1 [or 2 or 3 or 8 or 9, etc., but always something whose powers-of-2 makeup does not include a 4] -- adding 4 to whatever it is will lock the Layer.

 

The (cdr) functions find the current value paired with 70, the (cons) functions pair the result of subtracting or adding 4 from or to that with a 70, the (subst) functions replace the old 70-code pair with the new one, and the (entmod) functions impose that change on the database.

Kent Cooper, AIA
Message 9 of 12
iwafb
in reply to: iwafb

Wow, I had never really understood it's use. Thanks for your explanation and all your help...

Message 10 of 12
Anonymous
in reply to: Kent1Cooper

Kent, I like how you use tblsearch to move through the layer list. Nice code. Just for giggles, here is something I use in my routines to unlock all layers. I set a variable to create a list of all locked layers (if any) and use that list at the end of the routine to lock them again.

 

; SETQ "DOC" TO THE ACTIVE DOCUMENT.
(setq doc (vla-get-ActiveDocument (vlax-get-Acad-Object)))

 

; UNLOCK ALL LAYERS
(vlax-for item (vla-get-layers doc)
 (if (= (vlax-get-property item "Lock") :vlax-true)
  (progn
   (setq Locked_Layers (cons item Locked_Layers))  ; SET VARIABLE "LOCKED_LAYERS" TO ALL LOCKED LAYERS.
   (vlax-put-property item "Lock" :vlax-false)               ; UNLOCK EACH LAYER IF IT IS LOCKED.
  ); end progn
 ); end if
); end vlax

 

(*** Place your code here ***)

 

; IF ANY LAYERS WERE LOCKED AT THE BEGINNING, LOCK THEM AGAIN.
(if Locked_Layers
  (mapcar '(lambda(x)(vlax-put-property x "Lock" :vlax-true)) Locked_Layers)
); end if

 

 

Jim

 

Message 11 of 12
markruys2
in reply to: iwafb

you can use a simpler approach

 

(command "._-layer")

(foreach lay laylist (command "_unlock" lay))

(command "")

Message 12 of 12
Kent1Cooper
in reply to: markruys2


@markruys2 wrote:

you can use a simpler approach

 

(command "._-layer")

(foreach lay laylist (command "_unlock" lay))

(command "")


[Look back at Messages 3 for a similar approach, and 7 for confirmation that the (command) function was apparently the cause of the slowness.  I imagine nesting (command) functions inside each other would only exacerbate that.]

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost