SOLIDOS API – Visual Lisp – Dividir Bacias

Vamos brincar um pouco com a API do SOLIDOS hoje: Dividir uma bacia lançada em duas.

Um comando que já deveria existir nativamente, não?

Imagina a situação: Você lançou a valeta de proteção e ela acabou ficando extensa e teve de dividir ela em duas, para aumentar a seção do trecho de jusante:

Se a bacia de contribuição atingia toda a extensão, então agora metade da bacia atinge o primeiro trecho e a outra metade, o segundo. Para dividir a valeta, usamos o comando SSPLIT:

Aí vem a parte complicada, dividir a bacia.

Normalmente você removeria parte dos vértices da bacia, faria outra e pronto. Mas isso pode ser bem demorado se tiver muitos vértices.

Pensando nisso, vamos analisar o código abaixo:

|--lsp--|
;--------------------------------------------------------------------------------------; ; SSPLITCATCHMENTORSECTOR ; ; ; ; divide uma bacia ou setor em 2 ; ;--------------------------------------------------------------------------------------; (defun c:SSPLITCATCHMENTORSECTOR (/ poligono vertices p1 p2 n1 n2 lista1 lista2 n grupo tipo bacia2 label) ;carrega as funções VL (vlax...) (vl-load-com) ;inicia a prevencao de erros ;para funcionar, carrege "lisps_dlls.fas" (if tbn:error-init (tbn:error-init nil)) ;seleciona a bacia ou setor (setq poligono (car (entsel "\nSelecione uma bacia de contribuição ou setor de consumo"))) (IF (not poligono) (exit)) ;testa se realmente é bacia ou setor (setq tipo (vl-string-subst "" "Sol" (SolidosGetNodeParam poligono "Type"))) (if (and (/= tipo "LongCatchment") (/= tipo "PointCatchment") (/= tipo "Sector")) (progn (alert "não é uma bacia ou setor!") (exit))) ;obtem a lista de vertices (setq vertices (SolidosGetNodeParam poligono "Vertices")) (IF (not vertices) (exit)) ;pede os pontos de corte (setq p1 (getpoint "\nClique um ponto próximo ao contorno da poligono")) (IF (not p1) (exit)) (setq p2 (getpoint "\nClique outro ponto próximo ao contorno da poligono" p1)) (IF (not p2) (exit)) ;calcula os indices das arestas inicial e final (setq n1 (calc-vertice-mais-proximo vertices p1) p1 (cadr n1) n1 (car n1) n2 (calc-vertice-mais-proximo vertices p2) p2 (cadr n2) n2 (car n2)) ;verifica se da pra cortar o poligono (if (= n1 n2) (progn (alert "os pontos clicados nao servem, pois n1=n2") (exit))) ;separa en 2 listas de pontos (setq lista1 (list p1) qtd (length vertices) n n1) ;p1, n1+1, n1+2, ... n1+x (While (/= n n2) (setq n (rem (1+ n) qtd) lista1 (append lista1 (list (nth n vertices)))) ) ;p1, n1+1, n1+2, ... n1+x, p2 (setq lista1 (append lista1 (list p2))) (setq lista2 (list p2)) ;p2, n2+1, n2+2, ... n2+x (While (/= n n1) (setq n (rem (1+ n) qtd) lista2 (append lista2 (list (nth n vertices)))) ) ;p2, n2+1, n2+2, ... n2+x, p1 (setq lista2 (append lista2 (list p1))) ;grupo onde a bacia ou setor está (setq grupo (SolidosGetNodeParam poligono "Pai")) ;redefine a lista de verices do poigono selecionado (SolidosSetNodeParams poligono (List "Vertices" lista1)) ;cria um novo poligono com a segunda lista de pontos (setq bacia2 (SolidosCreateNode grupo tipo (list "Vertices" lista2 "Style" (SolidosGetNodeParam poligono "Style") "Layer" (SolidosGetNodeParam poligono "Layer") "C" (SolidosGetNodeParam poligono "C") "Tc" (SolidosGetNodeParam poligono "Tc") ))) ;se é bacia pontual, tem a equação do tc (if (= tipo "PointCatchment") (SolidosSetNodeParams bacia2 (list "TcEq" (SolidosGetNodeParam poligono "TcEq")))) ;se o poligono tinha label, adicione uma no novo (if (setq label (SolidosGetChildNames poligono)) (progn (setq label (SolidosFindObjectByName poligono (car label)) tipo (vl-string-subst "" "Sol" (SolidosGetNodeParam label "Type"))) (SolidosCreateNode bacia2 tipo (list "Style" (SolidosGetNodeParam label "Style") "Layer" (SolidosGetNodeParam poligono "Layer") ) ) ) ) ;restaura o controle de erros (if tbn:error-restore (tbn:error-restore)) (princ) ) (defun calc-vertice-mais-proximo (vertices pt / n qtd v1 v2 linha ptProx dist d escolha tmp) ;inicializa parametros (setq n 0 qtd (length vertices) dist 1e100) ;para todas as arestas, calcule (repeat qtd (setq tmp n v1 (nth n vertices) ;enesimo vertice n (rem (1+ n) qtd) ;incrementa para n = (n+1) mod qtd v2 (nth n vertices) ;enesimo vertice linha (entmakex (list '(0 . "LINE") (cons 10 v1) (cons 11 v2))) ;linha temporaria ptProx (vlax-curve-getclosestpointto linha pt) ;ponto sobre a aresta d (distance pt ptprox) ;distancia do ponto clicado at a projeção na aresta ) ;se a distancia calculada é menor (if (< d dist) (setq dist d escolha (list tmp ptProx))) ;apaga a linha temporaria (entdel linha) ) ;retorna uma lista com o indice da aresta e o ponto sobre a aresta escolha ) (prompt "\nSSPLITCATCHMENTORSECTOR carregado") (princ)

Salva a lisp acima e carrega com o comando APPLOAD do AutoCAD.

Rode o comando SSPLITCATCHMENTORSECTOR:

E o resultado:

Pronto, agora é só conectar a bacia ao novo dispositivo, usando o comando SCONNECT

Bem fácil, não?

Comentei o código para melhor compreensão. As funções da API do SOLIDOS usadas foram:

  • SolidosGetNodeParam - obtém o valor de uma propriedade. Sintaxe: (SolidosGetNodeParam entId "PropertyName")
  • SolidosSetNodeParams - atribui valores às propriedades de um objeto do SOLIDOS. SIntaxe: (SolidosSetNodeParams entId (List "Prop1" Valor1 "PropN" ValorN))
  • SolidosGetChildNames - obtém os nomes dos nós filhos de um objeto do SOLIDOS. Sintaxe: (SolidosGetChildNames entId)
  • SolidosFindObjectByName - procura o 'entId' de um item do SOLIDOS, Sintaxe: (SolidosFindObjectByName entIdPai "nome do item")
  • SolidosCreateNode - cria um novo item do SOLIDOS. Sintaxe: (SolidosCreateNode parentId "tipo" (list "prop1" valor1 "propn" valorn))

Deixe um comentário

Rolar para cima