(defun clearDrawing ( / ss) ;; Select all non-locked, visible entities and delete them (setq ss (ssget "_X" '((0 . "*")))) ; select all (if ss (progn (command "_.erase" ss "") (princ "\nDrawing cleared.") ) ) ) (defun placeDeviceLabel (vlaBlock / insPt labelText labelPt ent) (setq insPt (vlax-get vlaBlock 'InsertionPoint)) (setq labelPt (list (+ (car insPt) 3.6) (+ (cadr insPt) 1.2) (caddr insPt))) (setq labelText (cond ((wcmatch (strcase (vla-get-effectivename vlaBlock)) "*POWERFLEX*") "APF") ((wcmatch (strcase (vla-get-effectivename vlaBlock)) "*SIO*") "SIO") ((wcmatch (strcase (vla-get-effectivename vlaBlock)) "*FIOM*") "FIO") ((wcmatch (strcase (vla-get-effectivename vlaBlock)) "*FIOH*") "FIOH") (T "") ) ) (if (/= labelText "") (progn ;; Create text entity with alignment point for justification (setq ent (entmakex (list (cons 0 "TEXT") (cons 8 "0") (cons 7 "WD") (cons 62 7) ;; white color (cons 10 labelPt) ;; insertion point (cons 11 labelPt) ;; alignment point (required for vertical just >0) (cons 40 0.5) (cons 72 0) ;; Horizontal Left (cons 73 3) ;; Vertical Top (cons 1 labelText) (cons 50 0.0) ;; rotation angle ) )) ) ) ) (defun insertBlockAt (blockName basePt targetPt) (command "_.-INSERT" blockName basePt 1 1 0) (setq ent (entlast)) (vla-move (vlax-ename->vla-object ent) (vlax-3d-point basePt) (vlax-3d-point targetPt)) ent ) (defun labelBlockLines (block startNum) (foreach att (vlax-invoke block 'GetAttributes) (setq tag (strcase (vla-get-tagstring att))) (if (wcmatch tag "LINE*") (progn (setq idx (atoi (substr tag 5))) (setq labelNum (+ startNum (- idx 1))) (setq labelStr (if (< labelNum 10) (strcat "0" (itoa labelNum)) (itoa labelNum))) ;; Use the block's X position + 0.5, and Y from the attribute (setq basePt (vlax-get att 'InsertionPoint)) (setq blockPos (vlax-get block 'InsertionPoint)) ; block base point ;; X from block + 0.5, Y from attribute - 0.05 (setq labelPt (list (+ (car blockPos) 0.12) (- (cadr basePt) 0.053) (caddr basePt))) (entmake (list (cons 0 "TEXT") (cons 8 "0") (cons 7 "WD") (cons 62 7) (cons 10 labelPt) (cons 11 labelPt) (cons 40 0.13) (cons 72 1) (cons 73 1) (cons 1 labelStr) (cons 50 0.0) (cons 100 "AcDbEntity") (cons 100 "AcDbText") (cons 100 "AcDbText") ) ) ) ) ) ) (defun setDESCAtoSpare (block) (foreach att (vlax-invoke block 'GetAttributes) (setq tag (strcase (vla-get-tagstring att))) (if (wcmatch tag "DESCA*") (vla-put-textstring att "SPARE") ) ) ) ;; Function to read device list from a text file (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")) (while (setq line (read-line file)) (setq result (append result (list (strcase (vl-string-trim " \t\r\n" line))))) ) (close file) result ) nil ) ) ;; Function to chunk a list into sublists of specified size (defun chunk-list (lst size / result chunk) (while lst (setq chunk (vl-remove-if 'null (list (nth 0 lst) (nth 1 lst) (nth 2 lst) (nth 3 lst)))) (setq result (append result (list chunk))) (setq lst (cddddr lst)) ) result ) ;; Function to read device list from file and return as a list (defun placeDevicesInLayout (layoutStartX devices / basePt positions i device blk pos ent vlaEnt) (setq basePt "0,0,0") ;; TODO: these cordinates are for the new SIO BLOCK coming from the amazon ;; They are not used in the current layout, but can be used for future reference. ; (setq positions (list ; (list 3.57 5.06 0.0) ;; A ; (list 3.57 -5.95 0.0) ;; B ; (list 22.84 5.06 0.0) ;; C ; (list 22.84 -5.95 0.0) ;; D ; )) ;; Ordered list of positions: always A, B, C, D (setq positions (list (list 9.63 9.5 0.0) ;; A (list 9.63 -1.5 0.0) ;; B (list 28.88 9.5 0.0) ;; C (list 28.88 -1.5 0.0) ;; D )) ;; Alternate layout for FIO/FIOH (setq positionsB (list (list 9.6 9.5 0.0) ;; A (list 9.6 -1.5 0.0) ;; B (list 28.9666 9.5 0.0) ;; C (list 28.9666 -1.5 0.0) ;; D )) (setq i 0) (while (< i (length devices)) (setq device (nth i devices)) (setq blk (cond ((vl-string-search "APF" device) "PLCIO_ARMORPOWERFLEX") ((vl-string-search "SIO" device) "PLCIO_ARMORBLOCK_SIO") ((vl-string-search "FIOH" device) "PLCIO_ARMORBLOCK_FIOH") ((vl-string-search "FIO" device) "PLCIO_ARMBLOCK_FIOM") (T nil) ) ) (if blk (progn ;; Pick the correct layout based on device type and position index (if (< i (length positions)) ; avoid overflow (setq pos (cond ((or (vl-string-search "FIOH" device) (vl-string-search "FIO" device)) (mapcar '+ (nth i positionsB) (list layoutStartX 0 0)) ) (T (mapcar '+ (nth i positions) (list layoutStartX 0 0)) ) ) ) (setq pos (list layoutStartX 0 0)) ; fallback if too many devices ) ;; Insert and move (command "_.-INSERT" blk basePt 1 1 0) (setq ent (entlast)) (if ent (progn (setq vlaEnt (vlax-ename->vla-object ent)) (vla-move vlaEnt (vlax-3d-point 0 0 0) (vlax-3d-point pos)) (setDESCAtoSpare vlaEnt) ; (placeDeviceLabel vlaEnt) ) (princ (strcat "\nFailed to insert block: " blk)) ) ) ) (setq i (1+ i)) ) ) (defun update20ZoneBlockAttributes (blockEnt layoutIndex startValue / blockObj attrList attr attrName newValue formattedValue) (setq blockObj (vlax-ename->vla-object blockEnt)) (setq attrList (vlax-invoke blockObj 'GetAttributes)) (foreach attr attrList (setq attrName (vlax-get-property attr 'TagString)) (if (and (>= (strlen attrName) 5) (= (substr attrName 1 4) "LINE") (>= (atoi (substr attrName 5)) 1) (<= (atoi (substr attrName 5)) 20)) (progn ;; Convert string to number, add index (setq newValue (+ (atoi startValue) layoutIndex)) ;; Format as string with period, no leading zeros (setq formattedValue (strcat (itoa newValue) ".")) ;; Apply value (vlax-put-property attr 'TextString formattedValue) (vlax-invoke attr 'Update) ) ) ) (vlax-invoke blockObj 'Update) ) (defun c:init_layout_base ( / layoutData groupedData layoutCount offsetX i currentOffset basePt ptLeft ptRight leftEnt rightEnt leftBlock rightBlock labelPt) ;; Read layout from file (setq layoutData (readDeviceListFromFile)) ; (setq groupedData (chunk-list layoutData 4)) (setq layoutCount (length groupedData)) ;; Clear drawing and setup (clearDrawing) (setq oldAttReq (getvar "ATTREQ")) (setvar "ATTREQ" 0) (setq offsetX 38.5) ;; prompt user for starting indexes (setq startIndex (getstring "\nEnter starting line index (e.g. 01600): ")) ;; Layout loop (setq i 0) (while (< i layoutCount) (setq currentOffset (* i offsetX)) ;; Draw outer box (command "_.PLINE" (list (+ 0 currentOffset) -11.0)) (command (list (+ 38.5 currentOffset) -11.0)) (command (list (+ 38.5 currentOffset) 11.0)) (command (list (+ 0 currentOffset) 11.0)) (command "C") ;; Side and center lines (command "_.PLINE" (list (+ 0 currentOffset) -11.0) (list (+ 0 currentOffset) 11.0) "") (command "_.PLINE" (list (+ 38.5 currentOffset) -11.0) (list (+ 38.5 currentOffset) 11.0) "") (command "_.PLINE" (list (+ 19.25 currentOffset) -11.0) (list (+ 19.25 currentOffset) 11.0) "") ;; Insert 20_zone blocks (setq basePt '(0 0 0)) (setq ptLeft (list (+ 0.75 currentOffset) 9.5 0)) (setq ptRight (list (+ 20.0 currentOffset) 9.5 0)) ;;todo fix the naming (setq leftEnt (insertBlockAt "20_zone" basePt ptLeft)) (setq leftBlock (vlax-ename->vla-object leftEnt)) (update20ZoneBlockAttributes leftEnt i startIndex) (labelBlockLines leftBlock 1) (setq rightEnt (insertBlockAt "20_zone" basePt ptRight)) (setq rightBlock (vlax-ename->vla-object rightEnt)) (update20ZoneBlockAttributes rightEnt i startIndex) (labelBlockLines rightBlock 21) ;; Add layout label (setq labelPt (list (+ currentOffset 14.0) 16.0 0.0)) (command "_.text" labelPt 1.5 0 (strcat "Layout " (itoa (1+ i)))) ;; Insert actual devices from group (placeDevicesInLayout currentOffset (nth i groupedData)) (setq i (1+ i)) ) ;; Reset (command "_.color" "BYLAYER") (setvar "ATTREQ" oldAttReq) (princ (strcat "\n" (itoa layoutCount) " layouts created from file.")) (princ) )