Bom dia pe-pessoal!!
Me pediram pra tirar umas seções de uns levantamentos feitos e desenhados no Civil 3D. Até aí tubo bem.
O problema é que, quem desenhou isso no Civil 3D, não foi lá muito caprichoso (nem garantido) e cometeu alguns deslizes ao conectar as 3DPOLY, que depois viriam a ser BREAKLINES do MDT do projeto, e coisas assim aconteceram:
Percebem? Tem pontos da superfície que ficaram com Z=0, depois que as breaklines foram adicionadas.
Obviamente, as seções gabaritadas ficaram um tanto.... erradas:
Esse tipo de erro é bem fácil de cometer, basta um pequeno deslize e o OSNAP não captura o ponto em 3D corretamente e pronto....
Obviamente, ao adicionar as BREAKLINES, o camarada viu essa tela famigerada pipocar na cara dele:
E ele escolheuesperar ignorar...
Bom, o caso é que eu peguei a coisa toda pronta, ou seja, já estava assim quando eu cheguei, hehehe
E agora? Arrumar uma por uma? hummm.... vai lá estagiário....
Vamos programar algo então....
Primeiro, como seria a receita do bolo?
1) selecionar as polilinhas
2) olhar em cada um dos seus vértices e
3) se estiver errado, acha um ponto e
4) se achar o ponto, corrige o vértice
Nossa, assim até parece fácil programar....
Olha como fica um programa em Visual Lisp:
;plugin para corrigir o Z de 3dpoly que deveria passar por cogopoints
;para lembrar a última opção
(setq arruma3dpoly:tolerancia 0.01)
(defun c:arruma3dpoly (/ acadApp aecVer c3dApp c3dDoc points cgs cg nx
ss ent vla pts x y z nv nc)
;inicializa o controle de erros
(tbn:error-init nil)
;pede a seleção das polilinhas
(prompt "\nSelecione as 3DPOLY")
(setq ss (ssget '((0 . "polyline") (100 . "AcDb3dPolyline"))))
;nada selecionado, sai
(if (not ss) (exit))
;pergunta pela tolerância na linha de comando
(setq tmp (getdist
(strcat
"\nInforme a tolerância <"
(rtos arruma3dpoly:tolerancia 2 5)
">")))
(if tmp (setq arruma3dpoly:tolerancia tmp))
;carrega as funções vl....
(vl-load-com)
(setq
;acessa o AutoCAD
acadApp (vlax-get-acad-object)
;calcula a versão do Civil 3D
aecVer (substr (vla-get-version acadapp) 1 4)
aecVer (vl-position aecVer
'("17.0" ;2007
"17.1" ;2008
"17.2" ;2009
"18.0" ;2010
"18.1" ;2011
"18.2" ;2012
"19.0" ;2013
"19.1" ;2014
"20.0" ;2015
"20.1" ;2016
"21.0" ;2017
"22.0" ;2018
"23.0" ;2019
))
aecVer (nth aecVer '("4.0" "5.0" "6.0" "7.0"
"8.0" "9.0" "10.0" "10.3"
"10.4" "10.5" "11.0" "12.0"
"13.0"))
;acessa a versão atual do Civil 3D
c3dApp (vla-GetInterfaceObject acadApp
(strcat "AeccXUiLand.AeccApplication."
aecVer))
;acessa o documento atual do civil 3d
c3dDoc (vla-get-activedocument c3dApp)
;pega sua lista de pontos
points (vlax-get-property c3dDoc "Points")
;inicializa a lista de coordenadas
cgs nil
;inicializa a tolerância
tolerancia 0.01)
;converte os cogopoints em lista de coordenadas
(vlax-for cg points
(setq cg (list (vlax-get-property cg "easting")
(vlax-get-property cg "northing")
(vlax-get-property cg "elevation"))
cgs (cons cg cgs)))
;em todas as polilinhas, faça
(repeat (sslength ss)
(setq
;pega a primeira polilinha da seleção
ent (ssname ss 0)
vla (vlax-ename->vla-object ent)
;obtém a lista de coordenadas da polilinha
;no format (x0 y0 z0 x1 y1 z1 ... xn yn zn)
pts (vlax-safearray->list
(vlax-variant-value
(vla-get-coordinates vla)))
;inicializa o contador de vértice
nv 0)
;para todos os vértices faça
(repeat (/ (length pts) 3)
(setq
;obtem X, Y e Z do vértice
nx (* nv 3)
x (nth nx pts)
y (nth (+ 1 nx) pts)
z (nth (+ 2 nx) pts)
;inicializa o contador de cogopoint
nc 0)
;se Z do vértice é igual (ou quase) a zero
(if (equal 0.0 z arruma3dpoly:tolerancia)
;busca o cogopoint mais próximo
(while (< nc (length cgs))
;pega o cogopoint NC
(setq cg (nth nc cgs)
nc (1+ nc))
;se a distância horizontal entre o cogopoint e
;o vértice for igual (ou quase) a zero
(if (equal (distance cg (list x y))
0.0
arruma3dpoly:tolerancia)
(progn
;redefina a coordenada NV da 3dpoly para
;coincidir com o cogopoint
(vla-put-coordinate vla nv (vlax-3d-point cg))
;e força o while a parar
(setq nc (length cgs))))))
;passa para o proximo vertice
(setq nv (1+ nv)))
;ao terminar de processar a polilinha,
;remove ela da seleção
(ssdel ent ss)
;hum... atualiza a aparência da 3dpoly
(vla-update vla)
;mostra uma contagem regressiva
;no canto inferior esquerdo
(grtext -2 (itoa (sslength ss)))
)
;finaliza o controle de erros
(tbn:error-restore)
)
(prompt "\nArruma3dpoly carregado com sucesso!
Use ARRUMA3DPOLY para corrigir o Z de 3dpoly baseado em cogopoins
Deve funcionar no Civil 3D 2007 a 2019
Criado por:
Neyton Luiz Dalle Molle
Engenheiro Civil
neyton@yahoo.com
+55 41 98884 3044
")
(princ)
Veja, basicamente é a receita do bolo lá do começo. leia só as partes comentadas e o código fica muito simples.
Claro que tive de desmontar cada um daqueles 4 passos em outros mais curtos até que cada passinho fosse uma função do Visual Lisp...
Ah, você vai perguntar o que é esse controle de erro, onde aparece essas funções: tbn:error-init e tbn;error-restore.... (copia o código sem ler a postagem e diz que não funciona!!!) Veja elas aqui.
Note que após rodar o programa, as 3DPOLY são corrigidas e ao fazer o rebuild da superfície, fica assim:
Ah, mas ainda tem umas "perdidas" ali.... bem estas são LINEs e não foram usadas como breaklines. Então decidi ignorar....
Viu, prometi voltar às raízes do blog, então aí está!!!
Me pediram pra tirar umas seções de uns levantamentos feitos e desenhados no Civil 3D. Até aí tubo bem.
O problema é que, quem desenhou isso no Civil 3D, não foi lá muito caprichoso (nem garantido) e cometeu alguns deslizes ao conectar as 3DPOLY, que depois viriam a ser BREAKLINES do MDT do projeto, e coisas assim aconteceram:
Percebem? Tem pontos da superfície que ficaram com Z=0, depois que as breaklines foram adicionadas.
Obviamente, as seções gabaritadas ficaram um tanto.... erradas:
Esse tipo de erro é bem fácil de cometer, basta um pequeno deslize e o OSNAP não captura o ponto em 3D corretamente e pronto....
Obviamente, ao adicionar as BREAKLINES, o camarada viu essa tela famigerada pipocar na cara dele:
E ele escolheu
Bom, o caso é que eu peguei a coisa toda pronta, ou seja, já estava assim quando eu cheguei, hehehe
E agora? Arrumar uma por uma? hummm.... vai lá estagiário....
Vamos programar algo então....
Primeiro, como seria a receita do bolo?
1) selecionar as polilinhas
2) olhar em cada um dos seus vértices e
3) se estiver errado, acha um ponto e
4) se achar o ponto, corrige o vértice
Nossa, assim até parece fácil programar....
Olha como fica um programa em Visual Lisp:
;plugin para corrigir o Z de 3dpoly que deveria passar por cogopoints
;para lembrar a última opção
(setq arruma3dpoly:tolerancia 0.01)
(defun c:arruma3dpoly (/ acadApp aecVer c3dApp c3dDoc points cgs cg nx
ss ent vla pts x y z nv nc)
;inicializa o controle de erros
(tbn:error-init nil)
;pede a seleção das polilinhas
(prompt "\nSelecione as 3DPOLY")
(setq ss (ssget '((0 . "polyline") (100 . "AcDb3dPolyline"))))
;nada selecionado, sai
(if (not ss) (exit))
;pergunta pela tolerância na linha de comando
(setq tmp (getdist
(strcat
"\nInforme a tolerância <"
(rtos arruma3dpoly:tolerancia 2 5)
">")))
(if tmp (setq arruma3dpoly:tolerancia tmp))
;carrega as funções vl....
(vl-load-com)
(setq
;acessa o AutoCAD
acadApp (vlax-get-acad-object)
;calcula a versão do Civil 3D
aecVer (substr (vla-get-version acadapp) 1 4)
aecVer (vl-position aecVer
'("17.0" ;2007
"17.1" ;2008
"17.2" ;2009
"18.0" ;2010
"18.1" ;2011
"18.2" ;2012
"19.0" ;2013
"19.1" ;2014
"20.0" ;2015
"20.1" ;2016
"21.0" ;2017
"22.0" ;2018
"23.0" ;2019
))
aecVer (nth aecVer '("4.0" "5.0" "6.0" "7.0"
"8.0" "9.0" "10.0" "10.3"
"10.4" "10.5" "11.0" "12.0"
"13.0"))
;acessa a versão atual do Civil 3D
c3dApp (vla-GetInterfaceObject acadApp
(strcat "AeccXUiLand.AeccApplication."
aecVer))
;acessa o documento atual do civil 3d
c3dDoc (vla-get-activedocument c3dApp)
;pega sua lista de pontos
points (vlax-get-property c3dDoc "Points")
;inicializa a lista de coordenadas
cgs nil
;inicializa a tolerância
tolerancia 0.01)
;converte os cogopoints em lista de coordenadas
(vlax-for cg points
(setq cg (list (vlax-get-property cg "easting")
(vlax-get-property cg "northing")
(vlax-get-property cg "elevation"))
cgs (cons cg cgs)))
;em todas as polilinhas, faça
(repeat (sslength ss)
(setq
;pega a primeira polilinha da seleção
ent (ssname ss 0)
vla (vlax-ename->vla-object ent)
;obtém a lista de coordenadas da polilinha
;no format (x0 y0 z0 x1 y1 z1 ... xn yn zn)
pts (vlax-safearray->list
(vlax-variant-value
(vla-get-coordinates vla)))
;inicializa o contador de vértice
nv 0)
;para todos os vértices faça
(repeat (/ (length pts) 3)
(setq
;obtem X, Y e Z do vértice
nx (* nv 3)
x (nth nx pts)
y (nth (+ 1 nx) pts)
z (nth (+ 2 nx) pts)
;inicializa o contador de cogopoint
nc 0)
;se Z do vértice é igual (ou quase) a zero
(if (equal 0.0 z arruma3dpoly:tolerancia)
;busca o cogopoint mais próximo
(while (< nc (length cgs))
;pega o cogopoint NC
(setq cg (nth nc cgs)
nc (1+ nc))
;se a distância horizontal entre o cogopoint e
;o vértice for igual (ou quase) a zero
(if (equal (distance cg (list x y))
0.0
arruma3dpoly:tolerancia)
(progn
;redefina a coordenada NV da 3dpoly para
;coincidir com o cogopoint
(vla-put-coordinate vla nv (vlax-3d-point cg))
;e força o while a parar
(setq nc (length cgs))))))
;passa para o proximo vertice
(setq nv (1+ nv)))
;ao terminar de processar a polilinha,
;remove ela da seleção
(ssdel ent ss)
;hum... atualiza a aparência da 3dpoly
(vla-update vla)
;mostra uma contagem regressiva
;no canto inferior esquerdo
(grtext -2 (itoa (sslength ss)))
)
;finaliza o controle de erros
(tbn:error-restore)
)
(prompt "\nArruma3dpoly carregado com sucesso!
Use ARRUMA3DPOLY para corrigir o Z de 3dpoly baseado em cogopoins
Deve funcionar no Civil 3D 2007 a 2019
Criado por:
Neyton Luiz Dalle Molle
Engenheiro Civil
neyton@yahoo.com
+55 41 98884 3044
")
(princ)
Veja, basicamente é a receita do bolo lá do começo. leia só as partes comentadas e o código fica muito simples.
Claro que tive de desmontar cada um daqueles 4 passos em outros mais curtos até que cada passinho fosse uma função do Visual Lisp...
Ah, você vai perguntar o que é esse controle de erro, onde aparece essas funções: tbn:error-init e tbn;error-restore.... (copia o código sem ler a postagem e diz que não funciona!!!) Veja elas aqui.
Note que após rodar o programa, as 3DPOLY são corrigidas e ao fazer o rebuild da superfície, fica assim:
Ah, mas ainda tem umas "perdidas" ali.... bem estas são LINEs e não foram usadas como breaklines. Então decidi ignorar....
Viu, prometi voltar às raízes do blog, então aí está!!!
Muito interessante. Parabéns!
ResponderExcluir