2025-12-06 19:16:58 +04:00

331 lines
12 KiB
Common Lisp

(defun parseCSVLine (line / pos result)
(setq result '())
(while (setq pos (vl-string-search "," line))
(setq result (cons (substr line 1 pos) result))
(setq line (substr line (+ pos 2)))
)
(reverse (cons line result))
)
(defun readDPMNamesAndZoneFromCSV ( / file filename line zone dpmList counter row name)
;; Ask user to select CSV
(setq filename (getfiled "Select CSV File" (strcat (getenv "USERPROFILE") "\\Desktop\\") "csv" 0))
(if (not filename)
(progn (princ "\nNo file selected.") nil)
(progn
(setq file (open filename "r"))
(if (not file)
(progn (princ "\nFailed to open file.") nil)
(progn
;; Skip first line (header)
(read-line file)
;; Read first line (A2..F2) to get zone
(setq line (read-line file))
(setq row (parseCSVLine line))
(setq zone (nth 5 row)) ;; F2
;; Keep only digits from zone
(setq zone (vl-list->string (vl-remove-if-not '(lambda (c) (<= 48 c 57)) (vl-string->list zone))))
;; Initialize DPM list
(setq dpmList '())
(setq counter 1)
;; Read rest of the file
(while (setq line (read-line file))
(setq row (parseCSVLine line))
(setq name (nth 0 row)) ;; Column A
;; Only take every 24th row starting from first
(if (= (rem counter 24) 1)
(if (and name (/= name ""))
(setq dpmList (append dpmList (list (list (cons "NAME" name) (cons "ZONE" zone)))))
)
)
(setq counter (1+ counter))
)
(close file)
dpmList
)
)
)
)
)
(defun updateTagAttribute (ent tagValue / obj attribs att)
;; Convert entity to VLA object
(setq obj (vlax-ename->vla-object ent))
(if (and obj (eq (vla-get-hasattributes obj) :vlax-true))
(progn
(setq attribs (vlax-invoke obj 'GetAttributes))
(foreach att attribs
(if (eq (strcase (vla-get-TagString att)) "TAG1")
(vla-put-TextString att tagValue)
)
)
)
)
)
(defun addTextLabel (pt1 pt2 labelText / midPt textHeight alignPt)
;; Calculate midpoint of horizontal line
(setq midPt (list (/ (+ (car pt1) (car pt2)) 2.0) (cadr pt1)))
(setq textHeight 0.3) ;; Adjust text height as needed
(setq alignPt (list (car midPt) (+ (cadr midPt) 0.2))) ;; 0.3 units above line
;; Create text entity above the line with center alignment
(entmakex (list
'(0 . "TEXT")
(cons 10 alignPt) ;; Insertion point
(cons 11 alignPt) ;; Alignment point (required for centered text)
(cons 40 textHeight)
(cons 1 labelText)
(cons 72 1) ;; Center horizontal alignment
(cons 73 0) ;; Baseline vertical alignment
'(8 . "AS_ENET_CABLE") ;; Same layer as cables
'(62 . 7) ;; White color
))
)
(defun c:Init_Network ( / dpmCount rowCount colCount i row col x y spacingX spacingY blkName scaleFactor
startPt endPt zigzagStart secondCableEnds zigzagStarts cableCounter )
(setq firstHorizontalLabeled nil)
(setq cableCounter 2)
(setq blkName "DPM")
(setq hdvBlkName "HDV2_1756-EN4TR_CHILD")
(setq scaleFactor 0.45)
(setq spacingX 15.0)
(setq spacingY 9.0)
(setq dpmOffsetX 5.0)
(setq hdvY 4.0)
(setq secondCableEnds '())
(setq zigzagStarts '())
(command "_.ERASE" "ALL" "")
(setq filename (getfiled "Select CSV File" (strcat (getenv "USERPROFILE") "\\Desktop\\") "csv" 0))
(if (not filename)
(progn (princ "\nNo file selected.") (exit))
(progn
(setq file (open filename "r"))
(if (not file)
(progn (princ "\nFailed to open file.") (exit))
(progn
;; Skip header line
(read-line file)
;; Read first data line for zone
(setq line (read-line file)) ;; <-- assign to line
(setq row (parseCSVLine line))
(setq devices '())
(setq zone (nth 5 row)) ;; column F
;; extract digits only
(setq zone (vl-list->string
(vl-remove-if-not
'(lambda (c) (<= 48 c 57))
(vl-string->list zone)
)
))
;; Read rest of the lines for DPM names (column D, index 3)
(while (and (setq line (read-line file)) (/= line ""))
(setq row (parseCSVLine line))
(setq name (nth 3 row)) ;; Column D contains DPM names
;; Only include actual DPM names (must contain DPM and underscore, exclude header "DPM")
(if (and name (/= name "") (/= (strcase name) "DPM") (wcmatch (strcase name) "*_DPM*"))
(setq devices (append devices (list name)))
)
)
(close file)
)
)
)
)
(setq dpmCount (length devices))
;; Calculate grid size
(setq colCount (fix (sqrt dpmCount)))
(if (< (* colCount colCount) dpmCount)
(setq colCount (+ colCount 1))
)
(setq rowCount (fix (/ (+ dpmCount colCount -1) colCount)))
(setq gridWidth (* (- colCount 1) spacingX))
(setq centerOffsetX (- (/ gridWidth 2.0)))
(command "_.LAYER" "S" "0" "")
(command "_.INSERT" hdvBlkName (list 0 hdvY) scaleFactor scaleFactor 0)
(setq i 0)
(repeat dpmCount
(setq row (fix (/ i colCount)))
(setq col (rem i colCount))
(setq x (+ (* col spacingX) dpmOffsetX))
(setq y (* -1 row spacingY))
(setq dpmName (nth i devices))
(command "_.LAYER" "S" "0" "")
(command "_.INSERT" blkName (list x y) scaleFactor scaleFactor 0)
(setq ent (entlast))
(updateTagAttribute ent dpmName)
;; First cable: vertical up
(setq startPt (list (+ x 7.3656) (+ y 4.4406)))
(setq endPt (list (car startPt) (+ (cadr startPt) 2.0)))
(entmakex (list '(0 . "LINE") (cons 10 startPt) (cons 11 endPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq secondCableEnds (append secondCableEnds (list endPt)))
(if (or (= (rem (1+ i) colCount) 0) (= i (- dpmCount 1)))
(progn
(setq startPt (list (+ x 7.2677) (+ y 3.6094)))
(setq elbowPt (list (- (car startPt) 0.2) (- (cadr startPt) 0.2)))
(entmakex (list '(0 . "LINE") (cons 10 startPt) (cons 11 elbowPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq endPt (list (car elbowPt) (- (cadr elbowPt) 4.5)))
(entmakex (list '(0 . "LINE") (cons 10 elbowPt) (cons 11 endPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq zigzagStarts (append zigzagStarts (list nil)))
)
(progn
(setq zigzagStart (list (+ x 7.3656) (+ y 3.7852)))
(setq elbowPt (list (+ x 7.8585) (+ y 5.1262)))
(entmakex (list '(0 . "LINE") (cons 10 zigzagStart) (cons 11 elbowPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq startPt elbowPt)
(setq endPt (list (car startPt) (+ (cadr startPt) 1.3144)))
(entmakex (list '(0 . "LINE") (cons 10 startPt) (cons 11 endPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq zigzagStarts (append zigzagStarts (list endPt)))
)
)
(setq i (1+ i))
)
;; Combined loop
(setq i 0)
(repeat rowCount
(setq j (* i colCount))
(repeat (- colCount 1)
(if (< (1+ j) dpmCount)
(progn
(setq pt1 (nth j zigzagStarts))
(setq pt2 (nth (1+ j) secondCableEnds))
(if (and pt1 pt2 (listp pt1) (listp pt2))
(progn
(entmakex
(list
'(0 . "LINE")
(cons 10 pt1)
(cons 11 pt2)
'(62 . 256)
'(8 . "AS_ENET_CABLE")
)
)
(addTextLabel pt1 pt2 (strcat zone "701-CBL" (itoa cableCounter)))
(setq cableCounter (1+ cableCounter))
)
)
)
)
(setq j (1+ j))
)
;; Connect last in row to first in next row
(setq lastInRowIndex (- (* (1+ i) colCount) 1))
(setq firstInNextRowIndex (* (1+ i) colCount))
(if (and (< lastInRowIndex dpmCount) (< firstInNextRowIndex dpmCount))
(progn
(setq row i)
(setq col (- colCount 1))
(setq x (+ (* col spacingX) dpmOffsetX))
(setq y (* -1 row spacingY))
(setq downwardEndPt (list (- (+ x 7.2677) 0.2) (- (- (+ y 3.6094) 0.2) 4.5)))
(setq nextRow (1+ i))
(setq nextCol 0)
(setq nextX (+ (* nextCol spacingX) dpmOffsetX))
(setq nextY (* -1 nextRow spacingY))
(setq nextBlockFirstLineEnd (list (+ nextX 7.3656) (+ (+ nextY 4.4406) 2.0)))
(setq horizontalEndPt (list (car nextBlockFirstLineEnd) (cadr downwardEndPt)))
(entmakex (list '(0 . "LINE") (cons 10 downwardEndPt) (cons 11 horizontalEndPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(addTextLabel downwardEndPt horizontalEndPt (strcat zone "701-CBL" (itoa cableCounter)))
(setq cableCounter (1+ cableCounter))
(entmakex (list '(0 . "LINE") (cons 10 horizontalEndPt) (cons 11 nextBlockFirstLineEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
)
)
(setq i (1+ i))
)
;; Connect first block to HDV
(if (> dpmCount 0)
(progn
(setq firstX (+ (* 0 spacingX) dpmOffsetX))
(setq firstY (* -1 0 spacingY))
(setq firstBlockEnd (list (+ firstX 7.3656) (+ (+ firstY 4.4406) 2.0)))
(setq hdvEndPt (list (+ 0 1.4) (- hdvY 4.4)))
(setq horizontalEnd (list (+ (car hdvEndPt) 0.5) (cadr firstBlockEnd)))
(entmakex (list '(0 . "LINE") (cons 10 firstBlockEnd) (cons 11 horizontalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
;; This is intentionally first cable: label as first
(addTextLabel firstBlockEnd horizontalEnd (strcat zone "701-CBL1"))
(setq verticalEnd (list (car horizontalEnd) (+ (cadr hdvEndPt) 0.5)))
(entmakex (list '(0 . "LINE") (cons 10 horizontalEnd) (cons 11 verticalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(entmakex (list '(0 . "LINE") (cons 10 verticalEnd) (cons 11 hdvEndPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
)
)
;; Connect last block to HDV
(if (> dpmCount 0)
(progn
(setq lastBlockIndex (- dpmCount 1))
(setq lastRow (fix (/ lastBlockIndex colCount)))
(setq lastCol (rem lastBlockIndex colCount))
(setq lastX (+ (* lastCol spacingX) dpmOffsetX))
(setq lastY (* -1 lastRow spacingY))
(setq hdvLastEndPt (list (+ 0 1.1) (- hdvY 5.83)))
(if (= rowCount 1)
(progn
(setq startPt (list (- (+ lastX 7.2677) 0.2) (- (+ lastY 3.6094) 0.2)))
(setq extendedVerticalEnd (list (car startPt) (- (cadr hdvLastEndPt) 1.5)))
(entmakex (list '(0 . "LINE") (cons 10 startPt) (cons 11 extendedVerticalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
;; Reduce final horizontal length by 1 unit
(setq horizontalEnd (list (car hdvLastEndPt) (cadr extendedVerticalEnd)))
(entmakex (list '(0 . "LINE") (cons 10 extendedVerticalEnd) (cons 11 horizontalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
;; Single-row: last cable label (uses cableCounter)
(addTextLabel extendedVerticalEnd horizontalEnd (strcat zone "701-CBL" (itoa cableCounter)))
(entmakex (list '(0 . "LINE") (cons 10 horizontalEnd) (cons 11 hdvLastEndPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
)
(progn
;; Multiple rows:
(setq lastBlockVerticalEnd (list (- (+ lastX 7.2677) 0.2) (- (- (+ lastY 3.6094) 0.2) 4.5)))
(setq horizontalEnd (list (car hdvLastEndPt) (cadr lastBlockVerticalEnd)))
(entmakex (list '(0 . "LINE") (cons 10 lastBlockVerticalEnd) (cons 11 horizontalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(addTextLabel lastBlockVerticalEnd horizontalEnd (strcat zone "701-CBL" (itoa cableCounter)))
(entmakex (list '(0 . "LINE") (cons 10 horizontalEnd) (cons 11 hdvLastEndPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
)
)
)
)
(princ)
)