(LM:grsnap:parsepoint <bpt> <str>)
|View HTML Version||GrSnapV1-0.html|
|Download Demo Program||GrSnapDemo.lsp|
|View HTML Version||GrSnapDemo.html|
Introduction & Motivation
This utility provides a means of enabling the use of full Object Snap functionality within a grread loop.
The motivation for such a utility arises as a consequence of the behaviour of the AutoLISP grread function. This function pauses for any form of user input (whether it be mouse movement, mouse clicks, or keyboard input), and will return the type of input received & any relevant data associated with the input (such as the coordinates of the AutoCAD cursor, or the ASCII character codes of any key-presses issued by the user).
Given the ability to directly track the position of the AutoCAD cursor, the AutoLISP grread function is most commonly used within a while loop to continuously monitor user input and perform some operation or update the on-screen display depending upon the nature of the input received.
In this way, AutoLISP developers can create 'dynamic' programs in which the on-screen graphics can be updated in real-time based on the position of the AutoCAD cursor. There are several examples on my site demonstrating how to exploit this function to yield dynamic effects, including: Align Objects to Curve, Align Text to Curve, Draw Grid, Dynamic Attribute Width, Dynamic Information Tool, Dynamic Offset, Dynamic Text Alignment, Incremental Array, Incremental Numbering Suite, Label, Slinky Text, and many others.
However, the practicality of the grread function is severely hampered by the simplicity of its output - since the function merely pauses awaiting any form of data received from an input device, no information is provided pertaining to any active drawing aids, and consequently all standard drawing aids (such as Object Snap, Orthomode, Tracking, Dynamic Input, etc.) are unavailable whilst the grread function is awaiting or receiving input.
Given the necessity of Object Snap for accurate & precise drafting, the unavailability of Object Snap within a grread loop becomes a 'deal-breaker' for many AutoLISP developers (including myself), as the sacrifice of Object Snap far outweighs the benefit of any fancy visual effect offered by the use of such function.
Therefore, when designing a 'dynamic' application, a developer must either turn to a standard getXXX function to retrieve user input (such as getpoint, for example), and hence abandon the dynamic visual effect; or alternatively attempt to imitate the functionality of the Object Snap drawing aid by calculating the available snap points based on the active snap modes & reconstructing the snap symbols as temporary screen graphics.
This utility attempts to do exactly that.
It would be remiss of me at this point to neglect to mention the tremendous work others have contributed to achieving this goal, most notably ElpanovEvgeniy, a very talented AutoLISP developer on whose shoulders I stand.
|Function||A function returning a calculated snap point (if available) for a given point & Object Snap bit code.|
This function forms the core element of the GrSnap utility; the function defines & returns a function requiring two arguments: a point from which to calculate an available snap point & display the appropriate snap symbol, and an Object Snap bit code corresponding to one or more snap modes that are to be considered when calculating the snap point.
You may be puzzled as to why this function has been designed to return another function to be used to perform the snap calculations, rather than performing the calculations itself.
The answer is efficiency.
There are many operations pertaining to the construction of the Object Snap symbol vectors which only need to be performed once when the calling program is run. Given that the acquisition of a snap point is likely to be performed continuously within a grread loop, it would be incredibly inefficient & unnecessary if such operations were to be performed repeatedly.
Global variables could obviously be used to overcome this inefficiency, but the function then 'leaks' data and it becomes the responsibility of the calling program to clean up the variables when finished.
Instead, by defining & returning an optimised function, the calling program can assign the function to a local symbol (outside of any loop construct), and then evaluate the local function within the grread loop.
This technique is best demonstrated with code:
(setq osf (LM:grsnap:snapfunction) ;; Define optimised Object Snap function osm (getvar 'osmode) ;; Retrieve active Object Snap modes ) (while (= 5 (car (setq grr (grread t 13 0)))) ;; While the cursor is moved (redraw) ;; Refresh the display (osf (cadr grr) osm) ;; Calculate & display any available snap points )
The function will furthermore perform successfully under all UCS & View settings.
Parse Point Function
|Function Syntax||(LM:grsnap:parsepoint <bpt> <str>)|
|bpt||List||Basepoint for relative point input, e.g. @5,5|
|str||String||String representing point input|
|List||Point represented by the given string, else nil.|
This function facilitates typed point input within a grread loop.
To enable the user to specify points by entering absolute or relative coordinates at the keyboard, the calling program should be designed to monitor keyboard input & concatenate the entered characters accordingly. This is demonstrated by the second & third demo programs provided in the file available for download at the top of this page.
Given a string entered by the user, this function will test whether the string represents a valid 2D or 3D point input, and furthermore whether the specified point is an absolute or relative coordinate (i.e. whether or not the coordinate input is prefixed with the '@' symbol), and will return the appropriate absolute coordinate value or nil if the input is invalid.
As an example:
_$ (LM:grsnap:parsepoint '(3.0 5.0) "@2,2") (5.0 7.0)
Snap Mode Function
|Function Syntax||(LM:grsnap:snapmode <str>)|
|str||String||Object Snap modifier|
|Integer||Object Snap bit code for the given modifier, else nil.|
This function enables the use of Object Snap modifiers to override the active Object Snap modes during point input.
As with the above Parse Point function, to enable the implementation this function in a program, the calling program should be designed to monitor & concatenate keyboard input within the grread loop, before passing the string specified by the user to this function.
Evaluated with a given string, this function will test whether the supplied string matches any available Object Snap modifier and, if successful, will return the corresponding Object Snap bit code and print either 'of' or 'to' at the AutoCAD command-line, consistent with standard AutoCAD behaviour.
Since Object Snap modifiers are matched by treating the supplied string as a wildcard pattern, the function will accept any portion from the start of the modifier keyword, for example:
_$ (LM:grsnap:snapmode "end") 1 _$ (LM:grsnap:snapmode "endp") 1 _$ (LM:grsnap:snapmode "endpoint") 1
The implementation of this function is illustrated by the second & third demo programs available to download at the top of this page.
In addition to the above descriptions and code snippets, I have provided a set of three demonstration programs which are available for download using the link at the top of this page. These example programs provide implementations of my GrSnap utility with varying degrees of Object Snap functionality; the demo programs are described separately in more detail below.
Please ensure the GrSnap.lsp utility is loaded before running any of the following demo programs.
Demo Program 1
This first program is a very basic implementation of the GrSnap utility. The program will display available snap points using the appropriate symbols, but does not offer the user or support any form of keyboard input.
The program will simply prompt the user to pick a point and will create a POINT entity at the selected point. This can obviously be achieved using the getpoint AutoLISP function, however, the demo program is provided only as a simplified academic example.
Demo Program 2
This program demonstrates a full implementation of the GrSnap utility, displaying the available snap points as the cursor is moved, permitting keyboard input of absolute or relative coordinates, and enabling the use of Object Snap modifiers to override the active Object Snap modes.
As with the first demo program, this program will also simply prompt the user to pick a point and will create a POINT entity at the selected or specified point.
Demo Program 3
Finally, this third program demonstrates a full implementation of the GrSnap utility, in conjunction with the display of custom vector graphics on screen, showing functionality which could not be achieved using standard AutoLISP functions (unless a temporary block was created).
The program will prompt the user to specify the center of a circle with radius 1/20th of the screen height, displayed in real-time at the cursor. Given a valid point, the program will construct a CIRCLE entity centered at the selected point.
Below is a preview of the program in operation, showing compatibility under all UCS & View settings, and demonstrating the ability to use Object Snap modifiers:
The following programs serve as additional examples demonstrating an implementation of my GrSnap utility: