;;; --------------------------------------------------------------------- ;;; PBRKALL-bgol.lsp ;;; Command: PBRK ;;; ;;; PURPOSE ;;; Breaks every selected LWPOLYLINE at each point where it crosses any ;;; other selected LWPOLYLINE, producing individually editable segments ;;; at every mutual intersection. Useful when preparing road, drainage ;;; or utility networks for GIS export or topology cleanup. ;;; ;;; USAGE ;;; 1. Load this file (APPLOAD or drag-drop onto the drawing window). ;;; 2. Type PBRK at the command line and press Enter. ;;; 3. Select two or more LWPOLYLINEs that cross one another. ;;; 4. Each selected polyline is broken into separate segments at ;;; every intersection point. New segments are placed on layer ;;; "BGOL-PBRK". The original polylines are erased. ;;; ;;; NOTES ;;; - This is an original, independently written implementation. ;;; It is INSPIRED by the general idea of batch break-at- ;;; intersection utilities common in CAD/survey 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:PBRK-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:PBRK-MakeSeg (p1 p2 lname / dxfdata) (setq dxfdata (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") (cons 8 lname) '(100 . "AcDbPolyline") (cons 90 2) '(70 . 0) (cons 10 (list (car p1) (cadr p1))) (cons 10 (list (car p2) (cadr p2))) ) ) (entmakex dxfdata) ) ;; Break a single polyline object at a sorted list of parameters (0..1 excl endpoints) (defun BGOL:PBRK-BreakOne (obj params lname / sp ep plist i p1 p2) (setq sp (vlax-curve-getStartParam obj)) (setq ep (vlax-curve-getEndParam obj)) (setq params (vl-sort (vl-remove-if '(lambda (x) (or (<= x sp) (>= x ep))) params) '<)) (setq plist (append (list sp) params (list ep))) (setq i 0) (while (< i (1- (length plist))) (setq p1 (vlax-curve-getPointAtParam obj (nth i plist))) (setq p2 (vlax-curve-getPointAtParam obj (nth (1+ i) plist))) (if (and p1 p2 (> (distance p1 p2) 1e-6)) (BGOL:PBRK-MakeSeg p1 p2 lname) ) (setq i (1+ i)) ) ) (defun C:PBRK ( / ss n ents objs i j obj1 obj2 pts pt paramtbl ename brkcount res params) (BGOL:PBRK-EnsureLayer "BGOL-PBRK") (princ "\nSelect polylines to break at mutual intersections: ") (setq ss (ssget '((0 . "LWPOLYLINE")))) (if (and ss (>= (sslength ss) 2)) (progn (setq n (sslength ss)) (setq ents '()) (setq objs '()) (setq i 0) (while (< i n) (setq ename (ssname ss i)) (setq ents (append ents (list ename))) (setq objs (append objs (list (vlax-ename->vla-object ename)))) (setq i (1+ i)) ) ;; paramtbl: list of param-lists, one per entity, holding intersection params (setq paramtbl '()) (setq i 0) (while (< i n) (setq paramtbl (append paramtbl (list '()))) (setq i (1+ i))) ;; pairwise intersection (setq i 0) (while (< i n) (setq j (1+ i)) (while (< j n) (setq obj1 (nth i objs)) (setq obj2 (nth j objs)) (setq pts (vl-catch-all-apply 'vlax-invoke (list obj1 'IntersectWith obj2 acExtendNone))) (if (not (vl-catch-all-error-p pts)) (progn (while pts (setq pt (list (car pts) (cadr pts) (caddr pts))) (setq res (vl-catch-all-apply 'vlax-curve-getParamAtPoint (list obj1 pt))) (if (not (vl-catch-all-error-p res)) (setq paramtbl (subst (append (nth i paramtbl) (list res)) (nth i paramtbl) paramtbl)) ) (setq res (vl-catch-all-apply 'vlax-curve-getParamAtPoint (list obj2 pt))) (if (not (vl-catch-all-error-p res)) (setq paramtbl (subst (append (nth j paramtbl) (list res)) (nth j paramtbl) paramtbl)) ) (setq pts (cdddr pts)) ) ) ) (setq j (1+ j)) ) (setq i (1+ i)) ) ;; now break each polyline at its own collected params (setq brkcount 0) (setq i 0) (while (< i n) (setq params (nth i paramtbl)) (if params (progn (BGOL:PBRK-BreakOne (nth i objs) params "BGOL-PBRK") (entdel (nth i ents)) (setq brkcount (1+ brkcount)) ) ) (setq i (1+ i)) ) (princ (strcat "\nPBRK: " (itoa brkcount) " polyline(s) broken at intersections (layer BGOL-PBRK).")) ) (princ "\nSelect at least two intersecting polylines.") ) (princ) ) (princ "\nPBRKALL-bgol.lsp loaded. Type PBRK to break polylines at all mutual intersections.") (princ "\n -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --") (princ)