Civil 3D - breaklines standard e Z igual a zero

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 escolheu esperar 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á!!!

Um comentário: