;;; --------------------------------------------------------------------- ;;; MNMXT-bgol.lsp ;;; Command: MNMX ;;; ;;; PURPOSE ;;; Given a polyline boundary, scans all TEXT entities located within ;;; that boundary, identifies the minimum and maximum numeric values ;;; among them, and marks those specific text entities with a fitted ;;; circle -- filling the gap left by the native FIND command, which ;;; can only locate a known value, not determine which of many is ;;; smallest or largest. ;;; ;;; USAGE ;;; 1. Load this file (APPLOAD or drag-drop onto the drawing window). ;;; 2. Type MNMX at the command line and press Enter. ;;; 3. Select a closed polyline boundary. ;;; 4. All numeric TEXT entities whose insertion point falls inside ;;; that boundary are scanned. The minimum-value text is circled ;;; in blue and the maximum-value text is circled in red, both on ;;; layer "BGOL-MNMX". The values and count are reported at the ;;; command line. ;;; ;;; NOTES ;;; - This is an original, independently written implementation. ;;; It is INSPIRED by the general idea of boundary-scoped min/max ;;; text-value finder utilities common in survey/CAD 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:MNMX-EnsureLayer (lname / ) (if (not (tblsearch "LAYER" lname)) (entmake (list '(0 . "LAYER") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbLayerTableRecord") (cons 2 lname) '(70 . 0) '(62 . 7) ; white/black (default draw colour; circles colored per-entity) '(6 . "Continuous"))) ) ) ;; Standard point-in-polygon (crossing number) test using a vertex list (defun BGOL:MNMX-PointInPoly (pt verts / n i j inside xi yi xj yj x y) (setq x (car pt) y (cadr pt)) (setq n (length verts)) (setq inside nil) (setq i 0) (while (< i n) (setq j (if (= i 0) (1- n) (1- i))) (setq xi (car (nth i verts)) yi (cadr (nth i verts))) (setq xj (car (nth j verts)) yj (cadr (nth j verts))) (if (and (/= (>= yi y) (>= yj y)) (< x (+ xi (* (/ (- xj xi) (- yj yi)) (- y yi))))) (setq inside (not inside)) ) (setq i (1+ i)) ) inside ) (defun BGOL:MNMX-MarkCircle (obj colorcode lname / minpt maxpt radius center) (vla-getboundingbox obj 'minpt 'maxpt) (setq minpt (vlax-safearray->list minpt)) (setq maxpt (vlax-safearray->list maxpt)) (setq radius (* (/ (distance minpt maxpt) 2.0) 1.2)) (setq center (list (/ (+ (car minpt) (car maxpt)) 2.0) (/ (+ (cadr minpt) (cadr maxpt)) 2.0) (/ (+ (caddr minpt) (caddr maxpt)) 2.0))) (entmake (list '(0 . "CIRCLE") (cons 8 lname) (cons 10 center) (cons 40 radius) (cons 62 colorcode))) ) (defun C:MNMX ( / lname bnd bndobj verts allText ss n i ent obj pt val minval maxval minent maxent) (setq lname "BGOL-MNMX") (BGOL:MNMX-EnsureLayer lname) (setq bnd (car (entsel "\nSelect polyline boundary: "))) (if (and bnd (member (cdr (assoc 0 (entget bnd))) '("LWPOLYLINE" "POLYLINE"))) (progn (setq bndobj (vlax-ename->vla-object bnd)) ;; extract vertex list (2D, WCS) for point-in-polygon test (setq verts (vlax-safearray->list (vlax-variant-value (vla-get-Coordinates bndobj)))) (setq verts (BGOL:MNMX-PairUp verts)) (setq allText (ssget "_X" '((0 . "TEXT")))) (setq minval nil maxval nil minent nil maxent nil n 0) (if allText (progn (setq i 0) (repeat (sslength allText) (setq ent (ssname allText i)) (setq obj (vlax-ename->vla-object ent)) (setq pt (vlax-get obj 'InsertionPoint)) (if (BGOL:MNMX-PointInPoly pt verts) (progn (setq val (atof (vlax-get obj 'TextString))) (setq n (1+ n)) (if (or (null minval) (< val minval)) (setq minval val minent ent)) (if (or (null maxval) (> val maxval)) (setq maxval val maxent ent)) ) ) (setq i (1+ i)) ) (if (and minent maxent) (progn (BGOL:MNMX-MarkCircle (vlax-ename->vla-object minent) 5 lname) ; blue = minimum (BGOL:MNMX-MarkCircle (vlax-ename->vla-object maxent) 1 lname) ; red = maximum (princ (strcat "\nMNMX: " (itoa n) " text entit" (if (= n 1) "y" "ies") " found inside boundary.")) (princ (strcat "\nMinimum value: " (rtos minval 2 3) " (circled blue)")) (princ (strcat "\nMaximum value: " (rtos maxval 2 3) " (circled red)")) ) (princ "\nNo numeric text found inside the selected boundary.") ) ) (princ "\nNo text entities found in the drawing.") ) ) (princ "\nNo valid polyline boundary selected.") ) (princ) ) ;; helper: pair up a flat (x1 y1 x2 y2 ...) list into ((x1 y1) (x2 y2) ...) (defun BGOL:MNMX-PairUp (flatlist / result i n) (setq result '()) (setq n (length flatlist)) (setq i 0) (while (< i n) (setq result (append result (list (list (nth i flatlist) (nth (1+ i) flatlist))))) (setq i (+ i 2)) ) result ) (princ "\nMNMXT-bgol.lsp loaded. Type MNMX to find min/max text value inside a polyline boundary.") (princ "\n -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --") (princ)