is it possible to restrict zoom outside a given area on ModelSpace using Autolisp (like in paperspace)

is it possible to restrict zoom outside a given area on ModelSpace using Autolisp (like in paperspace)

Kh.mbkh
Advocate Advocate
435 Views
7 Replies
Message 1 of 8

is it possible to restrict zoom outside a given area on ModelSpace using Autolisp (like in paperspace)

Kh.mbkh
Advocate
Advocate

Can I create an Autolisp routine that restrict zooming outside a given rectangle on Model space ? (Like what we can do on Paper space).

Can Reactors do that ?

0 Likes
Accepted solutions (1)
436 Views
7 Replies
Replies (7)
Message 2 of 8

ryanatkins49056
Enthusiast
Enthusiast

You can restrict the zoom "ALL" command which I think is what you're after using the "LIMITS" command. You would then be able to use getpoints or point lists to set these. But one think to ensure is the "LIMCHECK" variable is set to "1".

 

Alternatively if I have completely misunderstood what you're after and you wish to zoom where you have everything within the model space within the viewing area also known as the extents.

(defun c:ZE () (command "._zoom" "extents"))

Double clicking your scroll wheel by default will do the same thing.

0 Likes
Message 3 of 8

Kh.mbkh
Advocate
Advocate

Thanks @ryanatkins49056 , Actually the goal is to "oblige" user to work only on a given rectangle area, so if he zoom out this area, the Autolisp function (using a Reactor) will zoom automatically to the "allowed" area. So that user always can see only this area, unless he call a function that remove this "Reactor". Exactly like on PaperSpace.

 

0 Likes
Message 4 of 8

Kent1Cooper
Consultant
Consultant

@ryanatkins49056 wrote:

.... But one think to ensure is the "LIMCHECK" variable is set to "1". ....


LIMCHECK is not going to help.  It will prevent your picking locations in drawing objects outside the drawing limits, but it won't prevent Zooming outside that area.  And there are objects you can draw that can get outside the limits, for example Text that starts inside them but is long enough to continue outside, or a Circle with the center point inside but a large-enough radius to go outside.

Kent Cooper, AIA
Message 5 of 8

Sea-Haven
Mentor
Mentor

The only way around it may be draw a rectangle on a non plot layer say at a size based on a plot scale, relative to your title block. Then its visible your going out of the work area. 

0 Likes
Message 6 of 8

CodeDing
Advisor
Advisor

@Kh.mbkh ,

 

View this answer and thread here:

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/autolisp-window-reactor-need-example... 

 

However, because ^^this link will break^^ (thanks Autodesk) in one month, I will paste same response here:


@dbroad wrote:

I doubt that you will succeed in achieving what you want by using lisp.  It will probably be necessary to switch to .NET programming as that has much deeper hooks into the program than lisp.  If you want to proceed, you might use the vlr-editor-reactor or vlr-sysvar-reactor.  The main problem is that mouse panning does not call a command and does not generate changes in sysvars other than  "VIEWBACKSTATUS" and "DYNMODE".  It would be necessary for you to query the value of viewctr and viewsize within a callback triggered by whatever event would be frequently related to view changes and to compare them to previously saved viewctr and viewsize settings.  Here is a sample which should suggest failure to be able to track fluidly.  A vlr-command-reactor tracking a vlr-commandended event might be a good place to get a quiescent state to track these variables and to make adjustments but it will not be problem free.


(vlr-remove-all)
(setq svr (vlr-sysvar-reactor
	    (list (cons "VIEWCTR" (getvar "viewctr"))
		  (cons "VIEWSIZE" (getvar "viewsize"))
	    )
	    '((:vlr-sysvarchanged . svcbexample)

	     )
	  )
)
(defun svcbexample (r l / data ovc ovs nvc nvs)
  (setq data (vlr-data r))
  (setq	ovc (cdr (assoc "VIEWCTR" data))
	ovs (cdr (assoc "VIEWSIZE" data))
	nvc (getvar "viewctr")
	nvs (getvar "viewsize")
  )
  (if (not(equal ovc nvc))
    (progn
      (alert (strcat "\nViewctr has changed.  It was: "
		     (vl-princ-to-string ovc)
		     " It is now: "
		     (vl-princ-to-string nvc)
	     )
      )
      (setq
	data (subst (cons "VIEWCTR" nvc) (assoc "VIEWCTR" data) data)
      )
    )
  )
  (if (not(equal ovs nvs))
    (progn
      (alert (strcat "\Viewsize has changed. It was "
		     (rtos ovs)
		     ". It is now "
		     (rtos nvs)
	     )
      )
      (setq data
	     (subst (cons "VIEWSIZE" nvs ) (assoc "VIEWSIZE" data) data)
      )
    )
  )
  (vlr-data-set r data)
)

 

Best,

~DD

0 Likes
Message 7 of 8

jreidKVSUZ
Advocate
Advocate

I have a command called ZO. I put this inside my startup ACAD.LSP file so it is ready at any time.
This Zoom Extents then types in .9X to give me a little outline of what Extents zoomed. This works great for MS or PS.
I have listed several others that I have in my ACAD.LSP file for Zoom that I use all the time as well. I posted commands below.

 

Hope this helps!
JRR!

 

(defun c:ZA ()
(command "ZOOM" "A")
(princ))

 

(defun c:ZE ()
(command "ZOOM" "E")
(princ))

 

(defun c:ZO ()
(command "ZOOM" "E" "ZOOM" ".9X")
(princ))

 

(defun c:9X ()
(command "ZOOM" ".9X")
(princ))

 

(defun c:ZP ()
(command "ZOOM" "P")
(princ))

 

(defun c:ZW ()
(command "ZOOM" "W")
(princ))

 

(defun c:ZZ ()
(command "ZOOM")
(princ))

 

0 Likes
Message 8 of 8

Kh.mbkh
Advocate
Advocate
Accepted solution

Thanks @CodeDing 

Yeah it's "impossible" to achieve this on Autolisp. There is no events for changing view with Lisp. 

The only solution I found is Document.ViewChanged event on .NET. And it's doing exactly what we're looking for !

 

For any one who may be interested, here is the code on c# .NET

 

Thanks !

 

 

using System;
using System.Threading.Tasks;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using acadApp = Autodesk.AutoCAD.ApplicationServices.Core.Application; // Alias to resolve ambiguity

[assembly: CommandClass(typeof(AutoCADZoomPanMonitor.ZoomPanMonitor))]

namespace AutoCADZoomPanMonitor
{
    public class ZoomPanMonitor
    {
        private Document _doc;

        [CommandMethod("StartZoomPanMonitor")]
        public void StartMonitoring()
        {
            _doc = acadApp.DocumentManager.MdiActiveDocument;
            if (_doc == null) return;

            // Subscribe to ViewChanged event
            _doc.ViewChanged += OnViewChanged;

            _doc.Editor.WriteMessage("\nZoom/Pan Monitor Started...\n");
        }

        [CommandMethod("StopZoomPanMonitor")]
        public void StopMonitoring()
        {
            if (_doc != null)
            {
                _doc.ViewChanged -= OnViewChanged;
                _doc.Editor.WriteMessage("\nZoom/Pan Monitor Stopped...\n");
                _doc = null;
            }
        }

        private async void OnViewChanged(object sender, EventArgs e)
        {
            await Task.Delay(1000); // Non-blocking delay
            acadApp.ShowAlertDialog("Zoom or Pan detected!");
        }
    }
}

 

0 Likes