autocad/network-v2.lsp
2025-07-23 20:57:16 +04:00

646 lines
21 KiB
Common Lisp

(defun clearDrawing ( / ss)
;; Select all visible, non-locked entities and delete them
(setq ss (ssget "_X" '((0 . "*")))) ; select everything
(if ss
(progn
(command "_.erase" ss "")
(princ "\nDrawing cleared.")
)
)
)
(defun getGap (count)
(cond
((<= count 20) 3.95)
((< count 25) 3.5)
((< count 36) 2.2)
((>= count 36) 1.3)
)
)
(defun getFinalOffsetY (numBlocks)
(cond
((>= numBlocks 36) 12.0)
((>= numBlocks 25) 11.5)
(T 10.5)
)
)
;; Function to get final stop for "new block" with negative XScale
(defun getFinalStopNewBlock ( / ss i ent obj xScale insPt finalX finalY finalZ finalStop)
(vl-load-com)`
(setq ss (ssget "X" '((0 . "INSERT") (2 . "new block"))))
(if (and ss (> (sslength ss) 0))
(progn
(setq i 0)
(while (< i (sslength ss))
(setq ent (ssname ss i))
(setq obj (vlax-ename->vla-object ent))
(setq xScale (vlax-get obj 'XScaleFactor))
(if (< xScale 0.0)
(progn
;; Get block insertion point and calculate final stop
(setq insPt (vlax-get obj 'InsertionPoint))
(setq finalX (+ (car insPt) 0.578))
(setq finalY (- (cadr insPt) 0.0072))
(setq finalZ (nth 2 insPt))
(setq finalStop (list finalX finalY finalZ))
(setq i (sslength ss)) ; exit loop early
)
)
(setq i (1+ i))
)
finalStop ; return
)
)
)
(defun getFinalStopSecondNewBlock ()
(vl-load-com)
(setq finalStop nil)
;; Get selection set of all "new block" inserts
(setq ss (ssget "X" '((0 . "INSERT") (2 . "new block"))))
(if (and ss (> (sslength ss) 0))
(progn
(setq i 0)
(while (< i (sslength ss))
(setq ent (ssname ss i))
(setq obj (vlax-ename->vla-object ent))
;; Get X scale
(setq xScale (vlax-get obj 'XScaleFactor))
(if (> xScale 0.0) ;; positive X scale = second block
(progn
;; Found second block
(setq insPt (vlax-get obj 'InsertionPoint)) ; list of 3 coords
(setq finalX (- (car insPt) 0.578))
(setq finalY (- (cadr insPt) 0.0072))
(setq finalStop (list finalX finalY (last insPt)))
(setq i (sslength ss)) ; exit loop
)
)
(setq i (1+ i))
)
)
)
finalStop
)
(defun drawHorizontalToFinalStop (startPt targetX)
(setq endPt (list targetX (cadr startPt) (caddr startPt)))
(entmake
(list
(cons 0 "LINE")
(cons 8 "0") ; Layer 0
(cons 62 3) ; Green color
(cons 10 startPt)
(cons 11 endPt)
)
)
)
(defun labelLine (pt1 pt2 index moveRight? / midPt labelText offsetPt)
;; Compose label text
(setq labelText (strcat "8911-CBL " (itoa index)))
;; Calculate midpoint
(setq midPt (list (/ (+ (car pt1) (car pt2)) 2.0)
(/ (+ (cadr pt1) (cadr pt2)) 2.0)
0.0))
;; Apply offset: if moveRight? then +2 in X, else -1 in X, and -0.05 in Y
(setq offsetPt (list (+ (car midPt) (if moveRight? 1.5 -1.0))
(- (cadr midPt) 0.05)
0.0))
;; Create the text entity
(entmake
(list
(cons 0 "TEXT")
(cons 8 "0")
(cons 10 offsetPt)
(cons 40 0.3) ; text height
(cons 1 labelText)
(cons 7 "Standard") ; style
(cons 72 1) ; left justified
(cons 73 1) ; middle baseline
(cons 11 offsetPt)
)
)
)
(defun drawZigzagCables (connectorData targetPt centerOffset numBlocks / sorted i pt1 pt2 direction yDown turnPoint cur next moveTo)
(setq lineIndex 2)
(setq greenColor 3) ; green
;; Calculate movement offset (same as blocks)
(setq moveTo
(list
(+ (car centerOffset) (if (>= numBlocks 36) 20.0 23.0))
(+ (cadr centerOffset) (getFinalOffsetY numBlocks))
0.0
)
)
;; Sort connectorData in snake order
(setq sorted
(vl-sort connectorData
(function
(lambda (a b)
(cond
((< (car a) (car b)) T) ; row
((> (car a) (car b)) nil)
;; same row, order by column - reversed for odd rows
((= (rem (car a) 2) 1) (> (cadr a) (cadr b)))
(T (< (cadr a) (cadr b)))
)
)
)
)
)
(setq i 0)
(while (and (< i (length sorted)))
(setq cur (nth i sorted))
(setq next (nth (1+ i) sorted))
(setq isOddRow (= (rem (car cur) 2) 1))
;; Check if current block is the last in its row
(if (or (= i (1- (length sorted))) ; last block overall
(and next (/= (car cur) (car next)))) ; or next block is in different row
(progn
;; Get start point: x2 for even row, x1 for odd row
(setq pt1 (mapcar '+ (list (if isOddRow (nth 2 cur) (nth 3 cur)) (nth 4 cur) 0.0) moveTo))
;; Step 1: short horizontal (1 unit left or right)
(setq horizOffset (if isOddRow -3.0 1.0))
(setq pt2 (list (+ (car pt1) horizOffset) (cadr pt1) 0.0))
(setq shouldLabel T)
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor) (cons 10 pt1) (cons 11 pt2)))
(setq shouldMoveRight (and (not isOddRow) ; even row
(or (= i (1- (length sorted))) ; last block overall
(and next (/= (car cur) (car next))))) ; or last in row
)
(if shouldLabel (labelLine pt1 pt2 lineIndex shouldMoveRight))
(setq lineIndex (1+ lineIndex))
;; Step 2: vertical drop if there's a next block
(if next
(progn
(setq shouldLabel nil)
(setq pt3 (list (car pt2) (+ (cadr moveTo) (nth 4 next)) 0.0))
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor) (cons 10 pt2) (cons 11 pt3)))
;; Step 3: horizontal to connector of next block
(setq pt4 (list (if isOddRow (nth 2 next) (nth 3 next)) (nth 4 next) 0.0))
(setq pt4 (mapcar '+ pt4 moveTo))
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor) (cons 10 pt3) (cons 11 pt4)))
)
)
)
)
;; Horizontal connection to next block in same row
(if (and next (= (car cur) (car next))) ; same row
(progn
;; Choose correct x sides for direction
(if isOddRow
(progn
;; right to left
(setq pt1 (mapcar '+ (list (nth 2 cur) (nth 4 cur) 0.0) moveTo)) ; x1 cur
(setq pt2 (mapcar '+ (list (nth 3 next) (nth 4 next) 0.0) moveTo)) ; x2 next
)
(progn
;; left to right
(setq pt1 (mapcar '+ (list (nth 3 cur) (nth 4 cur) 0.0) moveTo)) ; x2 cur
(setq pt2 (mapcar '+ (list (nth 2 next) (nth 4 next) 0.0) moveTo)) ; x1 next
)
)
(setq shouldLabel T)
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor) (cons 10 pt1) (cons 11 pt2)))
(if shouldLabel (labelLine pt1 pt2 lineIndex f))
(setq lineIndex (1+ lineIndex))
)
)
(setq i (1+ i))
)
;; Draw extra for last block
(setq lastIndex (1- (length sorted)))
(setq lastBlock (nth lastIndex sorted))
(setq rowNum (car lastBlock))
(setq isEvenRow (= (rem rowNum 2) 0))
;; Only draw the extra if last block didn't already connect downward
(if (= lastIndex (1- (length sorted))) ; true last block
(if isEvenRow
(progn
(setq finalStop (getFinalStopNewBlock))
(if finalStop
(progn
;; Print finalStop for debug
(prompt (strcat "\nFinal stop X: " (rtos (car finalStop) 2 4)
", Y: " (rtos (cadr finalStop) 2 4)
", Z: " (rtos (caddr finalStop) 2 4)))
;; EVEN row: x2 → right 1 → down 1
(setq pt1 (mapcar '+ (list (nth 3 lastBlock) (nth 4 lastBlock) 0.0) moveTo)) ; x2
(setq pt2 (list (+ (car pt1) 1.0) (cadr pt1) 0.0)) ; right 1
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor)
(cons 10 pt1) (cons 11 pt2)))
(setq pt3 (list (car pt2) (- (cadr pt2) 1.0) 0.0)) ; down 1
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor)
(cons 10 pt2) (cons 11 pt3)))
;; Step 3: go left to near finalStop.x
(setq xTarget (+ (car finalStop) 1.0))
(setq pt4 (list xTarget (cadr pt3) 0.0))
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor)
(cons 10 pt3) (cons 11 pt4)))
;; Step 4: vertical to finalStop.y
(setq pt5 (list xTarget (cadr finalStop) 0.0))
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor)
(cons 10 pt4) (cons 11 pt5)))
;; Step 5: final horizontal to exact finalStop.x
(setq pt6 (list (car finalStop) (cadr finalStop) 0.0))
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor)
(cons 10 pt5) (cons 11 pt6)))
)
(prompt "\nError: finalStop is NIL! 'new block' with negative XScale not found.")
)
)
(progn
(setq finalStop (getFinalStopNewBlock))
(if finalStop
(progn
;; Print finalStop for debug
(prompt (strcat "\nFinal stop X: " (rtos (car finalStop) 2 4)
", Y: " (rtos (cadr finalStop) 2 4)
", Z: " (rtos (caddr finalStop) 2 4)))
;; Get x1 of last block + movement
(setq pt1 (mapcar '+ (list (nth 2 lastBlock) (nth 4 lastBlock) 0.0) moveTo))
;; Calculate X target (1 unit before finalStop X)
(setq xTarget (+ (car finalStop) 1.0))
;; Horizontal point (end of first line)
(setq horizPt (list xTarget (cadr pt1) 0.0))
;; Vertical line end
(setq vertPt (list xTarget (cadr finalStop) 0.0))
;; Draw horizontal
(drawHorizontalToFinalStop pt1 xTarget)
;; Draw vertical
(entmake (list
(cons 0 "LINE")
(cons 8 "0")
(cons 62 greenColor)
(cons 10 horizPt)
(cons 11 vertPt)))
;; Final horizontal: to reach exact finalStop X
(setq finalPt (list (car finalStop) (cadr finalStop) 0.0))
(entmake (list
(cons 0 "LINE")
(cons 8 "0")
(cons 62 greenColor)
(cons 10 vertPt)
(cons 11 finalPt)))
)
(prompt "\nError: finalStop is NIL! 'new block' with negative XScale not found.")
)
)
)
)
;; Draw extra line for first block (x1 → left until aligned with final route)
(setq finalStop (getFinalStopNewBlock))
(if finalStop
(progn
;; Print finalStop for debug
(prompt (strcat "\nFinal stop X: " (rtos (car finalStop) 2 4)
", Y: " (rtos (cadr finalStop) 2 4)
", Z: " (rtos (caddr finalStop) 2 4)))
(setq firstBlock (car sorted))
(setq pt1 (mapcar '+ (list (nth 2 firstBlock) (nth 4 firstBlock) 0.0) moveTo)) ; x1
(setq targetX (+ (car finalStop) 1.0)) ; align with the rest
(setq pt2 (list targetX (cadr pt1) 0.0)) ; same Y, just X target
;; Draw the horizontal line
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor)
(cons 10 pt1) (cons 11 pt2)))
(setq pt3 (list (car pt2) (+ (cadr finalStop) 2.0) 0.0))
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor)
(cons 10 pt2) (cons 11 pt3)))
;; Draw line label
(labelLine pt1 pt2 1 f)\
;; Now get second final stop and add horizontal line from pt3 to second final stop X + 1
(setq finalStop2 (getFinalStopSecondNewBlock))
(if finalStop2
(progn
;; Print debug info for second stop
(prompt (strcat "\nSecond Final stop X: " (rtos (car finalStop2) 2 4)
", Y: " (rtos (cadr finalStop2) 2 4)
", Z: " (rtos (caddr finalStop2) 2 4)))
;; Target point for second horizontal line (to second final stop X + 1, same Y as pt3)
(setq pt4 (list (- (car finalStop2) 1.0) (cadr pt3) 0.0))
;; Draw horizontal line to second final stop X + 1
(entmake (list (cons 0 "LINE") (cons 8 "0") (cons 62 greenColor)
(cons 10 pt3) (cons 11 pt4)))
;; Draw vertical line down from pt4 to finalStop2 Y (keeping pt4.X)
(setq vertPt (list (car pt4) (cadr finalStop2) 0.0))
(entmake (list
(cons 0 "LINE")
(cons 8 "0")
(cons 62 greenColor)
(cons 10 pt4)
(cons 11 vertPt)))
;; Draw horizontal line from vertPt to finalStop2 (full X and Y)
(entmake (list
(cons 0 "LINE")
(cons 8 "0")
(cons 62 greenColor)
(cons 10 vertPt)
(cons 11 finalStop2)))
)
(prompt "\nError: finalStop2 is NIL! 'new block' with positive XScale not found.")
)
)
(prompt "\nError: finalStop is NIL! 'new block' with negative XScale not found.")
)
)
(defun readDeviceListFromFile ( / file filePath line result)
;; Open file dialog for user to pick device list text file
(setq filePath (getfiled "Select Device List File" "" "txt" 0))
(if filePath
(progn
(setq file (open filePath "r"))
(setq result '()) ;; initialize empty list before appending
(while (setq line (read-line file))
(setq result (append result (list (strcase (vl-string-trim " \t\r\n" line)))))
)
(close file)
result
)
nil
)
)
(defun c:Init_Network ( / numBlocks cols rows i row col x y
spacing gap baseGap totalWidth totalHeight
xStart yStart basePt targetPt ent blkRef
attList centerOffset)
;; Clear everything first
(clearDrawing)
(setq deviceList (readDeviceListFromFile))
(if (not deviceList)
(progn
(princ "\nError: Device list file not found or empty.")
(exit)
)
)
(setq numBlocks (length deviceList))
; Grid dimensions
(setq rows (fix (sqrt numBlocks))) ; fewer rows
(setq cols (fix (/ (+ numBlocks rows -1) rows))) ; more columns
(if (or (= numBlocks 25) (= numBlocks 36))
(setq cols (1+ cols))
)
;; Dynamic gap
(setq gap (getGap numBlocks))
(setq spacing 3.0)
(setq step (+ spacing gap)) ; actual distance between blocks
;; Insert background grid block
(setvar "CLAYER" "AS_GRID")
(setq basePt "0,0,0")
(command "_-INSERT" "A$Cae272396" basePt 1 1 0)
;; UPS block layer and setup
(setvar "CLAYER" "AS_ENET CABLE")
(setvar "ATTDIA" 0)
(setvar "ATTREQ" 0)
;; Calculate offsets for centering
(setq totalWidth (* cols step))
(setq totalHeight (* rows step))
(setq xStart (- (/ totalWidth 2.0)))
(setq yStart (/ totalHeight 2.0))
(setq centerOffset (list (/ spacing 2.0) (/ spacing 2.0) 0.0))
(setq extraColGap (if (>= numBlocks 36) 0.75 0.0))
(setq i 0)
;; Place UPS blocks
(while (< i numBlocks)
(setq row (/ i cols))
(setq col (rem i cols))
;; Snake pattern
(if (= (rem row 2) 1)
(setq col (- cols 1 col))
)
;; Grid point
(setq x (+ xStart (* col step) (* col extraColGap)))
(setq y (- yStart (* row step)))
(setq targetPt (list x y 0))
;; Insert block at 0,0 and scale
(command "_-INSERT" "UPS_DPM_BRACKET" "0,0,0" 0.2212 0.2212 0.2212 0)
(setq ent (entlast))
(if ent
(setq blkRef (vlax-ename->vla-object ent))
(princ "\nError: Block insert failed.")
)
;; Move to adjusted centered position
(setq moveTo
(mapcar '+ targetPt
(list
(+ (car centerOffset) (if (>= numBlocks 36) 20.0 23.0))
(+ (cadr centerOffset) (getFinalOffsetY numBlocks))
0.0
)
)
)
(vla-move blkRef (vlax-3d-point '(0 0 0)) (vlax-3d-point moveTo))
;; Get device name for current block
(setq deviceName (nth i deviceList))
;; Set TAG2 attribute to zigzag index
(setq attList (vlax-invoke blkRef 'GetAttributes))
(foreach att attList
(if (= (strcase (vla-get-TagString att)) "TAG2")
(vla-put-TextString att deviceName)
)
)
;; === Draw connector lines ===
(setq start1 (list (+ (car moveTo) 3.99) (- (cadr moveTo) 3.196) 0.0))
(setq end1 (list (car start1) (- (cadr start1) 0.25) 0.0))
(setq start2 (list (+ (car moveTo) 4.155) (cadr start1) 0.0))
(setq end2 (list (car start2) (- (cadr start2) 0.25) 0.0))
(setvar "CLAYER" "0") ; or create a special cable layer if needed
(setq greenColor 3) ; AutoCAD color index for green
;; Draw first line
(entmake
(list
(cons 0 "LINE")
(cons 8 "0") ; layer
(cons 62 greenColor) ; color
(cons 10 start1)
(cons 11 end1)
)
)
;; Draw second line
(entmake
(list
(cons 0 "LINE")
(cons 8 "0") ; layer
(cons 62 greenColor)
(cons 10 start2)
(cons 11 end2)
)
)
(setq i (1+ i))
)
;; Layer and attribute prompt settings
(setvar "CLAYER" "PSYMS")
(setvar "ATTDIA" 0)
(setvar "ATTREQ" 0)
;; Target positions
(setq ptTop (list 1.0 16.0 0.0)) ; Top block
(setq ptBot (list 1.86 10.0 0.0)) ; Bottom block
;; If block count is 16 or less, shift X positions by +4.0
(cond
((<= numBlocks 16)
(setq ptTop (list (+ (car ptTop) 4.0) (cadr ptTop) (caddr ptTop)))
(setq ptBot (list (+ (car ptBot) 4.0) (cadr ptBot) (caddr ptBot))))
((and (>= numBlocks 25) (< numBlocks 31))
(setq ptTop (list (+ (car ptTop) 3.0) (cadr ptTop) (caddr ptTop)))
(setq ptBot (list (+ (car ptBot) 3.0) (cadr ptBot) (caddr ptBot))))
)
;; Insert top block (1783-BMS20CGL)
(command "_-INSERT" "1783-BMS20CGL" "0,0,0" 0.75 0.75 0.75 0)
(setq blk1 (vlax-ename->vla-object (entlast)))
(vla-put-Rotation blk1 0.0) ; <- Force zero rotation
(vla-move blk1 (vlax-3d-point '(0 0 0)) (vlax-3d-point ptTop))
;; Insert bottom block (PATCH_PANEL)
(command "_-INSERT" "PATCH_PANEL" "0,0,0" 0.75 0.75 0.75 0)
(setq blk2 (vlax-ename->vla-object (entlast)))
(vla-put-Rotation blk2 0.0) ; <- Force zero rotation
(vla-move blk2 (vlax-3d-point '(0 0 0)) (vlax-3d-point ptBot))
;; Calculate new Y position based on second block (PATCH_PANEL)
(setq newBlockY (+ (cadr ptBot) 1.3702))
;; X positions relative to second block X
(setq newBlock1X (+ (car ptBot) 0.4274))
(setq newBlock2X (+ (car ptBot) 1.5219))
;; Y position for both new blocks
(setq newBlockYPos newBlockY)
;; Insert first "new block"
(command "_-INSERT" "new block" "0,0,0" 0.5909 0.5909 0.5909 0)
(setq newBlk1 (vlax-ename->vla-object (entlast)))
(vla-put-Rotation newBlk1 0.0)
(vla-move newBlk1 (vlax-3d-point '(0 0 0)) (vlax-3d-point (list newBlock1X newBlockYPos 0.0)))
;; Insert second "new block" mirrored on X scale
(command "_-INSERT" "new block" "0,0,0" -0.5909 0.5909 0.5909 0)
(setq newBlk2 (vlax-ename->vla-object (entlast)))
(vla-put-Rotation newBlk2 0.0)
(vla-move newBlk2 (vlax-3d-point '(0 0 0)) (vlax-3d-point (list newBlock2X newBlockYPos 0.0)))
;; === Collect connector info ===
(setq connectorData '())
(setq i 0)
(while (< i numBlocks)
(setq row (/ i cols))
(setq col (rem i cols))
(prompt (strcat "numBlocks: " (itoa numBlocks)))
(prompt (strcat "cols: " (itoa cols)))
(if (= (rem row 2) 1)
(setq col (- cols 1 col))
)
(setq x (+ xStart (* col step) (* col extraColGap)))
(setq y (- yStart (* row step)))
(setq x1 (+ x 3.99))
(setq x2 (+ x 4.155))
(setq yLine (- y 3.446))
;; Debug: print each block being added
(prompt (strcat "Adding block " (itoa i) ": Row " (itoa row) " Col " (itoa col)))
(setq connectorData (append connectorData (list (list row col x1 x2 yLine))))
(setq i (1+ i))
)
(prompt (strcat "Total connectorData entries: " (itoa (length connectorData))))
;; === Draw horizontal cables ===
(drawZigzagCables connectorData targetPt centerOffset numBlocks)
;; Insert "CONDUCTOR" block at center point
(setq centerPt (list 40.1 1.1 0.0)) ; Adjust this if needed
(entmake
(list
(cons 0 "INSERT")
(cons 2 "CONDUCTOR") ; Block name
(cons 8 "0") ; Layer
(cons 10 centerPt) ; Insertion point
(cons 41 1.0) ; X scale
(cons 42 1.0) ; Y scale
(cons 43 1.0) ; Z scale
(cons 50 0.0) ; Rotation
)
)
(princ (strcat "\nPlaced " (itoa numBlocks) " UPS blocks with dynamic spacing."))
(princ)
)