Jump to content

Lisp to change view in modelspace


DeBroiler

Recommended Posts

Hi all,

 

i'm a beginner Lisp user and absolute beginner Visual-Lisp user and till now have managed to get Lisp to do my biding with internet tutorials and existing forum posts i found via google etc. However now i've run into a problem which i can't seem to fix with the limited resources available to me and i'm hoping to find some help here.

 

A little background: i work for a german company specialized in geotechnics. One of our projects is geotechnical consultation for a new railway which is currently in-construction. The earthworks for this railway are just about done and to observe the settling and lifting of the dams and incisions, geodesic measurement points have been installed. My job is to manage the plans showing the latest measurements results. Measurement results are represented by blocks (those little green dots in the attached image). As new measurements mostly arrive in bulk and i'm rather lazy but still want to keep the plans up-to-date, i've put togethere a little Lisp-routine which jumps from block to block allowing the user (well mostly me i gues) to enter the newly measured settlement / lifting and automatically moves the blocks accordingly. This is working rather well so far (not least thanks to Lee Mac and the incredible wealth of tutorials, forum posts and tweets he has put together - if you're reading this i honestly can't thank you enough!).

 

verformungsdarstellung.JPG.2a6e4ccb8b1522609d0477317b9aab63.JPG

 

However the better things worked, the more ambitious i got with lisp-programming and the less work i'm willing to put into entering new measurements. So now i'm looking into ways to automatically focus the view in modellspace on the block which is currently being edited. Looking at the Autocad-object-model i figured what i need to edit is the current "view". According to the this link, views can be accessed with the "item" method of the "Views" collection and i'm just hoping that "item 0" in my views-collection is the active view in modelspace - i'm rather unsure about this but it was the most plausible approach i could imagine. As i mentioned earlier, i just started working with visual-lisp, so what i've come up with so far is:

 

(vlax-invoke-method (vla-get-views (vla-get-activedocument (vlax-get-acad-object))) 
                    "item" 
                    (vlax-make-variant 0 vlax-vbinteger))

However all i get is an error: (translated from german) "error: automatisation error. no description available". I'm rather lost. Everything else i've tried to access, let alone edit the current view has failed miserably and i'm not even sure the "view" object realy is the object i need to modify in order to focus the camera on the next block. So i'm stuck on track and i don't even know if it's the right one. I hope i could clarify my problem. Any help would be greatly appreciated!

 

Many thanks in advance,

Robert

Link to comment
Share on other sites

There is no default view that can be accessed in this manner. Views have to be created first.

In your case it is probably easier to work with the zoom methods of the application object.

  • Like 1
Link to comment
Share on other sites

Thanks a lot! That was much easier than i expected. 😀

 

So now i've got autolisp to move the the view in modelspace like this.

(vlax-invoke-method (vlax-get-acad-object) 
                    'zoomcenter 
                    (vlax-3d-point x-coords y-coords) 
                    magnify)

The zoomcenter appears to me, to be  the easiest method to set a new center for the view. However the "magnify" parameter cannot be ommited. In the activeX and VBA reference it says:

 

Quote

Magnify

Double; input-only
The magnification level of the window. A value smaller than the current value increases the magnification. A larger value decreases the magnification.

 

As i only want to move the view, could you (or anybody) help me on how to get the current magnification level before calling the zoomcenter method, so that i can move the view without changing the magnification? Again thanks in advance! 🍻

Link to comment
Share on other sites

Good question. I can't find any 'official' documentation. But a quick test suggests that the magnification argument represents the height of the view in drawing units. You can use the VIEWSIZE variable to retrieve the current height.

(vla-zoomcenter (vlax-get-acad-object) (vlax-3d-point (getpoint)) (getvar 'viewsize))

 

Edited by Roy_043
Link to comment
Share on other sites

Jesus... A one-liner - that is way to easy for me to have tried working it out to no avail for hours this morning! 🤯

 

Just out of curiosity and so i get some learning about the object model out of this:

I don't really get why i need to call a method of the application-object to change the current view, even though each open document has it's own discrete view setting. But then on the other hand each document has it's own "views" collection. So the "views"-collection contains all the custom views, which the user can save via the view-manager, right? Then why is there no activeView object like there is an activeviewport object? And what does the viewport collection contain? Model Space Viewports or Layour Viewports or both? 🤔

 

Anyway, i realize gaining a thorough understanding of the object model of a program as complex as autocad will take some time and i've only just begun my journey.

For now, you've helped me tremendously, so thanks again! 😀👍

 

Edited by DeBroiler
Link to comment
Share on other sites

I don't know why the document object does not have zoom methods as, indeed, that would make a lot of sense.

Stored views are used to quickly reset the view (and the layers, and the UCS etc.), which can be very useful for moving around in a complex model (Both MS and PS views can be saved). But once a view has been restored it typically won't stay fixed, which is why having an active view object or setting is probably not an obvious choice.

Edited by Roy_043
  • Thanks 1
Link to comment
Share on other sites

Just a question if you have a block why are you manually changing the block postion, if the block has an attribute of say ID then just find that one and reset the Y value, just have a csv file id,value then adjust all in one go.

Link to comment
Share on other sites

On 1/17/2019 at 11:34 AM, DeBroiler said:

Hi all,

 

i'm a beginner Lisp user and absolute beginner Visual-Lisp user and till now have managed to get Lisp to do my biding with internet tutorials and existing forum posts i found via google etc. However now i've run into a problem which i can't seem to fix with the limited resources available to me and i'm hoping to find some help here.

 

A little background: i work for a german company specialized in geotechnics. One of our projects is geotechnical consultation for a new railway which is currently in-construction. The earthworks for this railway are just about done and to observe the settling and lifting of the dams and incisions, geodesic measurement points have been installed. My job is to manage the plans showing the latest measurements results. Measurement results are represented by blocks (those little green dots in the attached image). As new measurements mostly arrive in bulk and i'm rather lazy but still want to keep the plans up-to-date, i've put togethere a little Lisp-routine which jumps from block to block allowing the user (well mostly me i gues) to enter the newly measured settlement / lifting and automatically moves the blocks accordingly. This is working rather well so far (not least thanks to Lee Mac and the incredible wealth of tutorials, forum posts and tweets he has put together - if you're reading this i honestly can't thank you enough!).

 

verformungsdarstellung.JPG.2a6e4ccb8b1522609d0477317b9aab63.JPG

 

However the better things worked, the more ambitious i got with lisp-programming and the less work i'm willing to put into entering new measurements. So now i'm looking into ways to automatically focus the view in modellspace on the block which is currently being edited. Looking at the Autocad-object-model i figured what i need to edit is the current "view". According to the this link, views can be accessed with the "item" method of the "Views" collection and i'm just hoping that "item 0" in my views-collection is the active view in modelspace - i'm rather unsure about this but it was the most plausible approach i could imagine. As i mentioned earlier, i just started working with visual-lisp, so what i've come up with so far is:

 


(vlax-invoke-method (vla-get-views (vla-get-activedocument (vlax-get-acad-object))) 
                    "item" 
                    (vlax-make-variant 0 vlax-vbinteger))

However all i get is an error: (translated from german) "error: automatisation error. no description available". I'm rather lost. Everything else i've tried to access, let alone edit the current view has failed miserably and i'm not even sure the "view" object realy is the object i need to modify in order to focus the camera on the next block. So i'm stuck on track and i don't even know if it's the right one. I hope i could clarify my problem. Any help would be greatly appreciated!

 

Many thanks in advance,

Robert

Hello Robert,

 

Could you share your code with us?

 

Thanks.

Link to comment
Share on other sites

 

Hey all, sorry for the long delay, but i've been quite busy elsewhere last week. I'll answer each of your posts in order.


@Roy_043
Thanks for clarifying. My thinking was, that the activeview would allways hold the view currently used in model- or paperspace, just like the activeviewport holds the currently used viewports. But now i understand, views are used in a much more dynamic fashion, than viewports are - so i guess what makes sense for viewports doesn't necessarily make sense for views. I'm still confused though, as to why the view is changed via the acad-app object. Maybe somebody else has a valid explanation?

 

@BIGAL
Thanks for the input - very interesting idea!
As i mentioned before i'm rather new to LISP-programming, and when i started working on my lisp program i was an absolute newb. So my "method" was more like "try something new and see what happens" and working with manual input gave me better feedback as to how good/bad my programming was working. So until now i stuck with manual input.
I still have some features i want to implement, but once i got the program to run to my liking, i will definitely look into implementing a file-input option.

 

@Dani_Nadir
As much as i'd like to, i don't think i'm legally allowed to, as everything i create on company time, legally belongs to my company - and i'm afraid they are rather strict regarding legal matters. Besides with error-checking, help functions, user-input functions the program has grown to almost 650 lines of code with questionable formatting and comments in german - so i'm, afraid it wouldn't be too useful.
Basically what the code does is this:

1. select all blocks of name "GemesseneVerformung" (= measured settlement, which is just how i happened to name the block with the little green circles) via ssget,
2. transform the selection set into a coordinate-sorted list of entity-names via a method i got from peters post over at AUGI (i hope i'm allowed to add links to other forums, but i couldn't find anything stating i wasn't)
3. let the user pick the first block he wants to edit
4. find the position of the selected block inside of the coordinate-sorted list of blocks via vl-position
5. enter an infinite while-loop (user has to abort to get out of the function - not very clean, but it does the trick for now and i can use a custom *error* function to clean up my mess) to iterate over all blocks including and following the user-selected block
6. inside the while-loop get the newly measured settlement for the active block and then calculate the new y-position of the block and move it via entget (like i said, i'm just beginning to explorer the posibilities of visual-lisp, back when i started the program it seemed safer to me, to just stick to vanilla-lisp and learn that, before trying to dive into the whole host of new posibilities offered by visual-lisp)

 

The rest is just checking for valid user-input plus some comfort functions to edit block attributes. You can see the block attributes in the attached picture (they reside on a seperate layer which is deactivated for plotting. So no danger of accidentally plotting 100 of green dots with miniature text). I added those, to help me navigate and not to get the blocks and the measurements mixed up - and since i added the view changing code, i asked about in this post, i'm rather glad i did add them. The view changes take place instantly which can leave the user rather confused as to where on the plans he is  after inputting some 50 or so measurements. If you have questions regarding how i implemented some of those functions specifically, i'd be glad to post some code with english commentary!

 

Hope that helped clarify things a bit - sorry for the wall of text. I'd be glad to keep the discussion going.

GMV-Block.JPG.a19dd7eab6a73d99e925c5f70c372361.JPG

 

Edited by DeBroiler
Link to comment
Share on other sites

Given the name 54247 can be used as block id via an attribute you make a list of chainage and settlement, just find the one that matches and move the block up or down obviously at scale.

 

If your company will let you post a sample text file of chainage and settlement other values etc and the  block, use wblock to export it out so its only the block and not a complete dwg. Its a pretty easy task to set up.

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...