Updating the C:GPath Function

AutoCAD Visual LISP

 
Updating the C:GPath Function
 
 
 

Update the C:GPath function by adding reactor creation logic.

To add reactor creation logic to C:GPath

  1. Replace your version of gpmain.lsp with the updated version shown below. Copy this code from the <AutoCAD directory>\Tutorial\VisualLISP\Lesson6 directory:
    (defun C:GPath (/
            gp_PathData
            gp_dialogResults
            PolylineName
            tileList
               )
      (setvar "OSMODE" 0)              ;; Turn off object snaps
    ;|
    ;; Lesson 6 adds a stubbed-out command reactor to AutoCAD
      ;; However, it would be undesirable to react to every
      ;; drawing of a circle should the COMMAND tile creation
      ;; method be chosen by the user.  So, disable the 
      ;; *commandReactor* in case it exists. 
      |;
    (if *commandReactor*
        (progn
          (setq *commandReactor* nil)
          (vlr-remove-all :VLR-Command-Reactor)
        )
      )
      ;; Ask the user for input: first for path location and
      ;; direction, then for path parameters.  Continue only if you
      ;; have valid input.  Store the data in gp_PathData.
      (if (setq gp_PathData (gp:getPointInput))
        (if (setq gp_dialogResults
               (gp:getDialogInput
             (cdr (assoc 40 gp_PathData))
               ) ;_ end of gp:getDialogInput
        ) ;_ end of setq
          (progn
        ;; Now take the results of gp:getPointInput and append this to
        ;; the added information supplied by gp:getDialogInput
        (setq gp_PathData (append gp_PathData gp_DialogResults))
        ;; At this point, you have all the input from the user
        ;; Draw the outline, storing the resulting polyline "pointer"
        ;; in the variable called PolylineName
        (setq PolylineName (gp:drawOutline gp_PathData))
        ;; Next, it is time to draw the tiles within the boundary.
        ;; The gp_tileList contains a list of the object pointers for
        ;; the tiles.  By counting up the number of points (using the
        ;; length function), we can print out the results of how many
        ;; tiles were drawn.
        (princ "\nThe path required ")
        (princ
          (length
            (setq tileList (gp:Calculate-and-Draw-Tiles gp_PathData))
          ) ;_ end of length
        ) ;_ end of princ
        (princ " tiles.")
    ;; Add the list of pointers to the tiles (returned by
        ;; gp:Calculate-and-Draw-Tiles) to gp_PathData. This will
        ;; be stored in the reactor data for the reactor attached 
        ;; to the boundary polyline.  With this data, the polyline
        ;; "knows" what tiles (circles) belong to it.
        (setq gp_PathData
               (append (list (cons 100 tileList))
                        ; all the tiles
                   gp_PathData
               ) ;_ end of append
        ) ;_ end of setq
    ;; Before we attach reactor data to an object, let's look at
        ;; the function vlr-object-reactor
        ;; vlr-object-reactor has the following arguments:
        ;;  (vlr-object-reactor owner's data callbacks)
        ;;      The callbacks Argument is a list comprised
        ;;      '(event_name . callback_function)
        ;;
        ;; For this exercise we will use all arguments
        ;; associated with vlr-object-reactor
        ;; These reactor functions will execute only if
        ;; the polyline in PolylineName is modified or erased
        (vlr-object-reactor
          ;; The first argument for vlr-object-reactor is
          ;; the "Owner's List" argument.  This is where to
          ;; place the object to be associated with the
          ;; reactor.  In this case, it is the vlaObject
          ;; stored in PolylineName.
          (list PolylineName)
          ;; The second argument contains the data for the path
          gp_PathData
          ;; The third argument is the list of specific reactor
          ;; types that we are interested in using
          '
           (
            ;; reactor that is called upon modification of the object
            (:vlr-modified . gp:outline-changed)
            ;; reactor that is called upon erasure of the object
            (:vlr-erased . gp:outline-erased)
           )
        ) ;_ end of vlr-object-reactor
        ;; Next, register a command reactor to adjust the polyline
        ;; when the changing command is finished
        (if (not *commandReactor*)
          (setq *commandReactor*
    (VLR-Command-Reactor
               nil          ; No data is associated with the command reactor
               '(
                 (:vlr-commandWillStart . gp:command-will-start)
                 (:vlr-commandEnded . gp:command-ended)
                )
             ) ;_ end of vlr-command-reactor
          )
        )
     ;; The following code removes all reactors when the drawing is
     ;; closed. This is extremely important!!!!!!!!!
     ;; Without this notification, AutoCAD may crash upon exiting!
     (if (not *DrawingReactor*)
          (setq *DrawingReactor*
             (VLR-DWG-Reactor
               nil          ; No data is associated with the drawing reactor
               '((:vlr-beginClose . gp:clean-all-reactors)
                )
             ) ;_ end of vlr-DWG-reactor
         )
     )
          ) ;_ end of progn
          (princ "\nFunction cancelled.")
        ) ;_ end of if
        (princ "\nIncomplete information to draw a boundary.")
      ) ;_ end of if
      (princ)               ; exit quietly
    ) ;_ end of defun
    ;;; Display a message to let the user know the command name.
    (princ "\nType GPATH to draw a garden path.")
    (princ)
  2. Review the code modifications and comments describing what each new statement does. This tutorial shows all modified code in boldface.