;;; --------------------------------------------------------------------- ;;; VXTXT-bgol.lsp ;;; Command: VXTX ;;; ;;; PURPOSE ;;; Builds a brand-new LWPOLYLINE that passes through the insertion ;;; points of a set of selected TEXT/MTEXT entities (e.g., elevation ;;; labels placed along an existing polyline). The result is a new ;;; polyline with a vertex located exactly at each selected text's ;;; position, ordered by nearest-neighbour walking from a chosen start ;;; point. The original polyline (if any) is left completely untouched. ;;; ;;; USAGE ;;; 1. Load this file (APPLOAD or drag-drop onto the drawing window). ;;; 2. Type VXTX at the command line and press Enter. ;;; 3. Select the TEXT/MTEXT entities marking where new vertices ;;; should be (e.g., elevation labels sitting on a polyline). ;;; 4. A new LWPOLYLINE is created on layer "BGOL-VXTX", passing ;;; through every selected text's insertion point in order. ;;; ;;; NOTES ;;; - Text entities are ordered by walking a nearest-neighbour chain ;;; starting from the text closest to the first-selected point, ;;; so selection order does not need to already be sequential. ;;; - This is an original, independently written implementation. ;;; It is INSPIRED by the general idea of building vertex-marked ;;; polylines from existing text label positions, a technique ;;; common in survey/civil drafting workflows, but the code, ;;; command name and file name here are new and are NOT copied ;;; from, nor identical to, any specific third-party product. ;;; ;;; --------------------------------------------------------------------- ;;; Developed and shared for the CAD community by: BGol Community ;;; Community website: https://bgol.in/ ;;; License: Open-source & free to use, modify, and share for all. ;;; Provided "as is", without warranty of any kind. ;;; --------------------------------------------------------------------- (vl-load-com) (defun BGOL:VXTX-EnsureLayer (lname / ) (if (not (tblsearch "LAYER" lname)) (entmake (list '(0 . "LAYER") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbLayerTableRecord") (cons 2 lname) '(70 . 0) '(62 . 3) ; green '(6 . "Continuous"))) ) ) (defun BGOL:VXTX-MakePolyline (pointlist lname / dxfdata pt) (setq dxfdata (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") (cons 8 lname) '(100 . "AcDbPolyline") (cons 90 (length pointlist)) '(70 . 0) ) ) (foreach pt pointlist (setq dxfdata (append dxfdata (list (cons 10 (list (car pt) (cadr pt)))))) ) (entmake dxfdata) ) ;; Pop the point in ptlist nearest to fromPt, return (nearpt . remaininglist) (defun BGOL:VXTX-PopNearest (fromPt ptlist / best bestd d pt rest) (setq best (car ptlist)) (setq bestd (distance fromPt best)) (foreach pt ptlist (setq d (distance fromPt pt)) (if (< d bestd) (progn (setq best pt) (setq bestd d))) ) (setq rest '()) (foreach pt ptlist (if (not (equal pt best 1e-8)) (setq rest (append rest (list pt)))) ) (list best rest) ) (defun C:VXTX ( / ss n i ent pt pts ordered cur result) (BGOL:VXTX-EnsureLayer "BGOL-VXTX") (setq ss (ssget '((0 . "TEXT,MTEXT")))) (if (and ss (>= (sslength ss) 2)) (progn (setq pts '()) (setq n (sslength ss)) (setq i 0) (while (< i n) (setq ent (ssname ss i)) (setq pt (cdr (assoc 10 (entget ent)))) (setq pts (append pts (list pt))) (setq i (1+ i)) ) ;; order points by nearest-neighbour chain starting at the first one (setq ordered (list (car pts))) (setq pts (cdr pts)) (setq cur (car ordered)) (while pts (setq result (BGOL:VXTX-PopNearest cur pts)) (setq cur (car result)) (setq pts (cadr result)) (setq ordered (append ordered (list cur))) ) (BGOL:VXTX-MakePolyline ordered "BGOL-VXTX") (princ (strcat "\nNew polyline created through " (itoa (length ordered)) " text-marked vertex position(s) (BGOL-VXTX).")) ) (princ "\nSelect at least 2 TEXT/MTEXT entities marking vertex positions.") ) (princ) ) (princ "\nVXTXT-bgol.lsp loaded. Type VXTX to build a polyline through selected text positions.") (princ "\n -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --") (princ)