gp:command-ended reactor callback with the following:Now that you have seen the pseudo-code and handled some important details, replace the stubbed-out code in the
(defun gp:command-ended (reactor command-list
;; CONDITION 1 - POLYLINE ERASED (Erase command)
;; If one or more polyline borders are being erased (indicated
;; by the presence of *reactorsToRemove*), erase the tiles
;; within the border, then remove the reactor.
(foreach objReactor *reactorsToRemove*
(setq *reactorsToRemove* nil)
;; CONDITION 2 - LOST ASSOCIATIVITY (Move, Rotate, etc.)
;; If associativity has been lost (undo, move, etc.), then
;; erase the tiles within each border
((and *lostassociativity* *reactorsToChange*)
(foreach reactorToChange *reactorsToChange*
(setq *reactorsToChange* nil)
;; CONDITION 3 - GRIP_STRETCH
;; In this case, the associativity of the tiles to the path is
;; kept, but the path and the tiles will need to be
;; recalculated and redrawn. A GRIP_STRETCH can only be
;; performed on a single POLYLINE at a time.
((and (not *lostassociativity*)
(member "GRIP_STRETCH" command-list)
;; for a GRIP_STRETCH, there will be only one reactor in
;; the global *reactorsToChange*.
(vlr-data (setq reactorToChange
;; First, erase the tiles within the polyline border.
;; Next, get the current coordinate values of the polyline
;; If the outline is a lightweight polyline, you have
;; 2d points, so use utility function xyList->ListOfPoints
;; to convert the coordinate data into lists of
;; ((x y) (x y) ...) points. Otherwise, use the
;; xyzList->ListOfPoints function that deals
;; with 3d points, and converts the coordinate data into
;; lists of ((x y z) (x y z) ... ) points.
(if (= (vla-get-ObjectName *polytochange*) "AcDbPolyline")
;; Send this new information to RedefinePolyBorder -- this
;; will return the new Polyline Border
(gp:RedefinePolyBorder CurrentPoints reactorData)
;; Get all the border Points and ...
(setq newpts (list (cdr (assoc 12 NewReactorData))
(cdr (assoc 13 NewReactorData))
(cdr (assoc 14 NewReactorData))
(cdr (assoc 15 NewReactorData))
;; ...update the outline of the polyline with the new points
;; calculated above. If dealing with a lightweight polyline,
;; convert these points to 2D (since all the points in
;; newpts are 3D), otherwise leave them alone.
(if (= (cdr (assoc 4 NewReactorData)) "LIGHT")
(setq newpts (mapcar '(lambda (point)
;; Now update the polyline with the correct points.
;; For description of the list->variantArray see utils.lsp.
(gp:list->variantArray (apply 'append newpts))
;; Now use the current definition of the NewReactorData,
;; which is really the same as the garden path data
;; structure. The only exception is that the field (100)
;; containing the list of tiles is nil. This is OK since
;; gp:Calculate-and-Draw-Tiles does not require this field
;; to draw the tiles. In fact this function creates the tiles
;; and returns a list of drawn tiles.
(setq tileList (gp:Calculate-and-Draw-Tiles
;; path data list without correct tile list
;; Object creation function
;; Within a reactor this *MUST* be ActiveX
;; Now that you have received all the tiles drawn, rebuild
;; the data structure with the correct tileList value and
;; reset the data property in the reactor.
;; Update the tiles associated with the polyline border.
(subst (cons 100 tileList)
(assoc 100 NewReactorData)
;; By now you have the new data associated with the polyline.
;; All there is left to do is associate it with the reactor
;; using vlr-data-set.
(vlr-data-set (car *reactorsToChange*) NewReactorData)
;; Remove all references to the temporary
;; variables *polytochange* and *reactorsToChange*.
(setq *polytochange* nil
;; Delete any items in the *Safe-to-Delete* global if you can!!!
(Gp:Safe-Delete (car command-list))