Ajmal Posted 2 hours ago Posted 2 hours ago ;;----------------------------=={ SmartPath }==-----------------------------;; ;; ;; ;; Creates a path connecting selected objects using various methods. ;; ;; Synthesized and enhanced by ajmalps, based on concepts from ;; ;; scripts by Kent Cooper, BlackBox, RJP, cab, and others. ;; ;; ;; ;; Command: SmartPath ;; ;; ;; ;;--------------------------------------------------------------------------;; ;; Date: August 6, 2025 (Fixed error handler on clean exit) ;; ;;--------------------------------------------------------------------------;; (vl-load-com) (defun c:SmartPath (/ *error* _get_midpoints _sort_nearest _sort_along_path _get_wire_settings doc ov_osmode ov_cmdecho sort_mode node_ss path_ent point_list sorted_list start_pt output_type layer) ;; --- CORRECTED Robust Error Handler --- (defun *error* (msg) (if ov_cmdecho (setvar 'CMDECHO ov_cmdecho)) (if ov_osmode (setvar 'OSMODE ov_osmode)) (if doc (vla-endundomark doc)) ;; Check if msg is a valid string before trying to process it (if (and msg (not (wcmatch (strcase msg t) "*CANCEL*,*QUIT*,*BREAK*"))) (princ (strcat "\nError: " msg)) ) (princ) ) ;; --- Helper: Get Center of Any Object's Bounding Box --- (defun _get_midpoints (ss / i ent vla_obj pt1 pt2 pt_list) (setq i 0) (repeat (sslength ss) (setq ent (ssname ss i)) (if (and (setq vla_obj (vlax-ename->vla-object ent)) (vlax-method-applicable-p vla_obj 'GetBoundingBox) ) (progn (vla-GetBoundingBox vla_obj 'pt1 'pt2) (setq pt_list (cons (mapcar '(lambda (a b) (/ (+ a b) 2.0)) (vlax-safearray->list pt1) (vlax-safearray->list pt2)) pt_list)) ) ) (setq i (1+ i)) ) pt_list ) ;; --- Helper: Sort by Nearest Neighbor --- (defun _sort_nearest (pt_list / current_pt sorted_list closest_pt) (setq current_pt (car pt_list) pt_list (cdr pt_list) sorted_list (list current_pt)) (while pt_list (setq closest_pt (car pt_list)) (foreach pt (cdr pt_list) (if (< (distance current_pt pt) (distance current_pt closest_pt)) (setq closest_pt pt))) (setq current_pt closest_pt sorted_list (cons current_pt sorted_list) pt_list (vl-remove current_pt pt_list)) ) (reverse sorted_list) ) ;; --- Helper: Sort Along a Guide Path --- (defun _sort_along_path (path_ent pt_list / path_obj) (setq path_obj (vlax-ename->vla-object path_ent)) (mapcar 'cdr (vl-sort (mapcar '(lambda (pt) (cons (vlax-curve-getDistAtPoint path_obj (vlax-curve-getClosestPointTo path_obj pt)) pt)) pt_list) '(lambda (a b) (< (car a) (car b))))) ) ;; --- Helper for Custom Wire Settings --- (defun _get_wire_settings ( / temp_h temp_a) (if (not *wire_height*) (setq *wire_height* 5.0)) (if (not *wire_angle_deg*) (setq *wire_angle_deg* 15.0)) (setq temp_h (getdist (strcat "\nEnter chamfer height <" (rtos *wire_height*) ">: "))) (setq temp_a (getangle (strcat "\nEnter chamfer angle in degrees <" (rtos *wire_angle_deg*) ">: "))) (if temp_h (setq *wire_height* temp_h)) (if temp_a (setq *wire_angle_deg* (/ (* temp_a 180.0) PI))) (list *wire_height* *wire_angle_deg*) ) ;;============== Main Execution Starts Here ============== (setq doc (vla-get-activedocument (vlax-get-acad-object))) (vla-startundomark doc) (setq ov_cmdecho (getvar 'CMDECHO) ov_osmode (getvar 'OSMODE)) (setvar 'CMDECHO 0) (initget "Nearest Path") (setq sort_mode (getkword "\nSelect sorting mode [Nearest/Path] <Nearest>: ")) (if (not sort_mode) (setq sort_mode "Nearest")) (cond ((= sort_mode "Nearest") (princ "\nSelect objects to connect: ") (if (and (setq node_ss (ssget '((0 . "~VIEWPORT")))) (setq start_pt (getpoint "\nPick point to start path from: ")) (setq point_list (_get_midpoints node_ss))) (setq sorted_list (_sort_nearest (cons start_pt point_list))) ) ) ((= sort_mode "Path") (princ "\nSelect guide path (line, pline, spline, etc.): ") (if (and (setq path_ent (car (entsel))) (princ "\nSelect objects to connect: ") (setq node_ss (ssget '((0 . "~VIEWPORT")))) (setq point_list (_get_midpoints node_ss))) (setq sorted_list (_sort_along_path path_ent point_list)) ) ) ) (if sorted_list (progn (initget "Polyline Line Arc Spline Wire") (setq output_type (getkword "\nSelect output type [Polyline/Line/Arc/Spline/Wire] <Polyline>: ")) (if (not output_type) (setq output_type "Polyline")) (setq layer (getstring (strcat "\nEnter layer for path <" (getvar "CLAYER") ">: "))) (if (= "" layer) (setq layer (getvar "CLAYER"))) (setvar 'OSMODE 0) (princ (strcat "\nDrawing " output_type "...")) (cond ((= output_type "Polyline") (entmakex (append '((0 . "LWPOLYLINE") (100 . "AcDbEntity") (100 . "AcDbPolyline")) (list (cons 8 layer) (cons 90 (length sorted_list)) '(70 . 0)) (mapcar '(lambda (pt) (cons 10 pt)) sorted_list))) ) ((= output_type "Line") (mapcar '(lambda (p1 p2) (entmakex (list '(0 . "LINE") (cons 8 layer) (cons 10 p1) (cons 11 p2)))) sorted_list (cdr sorted_list)) ) ((= output_type "Arc") (mapcar '(lambda (p1 p2 / ptm) (setq ptm (polar (polar p1 (angle p1 p2) (/ (distance p1 p2) 2.0)) (+ (angle p1 p2) (/ PI 2.0)) (* (distance p1 p2) 0.18))) (command "_.ARC" "_none" p1 "_none" ptm "_none" p2) (if (entlast) (command "_.CHPROP" (entlast) "" "_LA" layer ""))) sorted_list (cdr sorted_list)) ) ((= output_type "Wire") (progn (setq settings (_get_wire_settings) w_height (car settings) w_ang_deg (cadr settings) w_ang_rad (/ (* w_ang_deg PI) 180.0)) (mapcar '(lambda (p_start p_end / offset_start offset_end) (setq offset_start (polar p_start (+ (angle p_start p_end) w_ang_rad) w_height) offset_end (polar p_end (- (angle p_end p_start) w_ang_rad) w_height)) (entmakex (list '(0 . "LWPOLYLINE") (cons 8 layer) '(100 . "AcDbEntity") '(100 . "AcDbPolyline") '(90 . 4) '(70 . 0) (cons 10 p_start) (cons 10 offset_start) (cons 10 offset_end) (cons 10 p_end))) ) sorted_list (cdr sorted_list) ) ) ) ((= output_type "Spline") (entmakex (append '((0 . "SPLINE") (100 . "AcDbEntity") (100 . "AcDbSpline")) (list (cons 8 layer) '(70 . 8) '(71 . 3) (cons 72 (length sorted_list)) (cons 73 (length sorted_list)) '(74 . 0)) (mapcar '(lambda (pt) (cons 11 pt)) sorted_list))) ) ) (princ " Done.") ) (princ "\nPath creation cancelled or no valid objects found.") ) (*error* nil) ) (princ "\n:: SmartPath.lsp loaded. Command: SmartPath ::") (princ) try this Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.