Sie sind auf Seite 1von 16

oCota, AutoArea

em 3/28/2012 Opa e a minha gente!! Bom, hoje vou postar uma rotina que eu fiz a muito tempo, quando trabalhava num escritrio de topografia em Curitiba. Bom a lisp faz o seguinte: voc seleciona algumas polilinhas e cjama o comando. Este ir mostrar algumas opes e ir cotar todos os segmentos dessa polilinha. T e da? voc pergunta. Imagine que voc tem um loteamento, subdiviso ou coisa assim e precisa cotar todos os segmentos das polilinhas. primeiro que voc deveria considerar usar o Parcels do Civil 3D... Mas se voc s tem o AutoCAD, pode usar a lisp!! Por exemplo, temos estas polilinhas:

A chamamos a lisp AUTOCOTA Selecionamos todas as polilinhas, e a tela se abre:

Voc marca as opes e clica OK. As opes como voc pode ver, so auto explicativas. A no ser a opo "Por Dentro", por dentro ou por fora da polilinha. S isso. A outra opo que pode causar confuso a "Com Azimute".

Quer dizer que ela pe azimute na cota? , coloca... hehehe, posio, topograph, desculpa a, hehehe a cereja do bolo vem na hora que "estrcharmos" as polilinhas, hehehe.

Bom, o resultado ser:

Agora, e se precisarmos adicionar a rea de cada polilinha? A chamamos o comando AUTOAREA. Ser pedido a seleo das polilinhas e em seguinda ser aberto a tela:

Tambm autoexplicativo. O item "Calcula rotao", se marcado, analiza a polilinha e alinha o texto criado no sentido maior da polilinha.

O resultado ser:

isso. E a lisp?, bom, esta: ;subrotina que implementa as aes do DCL ;key a key usada no item do dcl ;prog indica se o autocota ou autoarea ;algumas aes dos dois programas so identicas ;ento preferi simplificar (defun autoactions (key val prog) (setq f t) (cond ((= key "layer") (if (snvalid val) (setq layer val) (alert "Nome de layer Invlido!!") ) (set_tile "poplay" (if (setq tmp (vl-position (strcase val) (mapcar 'strcase lays) ) ) (itoa tmp) "0" ) ) ) ((= key "poplay") (set_tile "layer" (setq layer (nth (atoi val) lays))) ) ((= key "offset") (if (<= (atof val) 0) (alert "Offset Invlido") (setq offset val) ) ) ((= key "altura") (if (> (atof val) 0) (setq altura val) (alert "Altura Invlida") ) ) ((= key "az") (setq az val)) ((= key "dentro") (setq dentro val))

((= key "duplicidade") (setq duplicidade val)) ((= key "srot") (setq srot val)) ((= key "dimstyle") (setq dimstyle (nth (atoi val) dims))) ((= key "txtstyle") (setq txtstyle (nth (atoi val) stys))) ((= key "prefixo") (setq prefixo val)) ((= key "sufixo") (setq sufixo val)) ((= key "suf") (setq suf val)) ((= key "prf") (setq prf val)) ) (mode_tile "accept" (if (and (if prog (> (atof offset) 0) (> (atof altura) 0) ) (snvalid layer) ) 0 1 ) ) (mode_tile "prefixo" (if (= prf "1") 0 1 ) ) (mode_tile "sufixo" (if (= suf "1") 0 1 ) ) ) ;rotina principal do autocota (defun c:autocota (/ ss ent pts n cont vla p1 p2 p3 bul clock? activespace xdir vars offset r h d ang lst flag dim az layer dimstyle dims tmp dentro ) ;controle de erros (tbn:error-init (list (list "cmdecho" 0) t)) (if (setq ss (ssget '((0 . "LWPOLYLINE")))) (progn (setq dcl (load_dialog "D:\\PROGRAMAS\\LISP\\tbn2\\LISPS\\autocota.dcl" ) ;angulo do eixo X do UCS xdir (angle (trans '(0 0) 0 1) (trans '(1 0) 0 1)) ;lista dos layers disponiveis lays (vl-sort (get-tableof "layers") '(lambda (e1 e2) (< (strcase e1) (strcase e2))) ) ;lista dos dmension styles dims (get-tableof "dimstyles") ;lista auxiliar vars '("offset" "layer" "az" "dentro"

"dimstyle" "duplicidade") ;model ou paper: activespace (get-activespace) ) ;lembra as configuraes anteriores do DCL (mapcar '(lambda (k v / tmp) (set (read k) (if (setq tmp (getcfg (strcat "Appdata/autocota/" k))) (if (/= "" tmp) tmp v ) v ) ) ) vars ;valores padro caso no haja valores a lembrar (list "1.0" "TEX_COTAS" "0" "0" (car dims) "1") ) ;carrega o dcl do autocota (new_dialog "autocota" dcl) ;define as acoes de todos os controles do dcl (foreach x (cons "poplay" vars) (action_tile x "(autoactions $key $value t)") ) ;calcula o dimstyle inicial (if (not (setq tmp (vl-position (strcase dimstyle) (mapcar 'strcase dims)) ) ) (setq dimstyle (car dims) tmp 0 ) ) ;preenche o combobox dos layers (start_list "poplay" 3) (mapcar 'add_list lays) (end_list) ;preenche o combobox do dmension style (start_list "dimstyle" 3) (mapcar 'add_list dims) (end_list) ;preenche os outros controles do dcl (set_tile "az" az) (set_tile "offset" offset) (set_tile "dentro" dentro) (set_tile "duplicidade" duplicidade) (set_tile "dimstyle" (itoa tmp)) ;fora a desabilitar ou habilitar os botes ;em funo dos valores dos mesmos

; uma validao dos dados (autoactions "layer" (set_tile "layer" layer) t) ;inicia o dialogo (if (= 1 (start_dialog)) (progn ;prepara as variaveis para desenhar (setq offs (* (if (= "1" dentro) -1 1 ) (atof offset) ) ) ;repita em todas as polilinhas selecionadas (repeat (if ss (sslength ss) 0 ) ;pega a polilinha ;verifica se esta em sentido horrio ;verifica o numero de vertices (dxf 90) (setq ent (ssname ss 0) vla (vlax-ename->vla-object ent) clock? (isclockwise (get-points-polig ent)) n 0 qtd (dxf 90 ent) ) ;para todos os segmentos da plilinha (repeat (if (= :vlax-true (vla-get-closed vla)) qtd (1- qtd) ) ;calcula o ponto inicial e final ;e se tem arco no segmento (setq p1 (append (3d-of-vla (vla-get-coordinate vla n)) '(0.0) ) bul (vla-getbulge vla n) n (1+ n) p2 (append (3d-of-vla (vla-get-coordinate vla (if (= n qtd) 0 n ) ) ) '(0.0) ) p3 (media p1 p2) ang (+ (/ pi 2) (angle p1 p2)) flag t ) ;verifica se o segmento j foi cotado ;se esta for uma opo escolhida (if (= "1" duplicidade) (foreach l lst (if (or (and (not (ponto-dif? p1 (car l)))

(not (ponto-dif? p2 (cadr l))) ) (and (not (ponto-dif? p1 (cadr l))) (not (ponto-dif? p2 (car l))) ) ) (setq flag nil) ) ) ) ;caso o inicio e o fim do segmento sejam diferentes ;ou seja, o segmento tem comprimento>0 ;e ainda, j no foi cotado (if (and (ponto-dif? p1 p2) flag) (progn ;cria a dimension apropriada (setq lst (cons (list p1 p2) lst) dim (if (zerop bul) ;dimension aligned (vla-AddDimAligned activespace (vlax-3d-point p1) (vlax-3d-point p2) (vlax-3d-point (polar p3 ang (* (if clock? 1 -1 ) offs ) ) ) ) ;dimension em arco (progn (Setq d (distance p1 p2) h (* bul d 0.5) r (/ (+ (expt h 2) (/ (expt d 2) 4)) (* bul d) ) ) (vla-addDimArc activespace (vlax-3d-point (polar p3 ang (- r h))) ;centro (vlax-3d-point p1) (vlax-3d-point p2) (vlax-3d-point (polar p3 ang (- (* (if clock? 1 -1 ) offs ) h

) ) ) ) ) ) ) ;sobreescreve alguns dxf: ;1 o texto escrito ;3 o estilo ;8 o layer ;51 o ngulo do X do UCS, ;ele evita que o texto fique de cabea pra baixo (remake-ent dim '(1 3 8 51) (list (if (= az "1") (strcat "<> - " (format-ang2 (angle p1 p2) nil "Azimute" 4) ) "<>" ) dimstyle layer xdir ) ) ;implmenta o componente de azimute se esta for ;requerido. O xdata serve para o reactor que o ;corrige ao strechar a domension (if (= az "1") (put-xdata2 dim '((1000 . "N") (1000 . "A") (1000 . "M") (1000 . "<> - []") ) "AUTOCOTA" ) ) ;implementa o reactor que corrige o azimute (if (= az "1") (vlr-object-reactor (list dim) "" '((:vlr-modified . autocota:update)) ) ) ) ) ) ;vai pra prxima polilinha (ssdel ent ss) ) ;salva as opes do dcl para lembrar depois (foreach k vars (setcfg (strcat "Appdata/autocota/" k) (eval (read k)))

) ) ) (unload_dialog dcl) ) ) ;restaura o controle de erros (tbn:error-restore) ) ;reactor que corrige os azimutes ;ele agenda a correo do azimute quando ;a edio do usurio termina. (defun autocota:update (vla rea par) (if (not (vlax-erased-p vla)) (vlr-editor-reactor (list vla rea) '((:vlr-commandEnded . autocota:doupdate)) ) ) ) ;quando a edio (move, stretch...) termina ;atualiza o azimute (defun autocota:doupdate (rea com / oldr ent) (setq tmp (vlr-data rea) ent (car tmp) oldr (cadr tmp) ) ;desabilita os reactors temporariamente (vlr-remove rea) ;ajusta o azimute e restaura o reactor (autocota:formatadata ent (list oldr) (get-xdata2 ent "AUTOCOTA") ) ) ;rotina que procede o ajuste do azimute (defun autocota:formatadata (vla oldr xd / aa) ;tira qualquer reactor da dimension ;para que a edio no os dispare (foreach aa oldr (vlr-owner-remove aa vla)) ;edita (vla-put-TextOverride vla (vl-string-subst (format-ang2 (angle (dxf 13 ent) (dxf 14 ent)) (= "S" (car xd)) ;COM ESPAOS (cadr xd) ;AZIMUTE/RUMO (caddr xd) ;PRECISAO ) "[]" (if (cadddr xd) (cadddr xd) "<> - []" ) )

) ;salva as xdata (put-xdata2 vla (mapcar '(lambda (x) (cons 1000 x)) xd) "AUTOCOTA" ) ;reestabelece os reactors ;sem isso, d pau, hehehe (foreach aa oldr (vlr-owner-add aa vla)) ) ;rotina que atva os reactors do desenho quando ;este aberto pela primeira vez (defun autocota:ativatodososreactors (/ tmp ss ent) ;antes de adicionar um reactor, verificar se ;ele j existe, se existir, apague (mapcar '(lambda (r / tmp) (setq tmp (mapcar 'cdr (vlr-reactions r))) (if (or (member 'autocota:doupdate tmp) (member 'autocota:update tmp) ) (vlr-remove r) ) ) (apply 'append (mapcar 'cdr (vlr-reactors))) ) ;em todas as dimensions gerenciadas pelo autocota (setq ss (ssget "X" '((0 . "DIMENSION") (-3 ("AUTOCOTA"))))) (repeat (if ss (sslength ss) 0 ) (setq ent (ssname ss 0)) ;crie o reactor de atualizao do azimute (vlr-object-reactor (list (vlax-ename->vla-object ent)) "" '((:vlr-modified . autocota:update)) ) (ssdel ent ss) ) (princ) ) ;rotina que cria um texto com a rea das polilinhas selecionadas ;caso a polilinha seja alterada, ela atualiza a rea escrita no texto (defun c:autoarea (/ ss ent area reg altura rot d n tmp r layer txtstyle stys cg vars prefixo sufixo prf suf txt p f srot ) ;controle de erros inicializado (tbn:error-init (list (list "cmdecho" 0) t)) ;nas polilinhas selecionadas (if (setq ss (ssget '((0 . "LWPOLYLINE"))))

(progn ;carrege as variaveis iniciais (setq dcl (load_dialog "f:/tbn/lisps/autocota.dcl") ;lista dos layers do desenho lays (vl-sort (get-tableof "layers") '(lambda (e1 e2) (< (strcase e1) (strcase e2))) ) ;lista dos estilos de texto stys (get-tableof "textstyles") ;lista dos controles do dcl vars '("poplay" "txtstyle" "layer" "altura" "prefixo" "sufixo" "prf" "suf" "srot" ) rot (/ pi 180) ) ;lembra as escolhas antereiores do dcl (mapcar '(lambda (k v / tmp) (set (read k) (if (setq tmp (getcfg (strcat "Appdata/autoarea/" k))) (if (/= "" tmp) tmp v ) v ) ) ) (cdr vars) ;se no h o que lembrar, use os padres (list (car stys) "TEX_AREAS" "1.5" "rea=" "m" "1" "1" "1") ) ;inicializa o dcl (new_dialog "autoarea" dcl) ;define as aes de cada controle do dcl (foreach x vars (action_tile x "(autoactions $key $value nil)") ) ;popula o combobox dos layers (start_list "poplay" 3) (mapcar 'add_list lays) (end_list) ;popula o combobox dos estilos de texto (start_list "txtstyle" 3) (mapcar 'add_list stys) (end_list) ;preenche os demais campos (foreach x (cddr vars) (set_tile x (eval (read x)))) (set_tile "txtstyle" (itoa (if (setq tmp (vl-position (strcase txtstyle)

(mapcar 'strcase stys) ) ) tmp 0 ) ) ) ;fora a habilitar ou desabilitar campos em funo ;das escolhas atuais (autoactions "layer" (set_tile "layer" layer) nil) ;mostra o dcl (if (= 1 (start_dialog)) (progn ;se clicou ok, proceda em todas as polilinhas (repeat (sslength ss) (setq ent (ssname ss 0) area (vlax-curve-getarea ent) n 0 d 1e30 ;calcula uma region temporria, ;para obter o centroide da polilinha reg (regionme ent) ) ;se conseguir criar a region temporria (if reg (progn ;calcula o centroide da mesma. ;nele ser escrito o texto com a rea (setq cg (append (3d-of-vla (vla-get-centroid reg)) '(0.0)) ) ;se a polilinha mais comprida que larga, ;alinha o texto no sentido mais extenso da mesma ;se esta for uma opo marcada (if (= "1" srot) (repeat 181 (vla-rotate reg (vlax-3d-point cg) rot) (Setq box (get-bounding-box reg) tmp (- (caadr box) (caar box)) n (1+ n) ) (if (< tmp d) (Setq d tmp rn ) ) ) ) ;apaga a region temporria (vla-delete reg) ;calcula os componentes do texto (setq p (if (= prf "1") prefixo

"" ) f (if (= suf "1") sufixo ""

) ;desenha o texto na tela txt (draw-text (strcat p (fnum area 2) f) cg layer (rot-of-ucs (if (= "1" srot) (+ (/ pi 2) (* -1 r rot)) 0 ) ) (atof altura) txtstyle "mc" ) ) ;cria o xdata que serve de informao ao reactor (put-xdata2 ent (list (cons 1005 txt)) "AUTOAREA") ;cria o xdata que serve de informao ao reactor ;essa informao vincula o txt a polilinha (put-xdata2 txt (list (cons 1000 p) (cons 1000 f)) "AUTOAREA_PF" ) ;inicializa o reactor (autoarea:cria_reactor ent) ) ) ;proxima polilinha (ssdel ent ss) ) ;slava as opes do dcl para lembrar depois (foreach k (cdr vars) (setcfg (strcat "Appdata/autoarea/" k) (eval (read k))) ) ) ) ;descarrega o dcl (unload_dialog dcl) ) ) ;restaura o controle de erros (tbn:error-restore) ) ;subrotina que cria o reactor de atualizao da rea (defun autoarea:cria_reactor (ent) (vlr-object-reactor (list (vlax-ename->vla-object ent))

nil '((:vlr-modified . autoarea:update)) ) ) ;subrotina que ativa a atualizao das reas ;quando o desenho aberto (defun aautoarea:ativa_reactor (/ ss ent) ;se j existir um reactor vinculado ao txt, desabilite antes (mapcar '(lambda (r) (if (member 'autoarea:update (mapcar 'cdr (vlr-reactions r))) (vlr-remove r) ) ) (apply 'append (mapcar 'cdr (vlr-reactors))) ) ;cria o reactor em todas as polilinhas gerenciadas pelo autoarea (repeat (if (setq ss (ssget "X" '((0 . "LWPOLYLINE") (-3 ("AUTOAREA"))))) (sslength ss) 0 ) (setq ent (ssname ss 0)) (autoarea:cria_reactor ent) (ssdel ent ss) ) ) ;subrotina que atualiza o text (defun autoarea:update (ent rea par / area xd txt) (if (not (wcmatch (getvar "cmdnames") "*SAVE*")) (if (not (vlax-erased-p ent)) (setq txt (car (get-xdata2 ent "AUTOAREA")) area (vlax-curve-getarea ent) xd (get-xdata2 txt "AUTOAREA_PF") txt (if xd (remake-ent txt 1 (strcat (car xd) (fnum area 2) (cadr xd)) ) ) ) ) ) ) ;rotina que formata as cotas do autocota com quebras de linha ;ou sem quebras (defun c:arrumacota (/ ent xd lst str oldr reas X vla) (tbn:error-init (list (list "cmdecho" 0) t)) ;lista das possiveis formataes (Setq lst '("<> - []" "<>\\P[]" "[]\\P<>" "[]" "<>") reas (cdar (vlr-reactors :VLR-Object-Reactor)) ) ;procede o comando enquanto o usurio no interromper (while (progn

(prompt "\nSelecione a cota:") (setq ent (ssget ":S" '((-3 ("AUTOCOTA"))))) ) ;pega a cota selecionada ;substitui pela nova formatao (setq ent (ssname ent 0) vla (vlax-ename->vla-object ent) xd (get-xdata2 ent "AUTOCOTA") str (vl-position (if (cadddr xd) (cadddr xd) "<> - []" ) lst ) oldr nil str (nth (if (= 4 str) 0 (1+ str) ) lst ) ) ;desliga o reactor que tem sobre a cota (foreach x reas (if (member vla (vlr-owners x)) (setq oldr (cons x oldr)) ) ) ;atualiza a cota e religa o reactor (autocota:formatadata vla oldr (append (sub-list xd 0 2) (list str)) ) ) ;restaura o controle de erros (tbn:error-restore) )

;liga todos os reactor quando a rotina carregada ;ou quando o desenho aberto pela primeira vez (aautoarea:ativa_reactor) (autocota:ativatodososreactors)

Link(s) da(s) subrotina(s) usada(s): tbn:error-init, get-tableof, get-activespace, isclockwise, get-points-polig, dxf, 3d-of-vla, media, pontodif?, remake-ent, format-ang2, put-xdata2, tbn:error-restore, get-xdata2, cg, regionme, get-boundingbox, draw-text, fnum, rot-of-ucs, sub-list Para complementar, faltou o DCL, abaixo

autocota : dialog {label = "AutoCota"; :boxed_column {label ="Cota"; :popup_list{key = "dimstyle";} :row { :toggle {label = "Com Azimute"; key = "az";} :toggle {label = "Remove Duplicidade"; key = "duplicidade";}} } :boxed_column{ label = "Offset"; :edit_box {key = "offset";} :toggle {label = "Por Dentro"; key = "dentro";}} :boxed_column{label = "Layer"; :popup_list{ key = "poplay";} :edit_box {key="layer";}} :row{ :text {label="Powered by Neyton";} ok_cancel;}} autoarea : dialog {label = "Autorea"; :boxed_column{ label = "Texto:"; :popup_list {key = "txtstyle";} :row { :toggle {key="srot";label="Calcula rotao";} :edit_box { label = "Altura"; key = "altura";}}} :boxed_column {label = "Incluir..."; : row { :toggle {label = "Prefixo"; key = "prf";} :edit_box { key = "prefixo"; width = 40;}} : row { :toggle {label = "Sufixo "; key = "suf";} :edit_box { key = "sufixo"; width = 40;}} } :boxed_column{label = "Layer"; :popup_list{ key = "poplay";} :edit_box {key="layer";}} :row{ :text {label="Powered by Neyton";} ok_cancel;} }

Das könnte Ihnen auch gefallen