Pular para o conteúdo principal

Aplicando uma operação a todas as entidades em um desenho do AutoCAD usando .NET

A grande questão do AutoCAD  .NET é que a maior patê das entidades são tratadas genericamente. Com isso existem algumas vantagens e algumas desvantagens.

A vantagem maior é que podemos também trata-los genericamente quando queremos usar uma função especifica de um determinado grupo.

Esta função generalista apaga todas as entidades em um desenho que atendem a uma condição de precisão. Desta forma este código apaga todas as entidades tipo “cruva” que tem seu comprimento zerado.

Eu uso um programa chamado PLS-CADD para plotação e elaboração de projetos de Linhas aéreas de transmissão. A saída do programa são documentos em DXF que precisam ser trabalhados em AutoCAD. Nesse documento de saída muitas informações devido a planificação do projeto são projetadas na planta ou no perfil através de uma linha de comprimento 0, uma questão organizacional do programa.

Esta função me ajuda a apagar todos os objetos dos desenhos.
Aqui está o código em C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;




namespace funcoesadicionais

{
    public static class extensoes
    {

        static int analisaentrada(this Database db, Func<Entity, bool> f)
        {
            int count = 0;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                foreach (ObjectId btrId in bt)
                {
                    var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                    foreach (ObjectId entId in btr)
                    {
                        var ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
                        if (ent != null && f(ent))
                        {
                            count++;
                        }
                    }
                }
                tr.Commit();
            }
            return count;
        }


        public static int apagarcondicional(
          this Database db, Func<Entity, bool> f, bool countOnly = false
        )
        {
            return
              db.analisaentrada(
                e =>
                {
                    if (f(e))
                    {
                        if (!countOnly)
                        {
                            e.UpgradeOpen();
                            e.Erase();
                            e.DowngradeOpen();
                        }
                        return true;
                    }
                    return false;
                }
              );
        }

        public static double Comprimento(this Curve curva)
        {
            return curva.GetDistanceAtParameter(curva.EndParam);
        }

        public static bool ComprimentoZero(this Curve curva)
        {
            bool resultado = curva.Comprimento() < Tolerance.Global.EqualPoint;
            return resultado;
        }
    }

    public class commds
    {
        [CommandMethod("APAGA_COMP_ZERADO")]
        public void APAGA_COMP_ZERADO()
        {
            var documento = Application.DocumentManager.MdiActiveDocument;
            if (documento == null)
                return;
            var db = documento.Database;
            var ed = documento.Editor;

            var count = db.apagarcondicional(
              e =>
              {
                  if (e is Curve)
                      return ((Curve)e).ComprimentoZero();
                  return false;
              }
            );

            ed.WriteMessage("\n{0} entidades apagadas com sucesso!", count);
        }

        [CommandMethod("APAGA_COMP_ZERADO_ALTERNATIVO")]
        public void APAGA_COMP_ZERADO_ALTERNATIVO()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            if (doc == null)
                return;
            var db = doc.Database;
            var ed = doc.Editor;

            var count = db.apagarcondicional(
              e =>
              {
                  var cur = e as Curve;
                  if (cur != null && cur.ComprimentoZero())
                  {
                      e.UpgradeOpen();
                      e.Erase();
                      e.DowngradeOpen();

                      return true;
                  }
                  return false;
              }
            );

            ed.WriteMessage("\n{0} entidades apagadas com sucesso!", count);
        }
    }

}


Você pode comparar as implementações dos comandos funcionalmente de forma equivalente, APAGA_COMP_ZERADO e APAGA_COMP_ZERADO_ALTERNATIVO. Veja qual estilo você prefere.

Veja o vídeo do comando APAGA_COMP_ZERADO_ALTERNATIVO:


Projeto em Visual Studio 2019: Download

Comentários

  1. Penso que é possível fazer o mesmo usando Linq com uma única instrução.

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

Numeração Automática no AutoCAD

Sem dúvida esse é uma ferramenta única que fazia falta a tempos e foi introduzida recentemente no AutoCAD, na última década… Em 2013 tinha feito um programa para criar uma bolinhas de numeração automática usando o conceito de Leader eu fazia um controle dos números dos itens na mão mesmo, depois de um tempo resolvi fazer um menuzinho para controlar o conteúdo do número dos bullets, hoje isso não é mais necessário, existe um comando no próprio AutoCAD para isso e faz parte das Ferramentas Expressas do AutoCAD. Gosto de compartilhar ferramentas e dicas que tendem a ser menos conhecidas ou subutilizadas, mas ainda podem fornecer um impulso para sua produtividade e fluxo de trabalho e que eu mesmo me surpreendi quando as encontrei Hoje, quero apresentar outra ferramenta, a numeração automática. Como o nome indica, o comando Numeração automática permite que você adicione automaticamente um número às etiquetas ou texto em um desenho. Vou mostrar como a numeração automática pode ser usada par...

Alterar a cor de fundo do AutoCAD

Eu sou um adepto do fundo preto, tudo que eu posso mudo a cor do fundo para preto. Nas ultimas versões do AutoCAD tenho notado que não é mais o padrão o fundo preto absoluto, é um cinza escuro. As vezes gosto também de mudar a cor do Layout de branco para preto afinal de contas quando trabalhamos com penas e contraste no model space preto, ver um desenho no layout é impossível.  Você pode mudar sua cor de fundo do AutoCAD para a cor que quiser. Definindo cores personalizadas Primeiro, vá para o menu Opções (botão Aplicativo> Opções), selecione a guia Exibição e clique no botão Cores. Agora você deve ver a caixa de diálogo Cores da janela de desenho: Agora você pode atualizar as cores de qualquer elemento da interface. Isso incluí o plano de fundo em qualquer contexto (selecione Model e Layout). Você pode escolher qualquer uma das predefinições, ou você pode escolher a partir de todo o espectro (basta escolher a opção Selecionar Cor ...). Se você não gost...

Unindo blocos em AutoCAD utilizando .NET

Hoje me deparai com uma necessidade de unir blocos com propriedades então resolvi fazer um comando para realizar esses procedimento. A principio esse procedimento não é tão complexo de ser executado individualmente mas por outro lado gostaria também de analisar um pouco melhor as possibilidades de se manipular blocos utilizando o AutoCAD. Abaixo o código que utilizei: using Autodesk.AutoCAD.ApplicationServices ; using Autodesk.AutoCAD.DatabaseServices ; using Autodesk.AutoCAD.EditorInput ; using Autodesk.AutoCAD.Runtime ; using System.Linq ; // This line is not mandatory, but improves loading performances [assembly: CommandClass(typeof(Merging_AutoCAD_blocks.Comandos))] namespace Merging_AutoCAD_blocks { public class Comandos { /// <summary> /// Uni dois ou mais blocos em um unico bloco. /// </summary> [CommandMethod("MERGBLKS")] public static void UnindoBlocos () {...