Mostrando postagens com marcador VB. Mostrar todas as postagens
Mostrando postagens com marcador VB. Mostrar todas as postagens

Descida d'água tipo rápido DER-SP

Mais um pouco sobre o programa!!!

Hoje, vamos ver descidas d'água tipo rápido, padrão DER-SP.

Neste vídeo mostro a iteratividade do programa com o Civil 3D, fazendo alterações no greide que refletem no corredor, superfície de topo e consequentemente nos dispositivos lançados.

Você verá que o lançamento é bastante prático, pois os dispositivos podem ser redimensionados ou reposicionados em planta ou perfil. Também podem ser editados pelo quadro de propriedades.




Sei que não sou bom com vídeos, hehehe, mas dá um joinha aí!!!

Programinha - Mover label de pontos em polilinhas

Bom dia!!!

Hoje vou postar um pequeno programa que me quebra um baita galho!!!

É o seguinte, em poligonais onde queremos mostrar os vértices numerados no civil 3d, normalmente usamos o comando CREATEPTPLYLNCTRVERTAUTO, que cria os pontos automaticamente nos vértices da polilinha.

Até aí tudo bem, veja como fica:
Percebe que a label do ponto fica por cima da linha?

Bem, dá pra criar um estilo que põe o texto mais pra fora, mas isso nem sempre fica bom. E você acaba "estrechando" manualmente a label. Mas e se tiver uns 200 pontos? Aí a coisa começa a ficar chata e você manda o desenhista fazer... hehehehe

Bom, é para isso que este programinha serve, veja:

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.Civil.DatabaseServices

Public Class MovePtlabels
    'pra facilitar em muitos comandos:
    Public Function ED() As Editor
        Return DOC.Editor
    End Function

    'devolve o documento atual
    Public Function DOC() As Document
        Return Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
    End Function

    'move as labels dos pontos pela bissetriz das arestas
    <commandmethod commandflags.nopaperspace="" ovecogolabels="">
    Public Sub MoveCogoLabels()

        'selecione uma polilinha ou ecerra o comando:
        Dim peo As New PromptEntityOptions(vbNewLine & "Selecione a polilinha")
        peo.SetRejectMessage("Somente Polilinh")
        peo.AddAllowedClass(GetType(Polyline), True)
        Dim per As PromptEntityResult = ED.GetEntity(peo)
        If per.Status <> PromptStatus.OK Then Exit Sub

        'informe uma distância ou encerra o comando:
        Dim pdo As New PromptDistanceOptions(vbNewLine & "Indique a distância a afastar")
        Dim pdr As PromptDoubleResult = ED.GetDistance(pdo)
        If pdr.Status <> PromptStatus.OK Then Exit Sub

        'inicia a transação
        Using tr = DOC.TransactionManager.StartTransaction
            Try

                'obtem a polilinha selecionada
                Dim pl As Polyline = per.ObjectId.GetObject(OpenMode.ForRead)

                'determina se a polilinha está em sentido horário ou antihorário
                Dim s As Double = 0
                For i = 0 To pl.NumberOfVertices - 1
                    Dim pa = pl.GetPoint3dAt(i Mod pl.NumberOfVertices)
                    Dim pb = pl.GetPoint3dAt((i + 1) Mod pl.NumberOfVertices)
                    s += pa.X * pb.Y - pb.X * pa.Y
                Next

                'módulo do vetor entre a coordenada do vértice e a coordenada final da label
                'leva em conta o sentido da polilinha, para sempre mover para fora dela
                Dim f = If(s > 0, -1, 1) * pdr.Value

                'itera nos vértices:
                For i = 0 To pl.NumberOfVertices - 1
                    Dim pt As Point3d = pl.GetPoint3dAt(i)

                    'procura um cogopoint nas coordenadas deste vértice
                    'aqui podia criar uma query num pointgroup, mas fica como exercício
                    For Each cid In Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument.CogoPoints
                        Dim cogo As CogoPoint = cid.GetObject(OpenMode.ForWrite)
                        If cogo.Location <> pt Then Continue For

                        'se encontrou um cogopoint, calcula a bissetriz das arestas do vértice
                        Dim pAntes As Point3d = pl.GetPoint3dAt(If(i = 0, pl.NumberOfVertices - 1, i - 1))
                        Dim pDepois As Point3d = pl.GetPoint3dAt((i + 1) Mod pl.NumberOfVertices)
                        Dim vAntes As Vector3d = pAntes.GetVectorTo(pt).GetPerpendicularVector
                        Dim vDepois As Vector3d = pt.GetVectorTo(pDepois).GetPerpendicularVector

                        'reseta a posição da label antes de reposicionar:
                        cogo.ResetLabel()

                        'move a label para a nova posição
                        cogo.LabelLocation = pt.Add(f * vAntes.Add(vDepois).GetNormal)

                    Next
                Next
                'aplica as alterações e faz regen
                tr.Commit()
                ED.Regen()
            Catch
                MsgBox(Err.Description)

            End Try
        End Using
    End Sub
End Class


Eu usei o Visual Studio 2010 para compilar a dll e compilei para a versão 2014, que deverá funcionar também no 2015 e 2016.

Agora, é carregar com o NETLOAD e usar, veja o resultado:

Percebe a diferença?

É isso!!!!

Fica com exercício criar um algorítimo mais eficiente para encontrar cogopoints nos vértices da polilinha.

Veja que o programa tem um controle de erros (try, catch) para evitar erros fatais.

DOTNET, AutoCAD e blocos

É, as imagens do blog sumiram... mas não adianta ficar choramingando... pede pra sair!!!! pede pra sair sr 01!!!!

Hoje vou mudar um pouco e postar um código pra substituir blocos de diversos desenhos.

O caso é o seguinte: nosso contratante sismou que queria um bloco do carimbo diferente com layers diferentes, etc.

Temos trocentos arquivos DWG, com trocentos layouts cada. Imagina o trabalhão de substituir cada bloco de cada desenho....

Sim, você deve (deveria!!!) ter usado XREF, mas por algum motivo, não o fez. Terá de fazer não mão!!!

Serviço, não?

Bom, existem muitas formas de fazer isso, e como sou programador (ou não!!!), claro que escrevi algumas linhas pra me resolver isso

O programa resultou nisto:


No primeiro campo informamos o nome do bloco antigo.

No segundo campo, informamos um dwg que contem um bloco com o mesmo nome, porem editado.

Fiz assim, porque este bloco possui atributos dinâmicos.

Depois, no terceiro campo você escolhe a pasta onde estão os trocentos arquivos a modificar.

O último campo tem o nome do atributo dinâmico de "Visibility State". Se não tiver isso, deixe em branco.

Bem simples, né?

Aí é só mandar rodar e esperar.....
Um fiz aqui com 125 arquivos de 1.2MB cada e levou uns 5 minutos!!! Isso porque usei o RAMDISK e porque a técnica que usei para abrir o desenho, não precisa fazer nenhum "Regen", que é o que realmente demora no autocad.

Bom, o programa em sí é funcional, e nele voce poderá ver como abrir um dwg, editar e salvar

Compilei para o cad 2012, a DLL está na pasta ./bin/debug

use NETLOAD para carregar e TROCABLOCOS para usar

o código fonte está disponível. Usei o VS 2010

Se você gostar, posta um comentário aí!!!


O código fonte e o executável estão aqui

Autocad.NET - um exemplo simples


Que tal a gente exercitar um pouco a programação em .NET para autocad?

Bom, vou começar propondo um problema:
Você tem um eixo qualquer, que é uma polilinha e vai no campo levantar pontos, os quais possuem uma estaca e um offset (distância perpendicular ao eixo em questão)

Agora, pense que você precisa gerar o caminhamento resultante da conexão desses pontos. Algo assim:
Onde a linha preta é o seu eixo, e a linha azul, a linha resultante de um levantamento como este: link
Onde temos um valor de estaca e um valor de offset, separados por espaços.

Vamos estudar um possível código para isso:
''importar todos os namespaces necessarios:
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.DatabaseServices.OpenMode
Imports Autodesk.AutoCAD.EditorInput
Imports System.Reflection
Imports System.Windows.Forms
Imports Autodesk.AutoCAD.Runtime

Public Module teste

    ''CommandMethod, torna a sub FAZ visível para o usuário na linha de comando, como se fosse um comando do autocad
    
    Public Sub FAZ()

        ''pede a seleção de um arquivo qualquer:
        Dim PEGAARG As New OpenFileDialog
        PEGAARG.Filter = "Arquivo Txt|*.txt"

        ''se selecionou algo, continue, senão interrompa
        If PEGAARG.ShowDialog <> DialogResult.OK Then Exit Sub

        ''pede a selecão do eixo:
        Dim doc As Document = DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor
        Dim PPO As New PromptEntityOptions("SELECIONE O EIXO")
        Dim PPR As PromptEntityResult = ed.GetEntity(PPO)

        ''se selecionou, continue, senão interrompa:
        If PPR.Status <> PromptStatus.OK Then Exit Sub

        ''neste ponto, temos todas as informações necessárias
        ''logo, podemos abrir o arquivo de texto e ler, linha por linha
        Dim F As New System.IO.FileStream(PEGAARG.FileName, IO.FileMode.Open)
        Dim R As New System.IO.StreamReader(F)

        ''inicia uma transação com o autocad
        ''essa transação deverá ser fechada corretamente no fim da execução, ou causará erro fatal
        With doc.TransactionManager.StartTransaction()
            ''e tente executar o programa
            Try
                ''pegue o eixo selecionado, abrindo ele para lermos algumas informações:
                Dim eixo As Polyline = PPR.ObjectId.GetObject(ForRead)

                ''crie uma polilinha na memória. Ela irá receber os vertices calculados durante o
                ''processamento do arquivo de texto
                Dim PL As New Polyline
                PL.SetDatabaseDefaults()

                ''processe o arquivo de texto até o fim:
                Do
                    Dim LINHA As String = R.ReadLine
                    If LINHA = Nothing Then Exit Do

                    ''interprete a linha linha no texto, separando as informações:
                    Dim OBJ As String() = LINHA.Split(" ")
                    Dim ESTACA As Double = OBJ(0)
                    Dim OFFSET As Double = OBJ(1)

                    ''calcula a coordenada do ponto sobre o eixo, cuja estaca seja a que foi lida
                    Dim PT As Point3d = eixo.GetPointAtDist(ESTACA)

                    ''pegue a primeira derivada do eixo naquele ponto:
                    ''ele nos fornece um vetor unitario com a direção da reta tangente ao eixo neste ponto
                    Dim VETOR As Vector3d = eixo.GetFirstDerivative(PT)

                    ''calcula o vetor ortogonal a este, que é unitário também
                    Dim VETORTOGONAL As Vector3d = VETOR.GetPerpendicularVector()

                    ''calcula o ponto sobre a reta deste vetor ortogonal, que dista do ponto sobre o eixo
                    ''o valor lido na variavel OFFSET
                    Dim PT2 As Point3d = PT.Add(VETORTOGONAL * OFFSET)

                    ''adicione um vértice à nossa nova polilinha:
                    PL.AddVertexAt(PL.NumberOfVertices, New Point2d(PT2.X, PT2.Y), 0, 0, 0)
                Loop

                ''adicione a nova polilinha que está em memoria, ao modelspace:
                ''para isso, você deve pegar o BlockTableRecord do model (variavel btr)
                Dim bt As BlockTable = doc.Database.BlockTableId.GetObject(ForRead)
                Dim btr As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(ForWrite)
                btr.AppendEntity(PL)
                ''diz para a transação aberta que a polilinha deve fazer parte do nosso desenho
                ''e deve ser desenhada:
                .AddNewlyCreatedDBObject(PL, True)

            Catch
                ''se der pau, mostre na linha de comando o erro
                ed.WriteMessage(Err.Description)
            End Try

            ''ao terminar, feche o arquivo
            F.Close()

            ''encerra a transação, aceitando as modificações no desenho
            ''se pular essa linha, dá erro fatal
            .Commit()
        End With

    End Sub
End Module

A idéia é:
1) Pergunte pelo arquivo de texto
2) Pergunte pelo eixo
3) Abra o arquivo de texto e processe linha a linha deste, calcuando coordenadas
a serem adicionadas a uma polilinha nova

O passo três engloba um looping, para lermos as linhas
Tambem Calcula a coordenada do ponto que queremos, para isso seus conhecimentos de vetores, algebra linear e derivadas devem estar "frescos" ainda. No mais, depois de compilado o programa com o VISUAL STUDIO da Microsoft (sugiro o 10, express edition, é de gratis, ah, comfigure para usar o framework 3.5, senão o cad não consegue carregar e usar a nossa dll)

As referencias a serem adicionadas são o acmgd.dll e acdbmgd.dll, que estão na pasta do seu autocad.

Ao carregar a dll com o NETLOAD, digitamos o nosso novo comando: FAZ

e veja o resultado:

legal, não? e simples!!!

Explodir Spline em vb.net

Lembra daquele programinha para explodir spline? Que tal fazer isso em VB.NET? Veja:
(ah, usei o VISUAL STUDIO 2010 EXPRESS EDITION e AUTOCAD 2011)

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.DatabaseServices.OpenMode


Public Module TBN2
''ponteiro para a transacao atualmente aberta
 Public CurrentTrans As Transaction = Nothing

''funcoes internas
''editor, é como o utility do vba
    Public Function ED() As Editor
        Return AcadDOC.Editor
    End Function

''documento atual, é como do thisdrawing
    Public Function AcadDOC() As Document
        Return DocumentManager.MdiActiveDocument
    End Function

''retorna o banco de dados do desenho atual
    Public Function DB() As Database
        Return AcadDOC.Database
    End Function

''adiciona uma entidade criada ao modelspace
    Public Function AddToModel(ByVal e As Entity) As ObjectId
        Dim bt As BlockTable = DB.BlockTableId.GetObject(ForRead)
        Dim btr As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(ForWrite)
        AddToModel = btr.AppendEntity(e)
        CurrentTrans.AddNewlyCreatedDBObject(e, True)
    End Function

''inicia uma transacao com o desenho atual
    Public Sub StartTR()
        If CurrentTrans Is Nothing Then CurrentTrans = AcadDOC.TransactionManager.StartTransaction
    End Sub

''funcao principal: Spline2PLine
 <commandmethod("spline2pline", commandflags.usepickset)>
   Public Sub SPLINE2PLINE()
''inicia a transacao
        StartTR()
        Try
''pede a selecao das splines
            Dim ssr As PromptSelectionResult =
                ED.GetSelection(New PromptSelectionOptions,
                                New SelectionFilter(New TypedValue() {New TypedValue(0, "SPLINE")}))
            If ssr.Status <> PromptStatus.OK Then Exit Try

''pede a precisao
            Dim PPI As New PromptIntegerOptions(vbLf & "Qual a precisão?")
            PPI.UseDefaultValue = True
            PPI.DefaultValue = 10
            PPI.AllowNegative = False
            PPI.AllowZero = False
''se nao for informado, sai
            Dim ppr As PromptIntegerResult = ED.GetInteger(PPI)
            If ppr.Status <> PromptStatus.OK Then Exit Try

''em toda a selecao, repita:
            For Each ID As ObjectId In ssr.Value.GetObjectIds
                Dim S As Spline = ID.GetObject(ForWrite)
                Dim C As Entity = S.ToPolylineWithPrecision(ppr.Value)
                AddToModel(C)
            Next
'' em caso de erro na execucao:            
        Catch
''mostra o erro na linha de comando
            ED.WriteMessage(Err.Description)
        End Try

''fecha a transacao e informa ao autocad, para manter as alteracoes no banco de dados
        CurrentTrans.Commit()
    End Sub

End Module

Copie para um novo projeto do visual studio, carregue as referências:
acmgd.dll e acdbmgd.dll do autocad, compile e teste!!!



SlideViewer - Source Code

Lembra do visualizador de slides? Então teve até um paquito que disse que ele era fraco... e é mesmo... bom estou esperando ele mandar algo melhor pra postar no lugar dele, hehehe

Em todo caso, que tal dar uma olhadela no fonte do bicho?? como será que se lê um slide? Bem, veja se você entende a gambiarra que eu fiz aqui
Gostaria muito de melhorar o programa, corrigir os bugs... emfim, quem estiver disposto a olhar, sinta-se a vontade!!!

Ah, pode usar, mexer, mudar, etc o codigo, mas não é permitido vender sob hipotese alguma este programa e derivações deste codigo sem meu expresso consetimento. Afinal, você o obteve DE DRAÇA. Também não dou garantia alguma do seu funcionamento, hehehe

civil 3d 2010 e .NET

Manja de .NET? manja de civil 3d?

então dê uma olhada neste link

Aquele que conseguir uma resolver a charada, ganha uma lincença do EXPGE, pode ser da maneira que está lá ou outra, desde que o resultado seja o mesmo

lembrando que é preciso adicionar as referncias às dlls do civil: AeccDbMgd.dll e AecBaseMgd.dll, alem das dlls do autocad: acdbmgd.dll e acmgd.dll

o problema é que no 2008 e 2009 para alterar os "Part Data Value", bastava:
tubo.PartDataRecord.Find("parametro").Tag = valor

já no 2010 (ou ao menos deveria ser...):
tubo.PartData.GetDataField("parametro").Value = valor

mas isso não esta funcionando no 2010... então aí está: resolveu a charada, ganhou um EXPGE, hehehe

editado em 19 de setembro de 2009:
como ninguem consegiu, está encerrada a promoção, hehehe, veja aqui

Retangulos e vb.net

Que tal desenhar retângulos com VB.NET em qualquer ângulo?
Veja o programa abaixo:
mais...


'importa as dependencias


Imports Autodesk.AutoCAD.DatabaseServices


Imports Autodesk.AutoCAD.Runtime


Imports Autodesk.AutoCAD.Geometry


Imports Autodesk.AutoCAD.ApplicationServices


Imports Autodesk.AutoCAD.EditorInput


 


Public Class TestEntityJig


 


    'classe que faz o prompt do terceiro ponto, strechando o retângulo:


    Private Class GetPoint2Jig


        'herda estas caracteristicas:


        Inherits EntityJig


 


        'variaveis globais desta classe:


        Private pta, ptb, ptc As Point3d 'pontos que formam o retângulo


        Private msg As String


 


        Public Sub New(ByVal pt1 As Point3d, ByVal pt2 As Point3d, ByVal message As String)


            'cria uma pline virtual:


            MyBase.New(New Polyline(4))


            With DirectCast(Entity, Polyline)


                .AddVertexAt(0, New Point2d(pt1.X, pt1.Y), 0, 0, 0)


                .AddVertexAt(0, New Point2d(pt2.X, pt2.Y), 0, 0, 0)


                .AddVertexAt(0, New Point2d(pt2.X, pt2.Y), 0, 0, 0)


                .AddVertexAt(0, New Point2d(pt1.X, pt1.Y), 0, 0, 0)


                .Closed = True


            End With


            'inicializa as variaveis globais


            msg = message


            pta = pt1


            ptb = pt2


 


        End Sub


 


        'função que atualiza a variavel PTC, que é usada para redesenhar o retângulo


        Protected Overrides Function Sampler(ByVal prompts As JigPrompts) As SamplerStatus


            Dim jigOpts As New JigPromptPointOptions(msg)


            jigOpts.UserInputControls = UserInputControls.Accept3dCoordinates


 


            Dim dres As PromptPointResult = prompts.AcquirePoint(jigOpts)


            ptc = dres.Value


 


            If dres.Status = PromptStatus.Cancel Then


                Return SamplerStatus.Cancel


            Else


                Return SamplerStatus.OK


            End If


        End Function


 


        'função que atualizao retângulo


        Protected Overrides Function Update() As Boolean


            'angulo do vetor BA


            Dim ang_ab As Double = Math.Atan2(ptb.Y - pta.Y, ptb.X - pta.X)


 


            'angulo interno dos vetores AB e AC


            Dim ang_abc As Double = Math.Atan2(ptc.Y - pta.Y, ptc.X - pta.X) - ang_ab


 


            'distancia do ponto A ao B


            Dim d_ab As Double = pta.DistanceTo(ptc) * Math.Sin(ang_abc)


 


            'angulo perpendicular ao vetor AB


            Dim ang_ac = ang_ab + Math.PI / 2


 


            'delta das coordenadas (nao achei uma função polar...):


            Dim dx As Double = d_ab * Math.Cos(ang_ac)


            Dim dy As Double = d_ab * Math.Sin(ang_ac)


 


            'atualiza o retangulo


            Try


                With DirectCast(Entity, Polyline)


                    .SetPointAt(2, New Point2d(ptb.X + dx, ptb.Y + dy))


                    .SetPointAt(3, New Point2d(pta.X + dx, pta.Y + dy))


                End With


            Catch generatedExceptionName As System.Exception


                Return False


            End Try


            Return True


 


        End Function


 


        'função que devolve a polilinha virtual


        Public Function Get_Entity() As Polyline


            Return DirectCast(Entity, Polyline)


        End Function


    End Class


 


    'comando a ser usado na linha de comando:


    <CommandMethod("ret")> _


    Public Shared Sub ret()


        Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor


 


        'pede o primeiro ponto


        Dim res1 As PromptPointResult = ed.GetPoint(vbLf & "Ponto 1:")


        If res1.Status <> PromptStatus.OK Then Exit Sub


 


        'pede o segundo ponto


        Dim opts As New PromptPointOptions(vbLf & "Ponto 2:")


        opts.BasePoint = res1.Value


        opts.UseBasePoint = True


        Dim res2 As PromptPointResult = ed.GetPoint(opts)


        If res2.Status <> PromptStatus.OK Then Exit Sub


 


        'pede o terceiro ponto, modificando o retangulo


        'conforme o mouse mexe:


        Dim jig As New GetPoint2Jig(res1.Value, res2.Value, vbLf & "Ponto 3")


        Dim res As PromptResult = ed.Drag(jig)


 


 


        If res.Status = PromptStatus.OK Then


            'tudo certo, adiciona a polilina ao modelspace:


            Dim pline As Polyline = jig.Get_Entity


            Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database


            Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = db.TransactionManager


            Dim ta As Transaction = tm.StartTransaction()


 


            Try


                Dim bt As BlockTable = tm.GetObject(db.BlockTableId, OpenMode.ForRead, False)


                Dim btr As BlockTableRecord = tm.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, False)


                Dim lineid As ObjectId = btr.AppendEntity(pline)


                tm.AddNewlyCreatedDBObject(pline, True)


                ta.Commit()


            Finally


                ta.Dispose()


            End Try


 


        End If


    End Sub


End Class



Com ele dá pra fazer isso:

Baixe o programa pronto aqui (autocad 2008 em diante, ok?), para usar, descompacte a dll em algum lugar, e use o comando NETLOAD para carregar a DLL, depois digite RET na linha de comando.

Netload 2 - A Missão

Netload 2 - A Missão!!! hehehe então voce fez um probraminha em VB.NET ou (C#, em fim...)
carregou com o net load e nada aconteceu... é.... em lisp, se fazemos isso:


(defun c:algumacoisa
;....
)
(c:algumacoisa)



O programa algumacoisa é executado logo após ser carregada a lisp, correto?

Agora, que tal se um programa feito em VB.NET também fosse executado logo após ser carregado com o netload?? Seria legal né? Imagine colocar um "splashscreen"??
O pior, é que é muito simples de fazer, veja:


Imports Autodesk.AutoCAD.Runtime
 
Public Class INICIALIZACAO
 
    Implements IExtensionApplication
 
    Private Sub Initialize() Implements IExtensionApplication.Initialize
 
        'faça algo interessante aqui!!!
        MsgBox("Ei, carregou!!! Agora, na linha de comando digite: ALGUMACOISA")
 
    End Sub
 
    Private Sub Terminate() Implements IExtensionApplication.Terminate
 
    End Sub
 
    <CommandMethod("algumacoisa")> _
    Public Sub algumacoisa()
        MsgBox("Ei, deu certo!!")
    End Sub
End Class



O truque todo fica por conta daquele Implements IExtensionApplication e as subs Initialize e Terminate.

E olha que me debati um monte pra achar isso.... afff

Ah, claro, adicione as referências ACMGD.DLL e ACDBMGD.DLL do seu autocad!!
junte isso com o outro post do netload e você terá algo muito interessante para "autoinstalar" seu programa!!!

NETLOAD - que saco!!

Fez sua ".net" dll e toda vez que vai usar ela tem que usar o netload? Resolveu ela com lisp:
(command "netload" "c:/testenet.dll")???
Credo!!! Eu também já me encomodei com isso... em fim, eu fiz uma gambiarra aqui que pode te ser util, primeiro pegue aquele pequeno teste de vb.net, ou copia este:

mais...


Public Class teste
'o autocad em si
Public acadApp AsIAcadApplication

Public Sub New()
'17.0? = cad 2007
'17.1 = cad 2008
'17.2 = cad 2009
acadApp = GetObject(, "Autocad.Application.17.1")

'adiciona o loader ao registro:

'calcula a chave de registro:
Dim acadkey As String = SystemObjects.DynamicLinker.ProductKey & _
"\Applications"

'monta a string da localização da DLL:
Dim loader As String = My.Application.Info.DirectoryPath & "\" & _
My.Application.Info.AssemblyName & ".dll"

'cria e/ou abre uma chave para sua aplicação:
Dim key As RegistryKey = Registry.CurrentUser. _
OpenSubKey(acadkey, True). _
CreateSubKey("TESTE")

'caso voce mude a pasta onde está instalada, deve atualizar no registro:
If key.GetValue("LOADER") <>loader Then
With key
.SetValue("DESCRIPTION", "TESTE,este é um teste de AUTOLOAD")

'estes valores não mudam:
.SetValue("LOADCTRLS", 12, RegistryValueKind.DWord)
.SetValue("MANAGED", 1, RegistryValueKind.DWord)
.SetValue("LOADER", loader)

'aqui, adiciona a lista os comandos criados:
With .CreateSubKey("Commands")
Dim mtr() AsObject = {"DESENHALINHA","TESTE"}
ForEach k In mtr
.SetValue(k, k)
Next
End With
End With
End If

End Sub

<CommandMethod("TESTE")> _
Public Sub TESTE()
MsgBox("OLÁ MUNDO!")
End Sub
'expoe a sub como um novo comando do autocad
<CommandMethod("DESENHALINHA")> _
Public Sub desenhalinha()
Dim Thisdrawing As IAcadDocument = acadApp.ActiveDocument
Dim pt1(2), pt2(2) AsDouble
Dim linha As AcadLine
Dim lay As AcadLayer

'pede o primeiro ponto:
pt1 = Thisdrawing.Utility.GetPoint(, "Entre com o primeiro ponto")

'pede o segundo ponto:
pt2 = Thisdrawing.Utility.GetPoint(pt1,"Entre com o segundo ponto")

'desenha uma linha:
linha = Thisdrawing.ModelSpace.AddLine(pt1, pt2)

'troca o layer, criando se ele nao existe:
Try
linha.Layer = "layer_teste"
Catch
lay = Thisdrawing.Layers.Add("layer_teste")
linha.Layer = "layer_teste"
End Try

End Sub

End Class

A idéia é usar o registro do windows, como descrito aqui

Este exemplo, gerou estas linhas no registro:


Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R17.2\ACAD-7000:409\Applications\TESTE]
"DESCRIPTION"="TESTE, este é um teste de AUTOLOAD"
"LOADCTRLS"=dword:0000000c
"MANAGED"=dword:00000001
"LOADER"="I:\\vbnet\\TESTE\\teste\\bin\\Release\\teste.dll"

[HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R17.2\ACAD-7000:409\Applications\TESTE\Commands]
"DESENHALINHA"="DESENHALINHA"
"TESTE"="TESTE"



Veja que adicionei algumas linhas na sub "NEW" da minha classe, que faz o trabalho de adicionar ao registro os parâmetros necessários ao autoload.

Assim, só é necessário UM netload, que acaba funcionando como uma instalação. Se você fechar o autocad e abrir novamente, bastará digitar o nome do comando que você criou na sua dll, basta apenas que a inclua naquela lista, deste exemplo:
Dim mtr() AsObject = {"DESENHALINHA","TESTE"}
"DESENHALINHA" e "TESTE" são os nomes dos comandos implementados nesta dll.

Se quiser, baixe aqui o código fonte para o cad 2009. Caso tenha anteriores, apenas troque as referências:

VB.NET e o autocad

Que tal mudar um pouco a cara dos nosso programinhas e tornar a coisa mais interessante? Vamos experimentar o VB.NET então!!! Com ele podemos usar os forms do Framework, bem mais interessantes que os basiquinhos do VBA e MUIIIIIIIITTO melhor que os famigerados DCLs (objectdcl... nome fácil de pegar nojo, hehehe) vamos fazer algo mais que o famoso "Hello World" que todo tutorial faz, vamos já desenhar uma linha!!!

Para isso, usei o VB.NET Express Edition, di grátis no site da M$ e o Autocad, no caso as versões 2008 de ambos
no editor do VB.Net, crie uma nova "Class Library" e colenela este código:




'acadApp depende de:
Imports AutoCAD = Autodesk.AutoCAD.Interop

'objetos do cad (textot, linha, layer, etc..) dependem de:
Imports AcadLib = Autodesk.AutoCAD.Interop.Common

'CommandMethod depende de:
Imports Autodesk.AutoCAD.Runtime

Public Class teste

'o autocad em si
Public acadApp As AutoCAD.IAcadApplication

'documento corrente
Public Thisdrawing As AutoCAD.IAcadDocument

'é executado ao carregar a dll com o NETLOAD
Public Sub New()
'17.0? = cad 2007
'17.1 = cad 2008
'17.2 = cad 2009
acadApp = GetObject(, "Autocad.Application.17.1")
Thisdrawing = acadApp.ActiveDocument
End Sub

'expoe a sub como um novo comando do autocad
_
Public Sub desenhalinha()
Dim pt1(2), pt2(2) As Double
Dim linha As AcadLib.AcadLine
Dim lay As AcadLib.AcadLayer

'pede o primeiro ponto:
pt1 = Thisdrawing.Utility.GetPoint(, "Entre com o primeiro ponto")

'pede o segundo ponto:
pt2 = Thisdrawing.Utility.GetPoint(pt1, "Entre com o segundo ponto")

'desenha uma linha:
linha = Thisdrawing.ModelSpace.AddLine(pt1, pt2)

'troca o layer, criando se ele nao existe:
Try
linha.Layer = "layer_teste"
Catch
lay = Thisdrawing.Layers.Add("layer_teste")
linha.Layer = "layer_teste"
End Try

End Sub

End Class


Algumas palavras devem aparecer sublinhadas, pois ainda não adicionamos as referências que precisamos, são elas (no caso do cad 2008):
para que possamos criar comandos:
pasta do Autocad\"acmgd.dll"
para que possamos desenhar no cad:
"Autocad 2008 Type Lybrary"
"Autocad/ObjecDBX Commom 17.0 type Libray"

E pronto!!

As partes importantes da classe:
a sub "New" que inicializa qualquer coisa que precisamos ao carregar a dll que será gerada e a linha _ antes da Sub que contem o programa em si

De resto, é algumas adaptações do código VBA para VB.NET, por exemplo:
o tipo "Variant" irá ser o tipo "Object", o legal é que o processo do "copiar/colar" já az essa transformação!!!

No VBA, usamos o Thisdrawing, que no VB não tem, mas aí simulamos ele, como no código acima

E claro, precisamos dos tipos dos objetos do cad ("AcadLayer", "AcadLine", por exemplo) aí fiz outra gambiarra usando o "AcadLib" que aparece no código, veja como criei e usei ele...
Interessante, não?

Compile o código e ele irá gerar o arquivo "teste.dll" na pasta /bin/release ( se você não mudou isso)

Carregue no cad com o comando NETLOAD e na linha de comando chame o novo comando criado: "desenhalinha"
Chique, né?
mais aqui e aqui