Coding the command-ended Function
 
 
 

Now that you have seen the pseudo-code and handled some important details, replace the stubbed-out code in the gp:command-ended reactor callback with the following:

(defun gp:command-ended (reactor	command-list
			 /		objReactor
			 reactorToChange  reactorData
			 coordinateValues currentPoints
			 newReactorData   newPts
			 tileList
			 )
  (cond
	;; 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.
	(*reactorsToRemove*
	 (foreach objReactor *reactorsToRemove*
	 (gp:erase-tiles objReactor)
	 )
	 (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*
	 (gp:erase-tiles reactorToChange)
	 )
	 (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*)
	*polytochange*
	*reactorsToChange*
	(member "GRIP_STRETCH" command-list)
	;; for a GRIP_STRETCH, there will be only one reactor in
	;; the global *reactorsToChange*.
	(setq reactorData
		 (vlr-data (setq reactorToChange
				(car *reactorsToChange*)
				 )
			 )
		)
	)
	 ;; First, erase the tiles within the polyline border.
	 (gp:erase-tiles reactorToChange)
	 ;; Next, get the current coordinate values of the polyline
	 ;; vertices.
	 (setq coordinateValues
		(vlax-safearray->list
		(vlax-variant-value
		(vla-get-coordinates *polyToChange*)
		)
		)
	 )
	 ;; 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.
	 (setq CurrentPoints
		(if (= (vla-get-ObjectName *polytochange*) "AcDbPolyline")
		(xyList->ListOfPoints coordinateValues)
		(xyzList->ListOfPoints coordinateValues)
		)
	 )
	 ;; Send this new information to RedefinePolyBorder -- this
	 ;; will return the new Polyline Border
	 (setq NewReactorData
		(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)
				 (3dPoint->2dPoint Point)
				 )
				newpts
				)
		 )
	 )
	 ;; Now update the polyline with the correct points.
	 (vla-put-coordinates
	*polytochange*
	 ;; 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
			NewReactorData
			;; Object creation function
			;; Within a reactor this *MUST* be ActiveX
			"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.
	 (setq NewReactorData
		(subst (cons 100 tileList)
		 (assoc 100 NewReactorData)
		 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
	 *reactorsToChange* nil
	 )
	 )
	)
  ;; Delete any items in the *Safe-to-Delete* global if you can!!!
  (Gp:Safe-Delete (car command-list))
  (princ)
  )