This is something I've wanted ever since I first used Autocad, and finally made with help and guidance from Greg S at the Bricscad forum. It's two separate commands, TR and EX, and both have automatic switching between standard and Fence mode.
–If your pick doesn't find an object to be trimmed (or extended), you change automatically to Fence mode. That pick point is used as the first fence point, and you're prompted for the next fence point.
–You automatically switch back to normal mode by clicking within pickbox range of any object (though the pickbox isn't displayed, unfortunately). The object you clicked on is trimmed (or extended) if possible.
–Hitting Enter exits the command from either mode.
I've tested it in Bricscad v9. It doesn't work in Bricscad v8, but it might work in Autocad.
EDIT: Maybe it does work in v8. It passed a brief test just now, prompted by gskelly's reply.
Is there any way to make something that looks like the pickbox (but maybe grey?) appear at the crosshairs (or, ideally, instead of the crosshairs) during a GETPOINT function, with Object Snap turned off? Osnap has to be off. I'm using GETPOINT during fence mode because that's the only way I know to get a rubber-band line from the last fence point to the cursor. Or is there some way to get that during an ENTSEL function?
;;; sub-routine to highlight a selection set (without grips)
(defun hilite (set33 OnOff / N ObjN)
(if (= (type set33) 'PICKSET)
(progn
(setq N 0)
(repeat (sslength set33)
(and
(setq ObjN (vlax-ename->vla-object (ssname set33 N)))
(vlax-method-applicable-p ObjN "Highlight")
(vla-highlight ObjN OnOff)
) ;; end And
(setq N (1+ N))
) ;; end Repeat
) ;; end Progn
) ;; end IF
) ;-----------------------------------------------------------
;;; subroutine to handle errors
(defun IfAbort (emsg)
(prompt "\n-- Abnormal termination due to: ")
(prompt emsg)
(setvar "CMDECHO" SaveCE) ;; restore command echo status
(setvar "OSMODE" SaveOS) ;; restore Object Snap setting
(setq *error* SaveErr) ;; restore previous error-handling function
(hilite ss1 0) ;; turn off highlighting
) ;-----------------------------------------------------------
;;; TRIM command with Fence mode automatically turned on and off
(defun c:TR (/ )
(setq SaveCE (getvar "CMDECHO")) ;; save Command Echo status
(setq SaveOS (getvar "OSMODE")) ;; save Object Snap setting
(setq SaveErr *error*) ;; save current error-handling function
(setq *error* IfAbort) ;; make IfAbort the error-handling function
(princ "Select cutting objects: ")
(setq ss1 (ssget)) ;; select cutting edges
(sssetfirst nil ss1) (sssetfirst nil) ;; turn off grips of any pre-selected set
;------------------------------------------------------
(setvar "CMDECHO" 0) ;; suppress command echo
(setvar "OSMODE" 0) ;; turn off object snap
(setq pt1 nil pt2 nil NewPt nil) ;; clear fence points & pick point
(setq LoopFlag 1) ;; set Loop flag
;------------------------------ Begin Loop, get user input
(while (equal LoopFlag 1) ;; Loop till no point is picked
(setq e1 nil)
(setq NewPt nil)
(hilite ss1 1) ;; highlight cutting edges
(if pt1 ;;----------1: Is there a fence start point?
(progn ;; If so, look for a new fence vertex.
(setq NewPt (getpoint pt1 "Next fence point, or object to trim: "))
(if NewPt ;;---------2: Did the user actually pick a new point?
(progn ;; If so,
(if (ssget NewPt) ;;---------3: Is there an object at NewPt?
(progn ;; If so,
(setq e1 (ssname (ssget NewPt) 0)) ;; make it e1,
(setq ObjFound 1) ;; set the Object Found flag,
(setq pt1 nil pt2 nil) ;; and clear the fence points.
) ;; end Progn.
(setq ObjFound 0) ;; If not, clear the Object Found flag.
) ;;---end IF-3.
) ;; end Progn.
(progn ;; If not (no new point because user hit Enter),
(setq pt1 nil pt2 nil) ;; clear the fence points,
(setq LoopFlag 0) ;; and prepare to end the loop.
) ;;end Progn.
) ;;---end IF-2.
) ;; end Progn
(progn ;; If not (no fence start point), look for an object to trim
(setvar "ErrNo" 0) ;; (entsel) error 7 = none found, error 52 = Enter
(setq e1 (entsel "Object to trim, or start point of fence: "))
(setq NewPt (getvar "LASTPOINT"))
(if (equal (getvar "ErrNo") 7) ;;-------4: Was an object found?
(setq ObjFound 0) ;; If not, clear the Object Found flag.
(progn ;; If one was found (no errror 7),
(setq ObjFound 1) ;; set the Object Found flag,
(setq pt1 nil pt2 nil) ;; and clear the fence points.
) ;;end Progn.
) ;;---end IF-4
(if (equal (getvar "ErrNo") 52) ;;-------5: Did the user hit Enter?
(progn ;; If so,
(setq pt1 nil pt2 nil) ;; clear the fence points,
(setq LoopFlag 0) ;; and prepare to end the loop.
) ;;end Progn.
) ;;---end IF-5
) ;; end Progn
) ;;---end IF-1
;;;-------------------------- Continue Loop, process user input
(if (= ObjFound 1) ;;--------6: Was an object found during user input?
(command "Trim" ss1 "" NewPt "") ;; If so, trim the object,
(progn ;; If not (no object found),
(if pt1 ;;---------7: Is there a fence start point?
(progn ;; If so,
(setq pt2 NewPt) ;; make the new point the fence end point,
(command "Trim" ss1 "" "F" pt1 pt2 "" "") ;; trim the fence objects,
(setq pt1 pt2) ;; allow continuation of the fence line,
(setq pt2 nil) ;; and get rid of the old end point.
) ;; end Progn
(progn ;; If not (no fence start point),
(setq pt1 NewPt) ;; make this pt1,
(setq pt2 nil) ;; and get rid of the old pt2.
) ;; end Progn
) ;;---end IF-7
) ;; end Progn
) ;;---end IF-6
) ;; end WHILE loop
(setvar "CMDECHO" SaveCE) ;; restore Command Echo status
(setvar "OSMODE" SaveOS) ;; restore Object Snap setting
(setq *error* SaveErr) ;; restore previous error-handling function
(hilite ss1 0) ;; turn off highlighting
) ;-----------------------------------------------------------
;;; EXTEND command with Fence mode automatically turned on and off
(defun c:EX (/ )
(setq SaveCE (getvar "CMDECHO")) ;; save Command Echo status
(setq SaveOS (getvar "OSMODE")) ;; save Object Snap setting
(setq SaveErr *error*) ;; save current error-handling function
(setq *error* IfAbort) ;; make IfAbort the error-handling function
(princ "Select boundary objects to extend to: ")
(setq ss1 (ssget)) ;; select boundary objects
(sssetfirst nil ss1) (sssetfirst nil) ;; turn off grips of any pre-selected set
;------------------------------------------------------
(setvar "CMDECHO" 0) ;; suppress command echo
(setvar "OSMODE" 0) ;; turn off object snap
(setq pt1 nil pt2 nil NewPt nil) ;; clear fence points & pick point
(setq LoopFlag 1) ;; set Loop flag
;------------------------------ Begin Loop, get user input
(while (equal LoopFlag 1) ;; Loop till no point is picked
(setq e1 nil)
(setq NewPt nil)
(hilite ss1 1) ;; highlight cutting edges
(if pt1 ;;----------1: Is there a fence start point?
(progn ;; If so, look for a new fence vertex.
(setq NewPt (getpoint pt1 "Next fence point, or object to extend: "))
(if NewPt ;;---------2: Did the user actually pick a new point?
(progn ;; If so,
(if (ssget NewPt) ;;---------3: Is there an object at NewPt?
(progn ;; If so,
(setq e1 (ssname (ssget NewPt) 0)) ;; make it e1,
(setq ObjFound 1) ;; set the Object Found flag,
(setq pt1 nil pt2 nil) ;; and clear the fence points.
) ;; end Progn.
(setq ObjFound 0) ;; If not, clear the Object Found flag.
) ;;---end IF-3.
) ;; end Progn.
(progn ;; If not (no new point because user hit Enter),
(setq pt1 nil pt2 nil) ;; clear the fence points,
(setq LoopFlag 0) ;; and prepare to end the loop.
) ;;end Progn.
) ;;---end IF-2.
) ;; end Progn
(progn ;; If not (no fence start point), look for an object to extend
(setvar "ErrNo" 0) ;; (entsel) error 7 = none found, error 52 = Enter
(setq e1 (entsel "Object to extend, or start point of fence: "))
(setq NewPt (getvar "LASTPOINT"))
(if (equal (getvar "ErrNo") 7) ;;-------4: Was an object found?
(setq ObjFound 0) ;; If not, clear the Object Found flag.
(progn ;; If one was found (no errror 7),
(setq ObjFound 1) ;; set the Object Found flag,
(setq pt1 nil pt2 nil) ;; and clear the fence points.
) ;;end Progn.
) ;;---end IF-4
(if (equal (getvar "ErrNo") 52) ;;-------5: Did the user hit Enter?
(progn ;; If so,
(setq pt1 nil pt2 nil) ;; clear the fence points,
(setq LoopFlag 0) ;; and prepare to end the loop.
) ;;end Progn.
) ;;---end IF-5
) ;; end Progn
) ;;---end IF-1
;;;-------------------------- Continue Loop, process user input
(if (= ObjFound 1) ;;--------6: Was an object found during user input?
(command "Extend" ss1 "" NewPt "") ;; If so, extend the object,
(progn ;; If not (no object found),
(if pt1 ;;---------7: Is there a fence start point?
(progn ;; If so,
(setq pt2 NewPt) ;; make the new point the fence end point,
(command "Extend" ss1 "" "F" pt1 pt2 "" "") ;; extend fence objects,
(setq pt1 pt2) ;; allow continuation of the fence line,
(setq pt2 nil) ;; and get rid of the old end point.
) ;; end Progn
(progn ;; If not (no fence start point),
(setq pt1 NewPt) ;; make this pt1,
(setq pt2 nil) ;; and get rid of the old pt2.
) ;; end Progn
) ;;---end IF-7
) ;; end Progn
) ;;---end IF-6
) ;; end WHILE loop
(setvar "CMDECHO" SaveCE) ;; restore Command Echo status
(setvar "OSMODE" SaveOS) ;; restore Object Snap setting
(setq *error* SaveErr) ;; restore previous error-handling function
(hilite ss1 0) ;; turn off highlighting
) ;-----------------------------------------------------------