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...

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 () {...

Operando com Imagens Georreferenciadas no AutoCAD - Ortofotos

A coisa mais desagradável para quem trabalha com documentos em DWG com ortofotos ( fotos aéreas georreferenciadas) é quando se recebe o documento e a ortofoto não é carregada. Uma linha de transmissão onde a plotagem da estruturas é feita em um documento combinado de planta e perfil. Na área da planta é feito pela topografia um serviço de recorte e renderização das imagens em formato de ortofoto na região do desenho. Como a linha de transmissão a projeção é feita sempre linear na planta observando os vértices uma mesma ortofoto pode ser representada várias vezes numa mesma folha em um enjanelamento diferente. Tratamento de Ortofotos no AutoCAD - EXTERNALREFERENCES As ortofotos no AutoCAD são tratadas como referências a objetos externos. Isso é bom porque cada ortofoto pode ter de poucos kb até Gb de tamanho. Se for parte integrante do DWG poderia deixa-lo grande de mais para ser manipulado. Cada projeção no documento funciona como uma imagem projetada em um...