twitter youtube facebook linkedin email
Connect with:

Mundo AEC - Blog Oficial sobre soluções da Autodesk Brasil

Numerando Curvas de Bordo via API

Pedro Soethe
05/07/2013

Por Augusto Gonçalves, Autodesk Developer Network

Neste post irei mostrar como numerar as curvas de bordo de um alinhamento utilizando VB.NET. É necessário ter completado o exemplo do post anterior.

O objetivo geral é, em um dado alinhamento, por exemplo em verde na figura abaixo, localizar as curvas de bordo e escrever um texto indicativo numerado, por exemplo, “Curva = 1”.

resultado_final

Para numerar as curvas, é necessário descobrir a ordem. Sempre que trabalhamos com programação, temos que elaborar uma regra inequívoca para determinar a quais curvas serão consideradas e a ordem.

Então algumas regras deve ser adotadas: deve existir um Alinhamento do Civil 3D como referência, as curvas de bordo devem ser do tipo Arco do AutoCAD, e estes arcos devem estar até uma distância máxima do alinhamento. Estas regras definem quais arcos serão considerados.

Para determinar a ordem iremos determinar qual a estaca mais próxima do centro do arco que representa a curva de bordo (ver figura abaixo). Esta ordem deve ser definida no sentido de crescimento das estacas. Desta maneira, independente do lado, a numeração dos arcos será definida pela estaca onde o centro do arco está projetado.

visao_geral_curvas

Dica: embora possam parecer óbvias, as regras que serão implementadas em programação devem ser o mais especificas possíveis. Regras fracas levam a rotinas que podem falhar (produzir resultados inesperados).

Preparando para o código!

Partindo do projeto do post anterior, inicie o Visual Basic 2010 Express, abra o projeto ProjetoCivil3DBR. Na janela de Solution Explorer, clique com o botão direto no projeto e escolha Add, em seguida a opção Class. No formulário que se abrirá, digite o nome da classe, neste exemplo CurvasBordo.

menu_add_class

classe_curvas_bordo

Na prática não é necessário criar uma classe para cada novo comando, mas iremos adotar esta abordagem para facilitar a organização. A nova classe será criada em um novo arquivo .vb do projeto.

API de busca e ordenação

Na prática vamos sempre assumir que uma lista de qualquer coisa estará fora da ordem desejada. Para este exemplo, temos que selecionar todos os arcos, filtrar pelos que estão até uma determinada distância máxima do alinhamento, e ordená-los pela estaca.

A API do Civil 3D não incluir métodos para filtros muito específicos ou ordenação, mas por se tratar de uma API .NET, podemos utilizar recursos nativos da plataforma VB.NET. E isto vale para (praticamente) todos as maravilhas do .NET! Espetacular!

Para filtro e ordenação, dentre outros, temos uma API do .NET chamada LINQ (Language-Integrated Query), que existe desde a versão 3.5 e é extremamente útil. Vale a pena estudar um pouco.

Nota: Civil 3D 2012, 2013 e 2014 usam .NET 4.0.

Hora do código!

Como no exemplo anterior, todas a linhas de código que começam com ‘ (aspas simples) são comentários e ficam verde no Visual Basic 2010 Express. Utilizamos comentários para explicar o que um conjunto de linhas de código irá executar. Não é necessário, ou prático, comentar todas a linhas de código, apenas o que for necessário.

O código abaixo começa de maneira similar ao código do post anterior, com CommandMethod. Esta marcação (atributo em .NET) define o nome do comando no AutoCAD Civil 3D. Ou seja, sempre que digitarmos NUMERARCURVABORDO na linha de comando, iremos executar a rotina deste comando.

Este comando requer que o usuário selecione um alinhamento e digite uma distância. Temos que garantir que isso ocorra, caso contrário o comando não pode prosseguir. Observe o Exit Sub quando o resultado da seleção não é OK (o código <> significa diferente).

Em seguida selecionamos todos os arcos do model space. Estes arcos serão filtrados pela distancia máxima e ordenados pelo estaca, resultando na coleção curvasBordoFiltrada. Esta coleção será utilizada para a criação dos textos indicativos (similares ao label).

Agora copie o código abaixo, cole no arquivo CurvaBordo.vb aberto no Visual Basic 2010 Express. O resultado deve ser como na imagem abaixo. Retire eventuais linhas em branco.

vs_codigo_curva_bordo

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.EditorInput

Imports Autodesk.AutoCAD.DatabaseServices

Imports Autodesk.AutoCAD.Geometry

Imports Autodesk.AutoCAD.ApplicationServices

 

Imports Autodesk.Civil.DatabaseServices

 

Public Class CurvasBordo

  <CommandMethod(“numerarCurvaBordo”)> _

  Public Sub CmdNumerarCurvaBordo()

    ‘ acessar o editor do AutoCAD

    ‘ através deste objeto podemos selecionar

    ‘ entidade na tela

    Dim ed As Editor = Application.DocumentManager.

      MdiActiveDocument.Editor

 

    ‘ selecionar o alinhamento

    ‘ o método AddAllowedClass garante que apenas alinhamentos

    ‘ poderão ser selecionados pelo usuário

    Dim opSelAlinhamento As New PromptEntityOptions(

      “Selecione o alinhamento: “)

    opSelAlinhamento.SetRejectMessage(“Apenas alinhamento”)

    opSelAlinhamento.AddAllowedClass(GetType(Alignment), True)

    Dim resSelAlinhamento As PromptEntityResult =

      ed.GetEntity(opSelAlinhamento)

    If (resSelAlinhamento.Status <> PromptStatus.OK) Then Exit Sub

    Dim idAlinhamento As ObjectId = resSelAlinhamento.ObjectId

 

    ‘ distancia máxima para centro do circulo

    Dim opSelDistancia As New PromptDistanceOptions(

      “Distancia máxima das curvas (centro): “)

    opSelDistancia.AllowZero = False

    Dim resSelDistancia As PromptDoubleResult =

      ed.GetDistance(opSelDistancia)

    If (resSelDistancia.Status <> PromptStatus.OK) Then Exit Sub

    Dim distanciaMax As Double = resSelDistancia.Value

 

    Dim db As Database = Application.DocumentManager.

      MdiActiveDocument.Database

    Using trans As Transaction =

      db.TransactionManager.StartTransaction

 

      ‘ abrir o alinhamento

      Dim alinhamento As Alignment = trans.GetObject(

        idAlinhamento, OpenMode.ForRead)

 

      ‘ abrir o model space

      Dim mSpace As BlockTableRecord = trans.GetObject(

        alinhamento.OwnerId, OpenMode.ForWrite)

 

      ‘ criar uma lista de arcos

      Dim curvasBordo As New DBObjectCollection

      ‘ percorrer o model space buscando por curvas de bordo

      For Each idEntidade As ObjectId In mSpace

        ‘ abrir cada entidade do model space e tentar

        ‘ converter para Arc, se a conversão acontecer,

        ‘ então temos um arco e adicionamos a lista,

        ‘ se não, vamos para a próxima entidade

        Dim curva As Arc = TryCast(trans.GetObject(

            idEntidade, OpenMode.ForRead), Arc)

        ‘ se for vazio, então próximo item da lista

        If (curva Is Nothing) Then Continue For

        curvasBordo.Add(curva)

      Next

 

      ‘ usando LINQ para filtrar e ordenar os arcos

      ‘ obteremos o ponto no alinhamento mais próximo do centro

      ‘ do arco em seguida iremos ordenar estes pontos, desta

      ‘ maneira os arcos estarão ordenados pelo ponto mais

      ‘ proximo no alinhamento

      Dim curvasBordoFiltrada =

        From arco As Arc In curvasBordo

        Where arco.Center.DistanceTo(

          alinhamento.GetClosestPointTo(

            arco.Center, False)) < distanciaMax

        Order By alinhamento.GetDistAtPoint(

          alinhamento.GetClosestPointTo(arco.Center, False))

 

      ‘ numerador que será usado no texto

      Dim cont As Integer = 1

 

      ‘ escrever os textos nas curvas utilizando DBText

      ‘ os textos serão independentes do alinhamento

      For Each curva As Arc In curvasBordoFiltrada

        ‘ linha de referência entre os pontos inicial e

        ‘ final do arco. Esta linha não será desenhada no

        ‘ Civil3D, apenas utilizada para encontrar o midpoint,

        ‘ onde será inserido o texto

        Dim linhaRef As New LineSegment3d(

          curva.StartPoint, curva.EndPoint)

 

        Dim labelCurva As New DBText

        labelCurva.SetDatabaseDefaults()

        ‘ especificar o texto

        labelCurva.TextString = String.Format(

          “Curva = {0}”, cont)

        ‘ alinha pelo centro

        labelCurva.HorizontalMode =

          TextHorizontalMode.TextCenter

        ‘ alinhar pelo MidPoint

        labelCurva.AlignmentPoint = linhaRef.MidPoint

        ‘ rotacionar alinhado com os pontos do arco

        labelCurva.Rotation = linhaRef.

          Direction.GetAngleTo(Vector3d.XAxis)

 

        ‘ adicionar ao model space

        mSpace.AppendEntity(labelCurva)

        trans.AddNewlyCreatedDBObject(labelCurva, True)

 

        ‘ incrementar o numerador

        cont += 1

      Next

 

      ‘ este ‘commit’ confirma que as alterações estão

      ‘ ok e podem ser enviadas para a base de dados do C3D

      trans.Commit()

    End Using

  End Sub

End Class

Agora com o código inserido no Visual Basic 2010 Express, vá ao menu Debug, escolha a opção Build ProjetoCivil3DBR, da mesma forma que foi feito para o exemplo do primeiro post.

build_DLL

Finalmente abra o Civil 3D, execute o comando NETLOAD, escolha a DLL na pasta Release. Assim como no exemplo do primeiro post, a DLL deve estar na pasta:

…\ProjetoCivil3DBR\ProjetoCivil3DBR\bin\Release\ProjetoCivil3DBR.dll

O novo comando está pronto, execute NUMERARCURVABORDO, selecione o alinhamento, especifique a distancia máxima e pronto. O textos serão desenhados no projeto do Civil 3D.

No próximo post iremos incrementar este comando para desenhar uma tabela de curvas, com raio, comprimento, PC e PT.

Sugestões e comentários são bem vindos!

Featured Links

Pedro Soethe

Pedro Luis Soethe Cursino é formado em Engenharia Civil pela Universidade de Taubaté, tem pós-graduação em Georreferenciamento pela Faculdade de Pirassununga e em Estradas e Vias Urbanas pela FESP. Trabalha a mais de 15 anos na área de infraestrutura e é responsável por vários projetos executados no Brasil em diversas disciplinas como estradas, projetos urbanos, loteamentos, infraestrutura hidro-sanitária, drenagem, terraplanagem entre outras.

'