Jump to content

Layerstate-restore and VP Freeze


nmulder

Recommended Posts

I need some input. I have created a LISP routine that, after .las selection from user, will restore the layerstate through the viewport. At least that is what I am going for. Our CAD dept. has as a standard importing a given layer state through the viewport to not only restore the frozen/off layers, but to also vpfreeze the layers. When a model space layer state is imported through a viewport, it also vp freezes the frozen layers for that viewport.

 

I am trying to get the LISP to automate that. First, I am not sure if my counter is working correctly (to import .las into multiple vports, if applicable). Second, when a layer state is restored by LISP it doesn't seem to vpfreeze, though all other layer settings are restored.

 

If layerstate-restore command works a little different than doing it manually, I'd like to incorporate code to vpfreeze the frozen layers as part of the same routine, to match company standard.

 

Any help is appreciated.

 

Thanks.

 

Here is my code:

 

(defun c:ILS2 (/ _path laspath lasfile las_use)

(vl-load-com)

(setvar "ctab" "layout")

(setq _path (getvar "dwgprefix"))

(setq laspath (strcat _path "Xrefs\\"))

(setq lasfile (getfiled "Select a Layer States(.LAS) file to import:" laspath "las" 16))

(layerstate-import lasfile)

(setq las_use (vl-filename-base lasfile))

(setq vp_set (ssget "x" (list (cons 0 "Viewport"))))

(setq cntr 1)

(while (

(command ".mspace")

(layerstate-restore las_use)

(setq cntr(+ cntr 1))

)

(command ".pspace")

(princ)

)

Link to comment
Share on other sites

not sure if this would work?

 

(defun c:ILS2  (/ path file vp_set)
 (vl-load-com)
 (and (vl-file-directory-p
        (setq path
          (strcat (getvar "DWGPREFIX") "Xrefs\\")))
      (setq file (getfiled "Select a Layer States (.las) file" path "las" 16))
      (layerstate-import file)
      (setq vp_set (ssget "_X" (list (cons 0 "VIEWPORT"))))
      (mapcar
        (function
          (lambda (x)
            (layerstate-restore
              (vl-filename-base file) x 2)))
        (mapcar 'cadr (ssnamex vp_set))))
 (princ))

Link to comment
Share on other sites

thanks for the reply. i'm not entirely sure of all the changes you made, but it seems to not enter a viewport to restore the layerstate, and then vp freezes everything in paperspace. i did notice though that it does vp freeze the frozen layers. what part of the code is doing that?

Link to comment
Share on other sites

If you look up layerstate-restore in the Visual LISP Editor help files, it gives a great deal of information about the arguments it uses. The "2" within that function is causing the layers to freeze.

Link to comment
Share on other sites

can you explain to me mapcar and lambda? i don't understand the help files on these functions.

 

i follow the flags (1, 2, 4, etc) for layerstate-restore, but i don't understand why your code vpfreezes, and doesn't freeze, and why mine freezes but doesn't vp freeze. looks to me like i am calling the same layerstate-restore function as you. i'd like both to occur as part of the routine. thanks for your time.

 

i also checked out some of the links to your lsp. impressive! maybe i'll get there someday.

Link to comment
Share on other sites

Thanks :D I'm sure you will.

 

As for the incongruence between your code and mine, I believe it has something to do with this:

 

viewport An ename (ads_name) of the viewport to which layerstatename should be restored. If viewport is nil, the layer state is restored to model space.

 

As quoted from ACAD help, I have supplied an ename, whereas you haven't, so maybe, you just need to ignore the viewports and just call layerstate-restore without the viewport argument to get the desired result?
Link to comment
Share on other sites

As for Mapcar and Lambda, I have recently written a Tutorial on these, but the article has yet to be published in the FAQ, here is a copy/paste version:

 

What is Mapcar & How do I use the Lambda Function?

 

Main Author: Lee McDonnell

Last Updated: 13th June 2009 [First Draft]

 

In my experience, the mapcar and lambda functions are two of the least understood functions in the AutoLISP programming language, however, when understood and used correctly, they can replace superfluous code and are powerful functions for dealing with lists.

 

The Mapcar Function

 

 

Put simply, mapcar will apply a function to each member of a list (or multiple lists), and will return a list of the results of applying such function.

 

Mapcar is invoked using the following format:

(mapcar <function> <list1> <list2> ... <listn>)

Where is a function to be applied, and ... are a number of lists equal to the number of arguments required by the function. Hence if a function that takes a single argument is supplied - like strcase, for example - then only one list is required.

 

To clarify this explanation with an example, assume we have a list of strings:

 

("alan" "ben" "claire" "david")

Suppose we need to convert each of these strings into uppercase (capitals). We could approach this task in a number of ways, for example, using the foreach function to shuffle through the list and create a new list of strings:

 

(foreach str '("alan" "ben" "claire" "david")
 (setq nlist (cons (strcase str) nlist))) 
(setq nlist (reverse nlist))

The above would set the variable nlist to:

 

("ALAN" "BEN" "CLAIRE" "DAVID")

However, this same task can be accomplished with much less coding using the mapcar function:

 

(mapcar 'strcase '("alan" "ben" "claire" "david"))

The above would return:

 

("ALAN" "BEN" "CLAIRE" "DAVID")

Notice that mapcar has been supplied with the function strcase, using an apostrophe so that strcase is not evaluated, but is treated as an argument instead. Also, we know that the strcase function takes one argument, namely a string, and hence we only need to supply one list - our list of strings.

 

As shown, the return is a list of strings in uppercase - as if we had used the function strcase on every member of the list.

 

Functions with More than One Argument

 

 

In the example above, the strcase function is demonstrated, and only one list is required as strcase only requires a single argument, but what if we want to use a function that requires multiple arguments?

 

Assume we have the list of numbers:

 

(1 2 3 4 5)

Let us suppose that we want to add each number in the above list to each number in the list:

 

(5 4 3 2 1)

Again, we could approach this using the foreach function, but it takes much less code to use mapcar:

 

(mapcar '+ '(1 2 3 4 5) '(5 4 3 2 1))

Here we have supplied mapcar with the "+" function, which takes any number of numerical arguments and adds them together. In the above example, mapcar will apply the "+" function to each member of each list and return a list of the results:

 

(6 6 6 6 6)  =  ((1 + 5) (2 + 4) (3 + 3) (4 + 2) (5 + 1))

As before, an apostrophe is used to declare the function "+" as an argument, preventing it from being evaluated and causing an error. This can also be achieved using the quote function:

(mapcar (quote +) (quote (1 2 3 4 5)) (quote (5 4 3 2 1)))

The Lambda Function

 

 

Going back to our original list of strings:

 

("alan" "ben" "claire" "david")

Suppose we want to convert each string so that the first letter is capitalised, hence:

("Alan" "Ben" "Claire" "David")

We could again use a method using foreach, and shuffle through our list:

 

(foreach str '("alan" "ben" "claire" "david")
  (setq nlist
    (cons
      (strcat
        (strcase (substr str 1 1))
        (substr str 2)) nlist)))
(setq nlist (reverse nlist))

But we could also use mapcar to save ourselves some code. However, there is no function in LISP that allows us to capitalise the first letter of a word, so how to do we provide mapcar with a function to apply?

 

We could define a function ourselves and supply it:

 

(defun cap (str)
  (strcat
    (strcase
      (substr str 1 1))
      (substr str 2)))

 (mapcar 'cap '("alan" "ben" "claire" "david"))

Here we have defined a new function (cap) which takes one argument (str), and performs an operation on that argument, in this case, converting the first letter to a capital.

 

But this means that we have an extra function definition in our code that may only be used once. A better way to accomplish this task would be to use the lambda function.

 

The lambda function defines an anonymous function and is to be used when the overhead of defining a new function is not justified - as in our case.

 

Hence our code can altered to include the lambda function:

 

(mapcar '(lambda (str)
           (strcat
             (strcase (substr str 1 1))
             (substr str 2)))
        '("alan" "ben" "claire" "david"))

Above, our lambda expression has been used in place of our defined function (cap). It takes one argument (str) and performs the operation on that string, just as our defined function would - with the exception that after our mapcar function has completed its operation, the lambda function is no longer defined, resulting in a tidier solution to the problem.

Link to comment
Share on other sites

More help please. Two items. First, I have achieved my desired result by simply restoring the layerstate both with a supplied viewport and without; the result being that layers are frozen and vpfrozen. not sure if that is the best way, but it works.

 

Second, I am trying to modify the code you provided by giving a branching decision--to run the code on all viewports (default) or to prompt for the user to select a specific viewport. Wondering if you could help again please.

 

(defun c:ILS3 (/ laspath lasfile vp_set )
(setvar "TILEMODE" 0)
 (if (= defvport nil) (setq defvport "All"))
 (initget 6 "All a A Viewport v V")
 	(setq vportselect (getkword (strcat "\nSelect individual viewport or all viewports?(Viewport/All)<"defvport"> ")))
 		(if (= vportselect nil) (setq vportselect defvport) (setq defvport vportselect)
 		)
 
 (if (= vportselect "All")
(progn
  (vl-load-com)
 		(and (vl-file-directory-p
        		(setq laspath
          			(strcat (getvar "DWGPREFIX") "Xrefs\\Layer States\\")))
      			(setq lasfile (getfiled "Select a Layer States (.las) file" laspath "las" 16))
      (layerstate-import lasfile)
      (layerstate-restore (vl-filename-base lasfile))
      (setq vp_set (ssget "_X" (list (cons 0 "VIEWPORT"))))
      (mapcar
        (function
          (lambda (x)
            (layerstate-restore
              (vl-filename-base lasfile) x)))
        (mapcar 'cadr (ssnamex vp_set))))
  
   )
 )
 	(while (null obj)(setq obj (entsel "\nSelect viewport:"))
		(setq elist (entget (car obj)))
 			(setq objtype (cdr (assoc 0 elist)))
 				(if (/= objtype "VIEWPORT")
			  (entsel "\nInvalid object. Please select viewport:")
			 )
 	)
 				(vl-load-com)
 				(and (vl-file-directory-p
      					(setq laspath
         					(strcat (getvar "DWGPREFIX") "Xrefs\\Layer States\\")))
    						(setq lasfile (getfiled "Select a Layer States (.las) file" laspath "las" 16))
      							(layerstate-import lasfile)
      							(layerstate-restore (vl-filename-base lasfile) obj)
			     )
   
(princ)
)

Link to comment
Share on other sites

That's strange. I'm looking right now at my original post--and it seems to be displaying what I posted, with more questions I had. I posted some more code too. Did the post you viewed only display "more help please"?

Link to comment
Share on other sites

No, I saw the whole post. I just couldn't believe the audacity of your post.

 

After providing you with plentiful information about mapcar and lambda, I receive absolutely no thanks whatsoever, but a blunt statement of "more help please", with more questions.

 

Of course, I am here to help out, but there are better ways to phrase your responses.

 

Lee

Link to comment
Share on other sites

My apologies. I'm sorry. You're right--my reply was blunt and audacious.

I intended to tell you that your explanation of mapcar and lambda was much more helpful than the AutoLisp help file, but forgot in my post.

My apologies.

Link to comment
Share on other sites

  • 1 year later...

Hi Lee

 

Great post,

 

I am just starting to get my head rapped around this mapcar and lambda function. Your examples are very helpful.

 

Quick question:

You say you have a tutorial in the FAQ, I can't seem to find my way to your tutorial can you give me a link? Thanks

 

The FAQ I found seems to be for the website not LISP itself.

 

Thanks man...

Link to comment
Share on other sites

Hi CADMan,

 

Glad it could help you understand. I'm afraid the tutorial hasn't been published in the FAQ as it needs to be checked by other members of the FAQ team for correctness etc. Also, since CADTutor was attacked, I'm not sure of the status of the FAQ itself.

 

I might add something similar to my site if I get time.

 

Lee

Link to comment
Share on other sites

Hi CADMan,

 

A tutorial can be found here:

 

Mapcar & Lambda

 

 

I hope it is comprehensible and welcome any questions about the content, suggestions for improvement, or indeed notification of any mistakes found.

 

Enjoy,

 

Lee

Link to comment
Share on other sites

Thanks Lee

 

very helpful tutorial, as nmulder says, better than the help menu...

 

You should think about writting a Lisp guide book, something I think you would do well at.

 

Thanks for all your help

Link to comment
Share on other sites

Hi CADMan,

 

A tutorial can be found here:

 

Mapcar & Lambda

 

 

 

Lee, another great explaination. Much appreciated. I think I finally get what lambda does :)

 

Glad to see your site is up and going strong, looks great. Thanks!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...