twitter youtube facebook linkedin email
Connect with:

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

Tabela de Curvas de Bordo via API

Pedro Soethe
12/07/2013

Por Augusto Gonçalves, Autodesk Developer Network

Este post é uma continuação do post anterior, onde as curvas de bordo foram numeradas. Aqui o objetivo é criar uma tabela com o resumo das curvas, contendo o número, raio, comprimento, norte/este do PC e PT. A figura abaixo apresenta a tabela de resultado.

tabela_curva_bordo

Neste caso iremos criar uma tabela utilizando APIs do AutoCAD. Isto significa que a tabela será independente do Civil 3D e não irá atualizar como outras tabelas nativas. Ainda não temos APIs para acessar as tabelas nativas do Civil 3D.

Para criar a tabela iremos utilizar o objeto Table, que está dentro do namespace Autodesk.AutoCAD.DatabaseServices. Um namespace do .NET é utilizado para organizar os objetos, e sempre iremos encontrar objetos com características em comum. Neste case, o namespace é o DatabaseServices, que contém os objetos de banco de dados do AutoCAD, ou seja, aqueles que são gravados no desenho.

O nosso código anterior já tinha este e outros namespaces, como EditorInput, que contem a linha de comando e objetos de seleção, ou Geometry, que contém objetos relacionados a operações geométricas. É possível ter namespaces com mesmo nome, como DatabaseServices, mas em diferentes APIs, como Autodesk.AutoCAD e Autodesk.Civil.

Para este exemplo iremos criar uma tabela com 5 colunas. A quantidade de linhas será definida pela quantidade de curvas + 2, para conter o cabeçalho. Para adaptar este código e incluir mais colunas, é necessário alterar esta quantidade e escrever os valores desejados.

O código abaixo contém o código do post anterior em cinza, e o código adicional em cores, fica a sua escolha copiar o código inteiro (e colar substituindo no arquivo CurvasBordo.vb) ou adicionar as novas linhas.

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 acontencer,

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

        ‘ se não, vamos para a proxima entidade

        Dim curva As Arc = TryCast(trans.GetObject(

            idEntidade, OpenMode.ForRead), Arc)

        ‘ se for vazio, então proximo 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

      ‘ próximo 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

 

      ‘ *********************************************

      ‘ Incluir a tabela de curvas

      ‘ *********************************************

      ‘ como este comando é uma continuação, vamos

      ‘ pedir ao usuário para selecionar o ponto de

      ‘ inserção da tabela, mas se decidir cancelar

      ‘ (com ESC), então vamos aceitar o que já foi

      ‘ feito, mas se for OK, continuamos com a tabela

      Dim resSelPontoInsercaoTabela As  _

        PromptPointResult = _

        ed.GetPoint(“Ponto inserção da tabela: “)

      If (resSelPontoInsercaoTabela.Status <> _

          PromptStatus.OK) Then

        trans.Commit()

        Exit Sub

      End If

 

      ‘ criar uma tabela, com 5 colunas e linhas para

      ‘ as curvas que foram encontradas

      Dim tabela As New  _

        Autodesk.AutoCAD.DatabaseServices.Table

      tabela.SetSize(cont + 1, 5)

      tabela.TableStyle = db.Tablestyle

      tabela.Position = resSelPontoInsercaoTabela.Value

 

      ‘ iniciar a tabela com o cabeçalho

      Dim linha As Integer = 0

      linha = 0 ‘ linha de título

      tabela.Cells(linha, 0).TextString = “Curvas de Bordo”

      tabela.MergeCells(CellRange.Create(tabela, 0, 0, 0, 4))

      linha = 1 ‘ linha de cabeçalho

      tabela.Cells(linha, 0).TextString = “Número”

      tabela.Cells(linha, 1).TextString = “Raio”

      tabela.Cells(linha, 2).TextString = “Comp.”

      tabela.Cells(linha, 3).TextString = “PC”

      tabela.Cells(linha, 4).TextString = “PT”

      linha = 2 ‘ próxima linha

 

      ‘ percorrer as curvas encontradas

      cont = 1

      For Each curva As Arc In curvasBordoFiltrada

        ‘ coluna 1: número

        tabela.Cells(linha, 0).TextString = _

          cont.ToString()

        ‘ coluna 2: raio, com 4 casas decimais

        tabela.Cells(linha, 1).TextString = _

          String.Format(“{0:0.000}”, curva.Radius)

        ‘ coluna 3: comprimento

        tabela.Cells(linha, 2).TextString = _

          String.Format(“{0:0.000}”, curva.Length)

        ‘ coluna 4: norte e este do primeiro ponto

        tabela.Cells(linha, 3).TextString = _

          String.Format(“{0:0.0000}, {1:0.0000}”, _

                        curva.StartPoint.Y, _

                        curva.StartPoint.X)

        ‘ coluna 5: norte e este do segundo ponto

        tabela.Cells(linha, 4).TextString = _

          String.Format(“{0:0.0000}, {1:0.0000}”, _

                        curva.EndPoint.Y, _

                        curva.EndPoint.X)

        cont += 1 ‘ próximo número de curva

        linha += 1 ‘ próxima linha

      Next

 

      ‘ ajusta o layout da tabela

      tabela.GenerateLayout()

 

      ‘ insere a tabela no model space

      mSpace.AppendEntity(tabela)

      trans.AddNewlyCreatedDBObject(tabela, True)

      ‘ *********************************************

 

      ‘ 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

Os passos adicionais são exatamente os mesmos: chamar o Build no Visual Basic 2010 Express e em seguida executar NETLOAD no Civil 3D para carregar a DLL criada. Finalmente o comando NUMERARCURVABORDO.

Este post conclui o exemplo com curvas de bordo. No próximo post iremos abordar outros pontos da API.

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.

'