;;; ============================================================ ;;; EXTRATOR_VAO_ANG.lsp — Jornada Telecom ;;; Exporta Postes, Vãos e Ângulos para CSV compatível com ;;; a Calculadora de Esforço em Postes. ;;; ;;; COMO USAR: ;;; 1. Salve o DWG antes de executar. ;;; 2. No AutoCAD, digite: APPLOAD → carregue este arquivo. ;;; 3. No prompt de comando, digite: TABEXTRACT ;;; 4. Siga as instruções na tela (2 seleções). ;;; ============================================================ (defun c:TABEXTRACT ( / sel sel_cor cnt ent vla-ent obj-type val ins-pt p1 p2 file path f blk-name num-poste list_cor cordoalha ss_check i cor-ent cor-vla cor-pts ep1 ep2 dx dy dist) (vl-load-com) ;; ── fix-dec: vírgula decimal PT-BR → ponto ─────────────────── ;; Necessário para que "35,60" não quebre o split(',') do servidor (defun fix-dec (s / r) (setq r "") (foreach c (vl-string->list s) (setq r (strcat r (if (= c 44) "." (chr c)))) ) r ) ;; ── dist2d: distância entre dois pontos ────────────────────── (defun dist2d (a b) (sqrt (+ (expt (- (car b) (car a)) 2) (expt (- (cadr b) (cadr a)) 2))) ) ;; ── 1. Seleção Geral (Postes + Cotas) ──────────────────────── (prompt "\n[1/2] Selecione a AREA DO PROJETO (postes e cotas): ") (setq sel (ssget '((0 . "INSERT,DIMENSION")))) (if (not sel) (progn (princ "\nNada selecionado. Operacao cancelada.") (exit)) ) ;; ── 2. Seleção de Cordoalhas ────────────────────────────────── (prompt "\n[2/2] Selecione as LINHAS/POLYLINES de CORDOALHA (Enter para pular): ") (setq sel_cor (ssget '((0 . "*POLYLINE,LINE")))) ;; Monta lista de entidades + pontos extremos de cada cordoalha ;; Formato: ( (ename ep-inicio ep-fim) ... ) (setq list_cor nil) (if sel_cor (progn (setq cnt 0) (while (< cnt (sslength sel_cor)) (setq cor-ent (ssname sel_cor cnt)) (setq cor-vla (vlax-ename->vla-object cor-ent)) ;; Coleta os dois endpoints da linha/polyline (setq cor-pts (vlax-safearray->list (vlax-variant-value (vla-get-Coordinates cor-vla)))) ;; Pega só os primeiros (x0 y0) e últimos (xN yN) pontos (setq ep1 (list (nth 0 cor-pts) (nth 1 cor-pts))) (setq ep2 (list (nth (- (length cor-pts) 2) cor-pts) (nth (- (length cor-pts) 1) cor-pts))) (setq list_cor (cons (list cor-ent ep1 ep2) list_cor)) (setq cnt (1+ cnt)) ) ) ) ;; ── Abre o CSV ─────────────────────────────────────────────── (setq path (getvar "DWGPREFIX")) (if (= path "") (setq path "C:\\")) (setq file (strcat path "Tabela_VAO_ANG.csv")) (setq f (open file "w")) (write-line "Objeto,Valor,Coord_X,Coord_Y,Coord_X2,Coord_Y2,Cordoalha" f) ;; ── Loop principal ──────────────────────────────────────────── (setq cnt 0) (while (< cnt (sslength sel)) (setq ent (ssname sel cnt)) (setq vla-ent (vlax-ename->vla-object ent)) (setq obj-type (vla-get-ObjectName vla-ent)) (cond ;; ── POSTES ─────────────────────────────────────────────── ((= obj-type "AcDbBlockReference") (setq blk-name (strcase (vla-get-EffectiveName vla-ent))) (if (vl-string-search "POSTE" blk-name) (progn (setq num-poste "S/N") (if (= (vla-get-HasAttributes vla-ent) :vlax-true) (setq num-poste (vla-get-TextString (car (vlax-invoke vla-ent 'GetAttributes)))) ) (setq ins-pt (vlax-safearray->list (vlax-variant-value (vla-get-InsertionPoint vla-ent)))) ;; Ignora postes sem numeração: sem atributo (S/N), ;; atributo vazio ("") ou só espaços (setq num-poste (vl-string-trim " " num-poste)) (if (and (not (= num-poste "S/N")) (not (= num-poste ""))) (write-line (strcat "POSTE," num-poste "," (fix-dec (rtos (car ins-pt) 2 2)) "," (fix-dec (rtos (cadr ins-pt) 2 2)) ",0,0,") f) ) ) ) ) ;; ── VÃOS ───────────────────────────────────────────────── ((or (= obj-type "AcDbAlignedDimension") (= obj-type "AcDbRotatedDimension")) (setq val (fix-dec (rtos (vla-get-Measurement vla-ent) 2 2))) (setq p1 (vlax-safearray->list (vlax-variant-value (vla-get-ExtLine1Point vla-ent)))) (setq p2 (vlax-safearray->list (vlax-variant-value (vla-get-ExtLine2Point vla-ent)))) (setq cordoalha "NAO") (if list_cor (progn ;; ── MÉTODO 1: Fence — cordoalha cruza a linha da cota ── (setq ss_check (ssget "_F" (list p1 p2) '((0 . "*POLYLINE,LINE")))) (if ss_check (progn (setq i 0) (while (< i (sslength ss_check)) (if (vl-some (function (lambda (c) (equal (ssname ss_check i) (car c)))) list_cor) (setq cordoalha "SIM") ) (setq i (1+ i)) ) ) ) ;; ── MÉTODO 2: Proximidade — endpoint da cordoalha ;; está perto de p1 ou p2 (cobre CEO encostada no poste) ;; Raio = 5% do vão ou mínimo 200 unidades CAD (if (= cordoalha "NAO") (progn (setq dist (dist2d p1 p2)) (setq raio (max 200 (* dist 0.05))) (foreach c list_cor (if (or (< (dist2d p1 (cadr c)) raio) (< (dist2d p1 (caddr c)) raio) (< (dist2d p2 (cadr c)) raio) (< (dist2d p2 (caddr c)) raio)) (setq cordoalha "SIM") ) ) ) ) ) ) (write-line (strcat "VAO," val "," (fix-dec (rtos (car p1) 2 2)) "," (fix-dec (rtos (cadr p1) 2 2)) "," (fix-dec (rtos (car p2) 2 2)) "," (fix-dec (rtos (cadr p2) 2 2)) "," cordoalha) f) ) ;; ── ÂNGULOS ────────────────────────────────────────────── ((or (= obj-type "AcDb2LineAngularDimension") (= obj-type "AcDb3PointAngularDimension")) (setq val (fix-dec (rtos (* (vla-get-Measurement vla-ent) (/ 180.0 pi)) 2 2))) (setq ins-pt (if (= obj-type "AcDb3PointAngularDimension") (vlax-safearray->list (vlax-variant-value (vla-get-CenterPoint vla-ent))) (vlax-safearray->list (vlax-variant-value (vla-get-TextPosition vla-ent))) ) ) (write-line (strcat "ANGULO," val "," (fix-dec (rtos (car ins-pt) 2 2)) "," (fix-dec (rtos (cadr ins-pt) 2 2)) ",0,0,") f) ) ) (setq cnt (1+ cnt)) ) (close f) (princ (strcat "\n>>> SUCESSO! Arquivo gerado em: " file " <<<")) (princ (strcat "\n Importe este CSV na Calculadora de Esforco em Postes.")) (princ) )