Pular para o conteúdo principal

Destacando e Removendo Textos em Branco do AutoCAD usando .NET

       Estava aqui em casa sem conseguir dormir direito e resolvi pesquisar um pouco sobre o que está em voga ai no meandro do desenvolvimento para AutoCAD .NET, então dei uma lida nos últimos post's do Thougth the Interface e achei esse post sobre essa questão do texto vazio, veja.
     
       O post em si é uma resposta a um problema gerado exatamente por uma criação automática de textos que causava um problema que não era possível identificar mais os textos... Trata-se que ele tem um programa que gera diversos arquivos com textos aleatórios possivelmente alguma codificação com "_" e ele quer identificar todos os textos e remove-los.

       Deletar é relativamente fácil, trata-se de localizar os DBText e MText, para isso ele sugeriu utilizar o método IsApplicable() que eu mesmo nem conhecia ainda e ir checando dentro do conteúdo de cada texto se contém o tal caractere "_"  e depois deletar o dito cujo.


 sing Autodesk.AutoCAD.ApplicationServices;  
 using Autodesk.AutoCAD.DatabaseServices;  
 using Autodesk.AutoCAD.EditorInput;  
 using Autodesk.AutoCAD.Geometry;  
 using Autodesk.AutoCAD.GraphicsInterface;  
 using Autodesk.AutoCAD.Runtime;  
 using System;  
 using System.Text.RegularExpressions;  
 namespace DashedTextFinder  
 {  
  public class Commands  
  {     
   // Stores our global overrule instance  
   private static TextHighlightOverrule _tho = null;  
   [CommandMethod("EDT")]  
   public static void EraseDashedText()  
   {  
    var doc = Application.DocumentManager.MdiActiveDocument;  
    var ed = doc.Editor;  
    var db = doc.Database;  
    var count = 0;  
    // In case the SDT command hasn't been run, we need to create  
    // our custom overrule object  
    if (_tho == null)  
     _tho = new TextHighlightOverrule();  
    using (var tr = doc.TransactionManager.StartTransaction())  
    {  
     // Let's iterate through the BlockTable, erasing the  
     // relevant entities from the various BlockTableRecords  
     var bt =  
      (BlockTable)tr.GetObject(  
       db.BlockTableId, OpenMode.ForRead  
      );  
     foreach (var btrId in bt)  
     {  
      var btr =  
       (BlockTableRecord)tr.GetObject(  
        btrId, OpenMode.ForRead  
       );  
      foreach (var entId in btr)  
      {  
       // Also open erased objects, although we won't process  
       // them, of course  
       var ent =  
        (Entity)tr.GetObject(entId, OpenMode.ForRead, true);  
       if (!ent.IsErased)  
       {  
        // If the entity is a BlockReference, check its  
        // AttributeReferences, otherwise just check the  
        // entity itself using our overrule object  
        if (ent is BlockReference)  
        {  
         var br = (BlockReference)ent;  
         foreach (var aId in br.AttributeCollection)  
         {  
          var ar =  
           (AttributeReference)tr.GetObject(  
            (ObjectId)aId, OpenMode.ForRead, true  
           );  
          if (!ar.IsErased && _tho.IsApplicable(ar))  
          {  
           ar.UpgradeOpen();  
           ar.Erase();  
           count++;  
          }  
         }  
        }  
        else if (_tho.IsApplicable(ent))  
        {  
         ent.UpgradeOpen();  
         ent.Erase();  
         count++;  
        }  
       }  
      }  
     }  
     tr.Commit();  
    }  
    // As we've erased all "problematic" entities, we might also  
    // remove the overrule...  
    //_tho.Remove();  
    //_tho.Dispose();  
    //_tho = null;  
    ed.WriteMessage(  
     "\nErased {0} blank or dashed text entit{1}.",  
     count, count == 1 ? "y" : "ies"  
    );  
   }  
   // Highlights the dashed text objects in the drawing  
   [CommandMethod("HDT")]  
   public static void HighlightDashedText()  
   {  
    var doc = Application.DocumentManager.MdiActiveDocument;  
    if (_tho == null)  
     _tho = new TextHighlightOverrule();  
    short newCol = UpdateHighlightOverrule(doc, _tho);  
    if (newCol < 0)  
    {  
     _tho.Dispose();  
     _tho = null;  
    }  
    else  
     _tho.HighlightColor = newCol;  
   }  
   // A helper function which applies our highlight overrule  
   // to different types, adjusting the color index used  
   private static short UpdateHighlightOverrule(  
    Document doc, HighlightOverrule ho  
   )  
   {  
    // Ask the user for the new color index to use  
    var opts =  
     new PromptIntegerOptions("\nEnter highlight color index: ");  
    opts.LowerLimit = 0;  
    opts.UpperLimit = 127;  
    opts.Keywords.Add("Clear");  
    opts.DefaultValue = ho.HighlightColor;  
    var res = doc.Editor.GetInteger(opts);  
    if (res.Status == PromptStatus.Keyword)  
    {  
     // If the Clear keyword was entered, let's remove the  
     // overrule  
     if (res.StringResult == "Clear")  
     {  
      ho.Remove();  
      doc.Editor.Regen();  
      return -1;  
     }  
    }  
    else if (res.Status == PromptStatus.OK)  
    {  
     // Otherwise we attach the overrule for each type  
     ho.Add();  
     // If requested highlight color is a new color, then we  
     // want to change it  
     if (ho.HighlightColor != res.Value)  
      ho.HighlightColor = (short)res.Value;  
     doc.Editor.Regen();  
    }  
    return (short)res.Value;  
   }  
  }  
  // Custom base class with a highlight text property  
  public class HighlightOverrule : DrawableOverrule  
  {  
   private Type[] _types;  
   public HighlightOverrule(short col = 1, Type[] entTypes = null)  
   {  
    _types = entTypes;  
    _color = col;  
   }  
   // Color index used to highlight  
   private short _color;  
   // The color we highlight blocks with  
   public short HighlightColor  
   {  
    get { return _color; }  
    set  
    {  
     if ((value >= 0) && (value <= 127))  
     {  
      _color = value;  
     }  
    }  
   }  
   public void Add()  
   {  
    // Call Overrule.Remove for each of the passed-in types  
    foreach (Type t in _types)  
    {  
     // Use try-catch, as Overrule.HasOverrule() needs an  
     // instance of an AutoCAD object, and we just have the  
     // type  
     try  
     {  
      Overrule.AddOverrule(RXObject.GetClass(t), this, false);  
     }  
     catch  
     { }  
    }  
   }  
   public void Remove()  
   {  
    // Call Overrule.Remove for each of the passed-in types  
    foreach (Type t in _types)  
    {  
     // Use try-catch, as Overrule.HasOverrule() needs an  
     // instance of an AutoCAD object, and we just have the  
     // type  
     try  
     {  
      Overrule.RemoveOverrule(RXObject.GetClass(t), this);  
     }  
     catch  
     { }  
    }  
   }  
  }  
  // Overrule to highlight text (MText and DBText) objects  
  public class TextHighlightOverrule : HighlightOverrule  
  {  
   public TextHighlightOverrule(short col = 1, Type[] types = null)  
    : base(  
      col,  
      types == null ?  
       new Type[] { typeof(DBText), typeof(MText) } : types  
    )  
   {  
    SetCustomFilter();  
   }  
   public override bool WorldDraw(Drawable drawable, WorldDraw wd)  
   {  
    // Registered for MText and DBText, so proceed cautiously  
    var ent = drawable as Entity;  
    if (ent != null)  
    {  
     var mt = ent as MText;  
     var dt = ent as DBText;  
     if (mt != null || dt != null)  
     {  
      var norm = (mt == null ? dt.Normal : mt.Normal);  
      // Now we want to draw a box around the extents  
      var ext = ent.Bounds;  
      if (ext.HasValue)  
      {  
       var maxPt = ext.Value.MaxPoint;  
       var minPt = ext.Value.MinPoint;  
       // These are the vertices of the highlight box  
       // (it also contains a cross, for fun)  
       var pts =  
        new Point3dCollection(  
         new Point3d[]  
         {  
          new Point3d(minPt.X, minPt.Y, minPt.Z),  
          new Point3d(maxPt.X, maxPt.Y, maxPt.Z)  
         }  
        );  
       // Store old graphics color and lineweight  
       short oldColor = wd.SubEntityTraits.Color;  
       wd.SubEntityTraits.Color = this.HighlightColor;  
       var oldLineweight = wd.SubEntityTraits.LineWeight;  
       wd.SubEntityTraits.LineWeight = LineWeight.LineWeight070;  
       // Draw the polyline  
       wd.Geometry.Polyline(pts, norm, IntPtr.Zero);  
       // Restore old settings  
       wd.SubEntityTraits.LineWeight = oldLineweight;  
       wd.SubEntityTraits.Color = oldColor;  
      }  
     }  
    }  
    // Let the overruled Drawable draw itself  
    return base.WorldDraw(drawable, wd);  
   }  
   public override bool IsApplicable(RXObject overruledSubject)  
   {  
    // Extract the string we need to check from the types  
    // of entity this overrule works on (DBText & MText)  
    var stringToCheck = "";  
    var dt = overruledSubject as DBText;  
    if (dt != null)  
    {  
     stringToCheck = dt.TextString;  
    }  
    var mt = overruledSubject as MText;  
    if (mt != null)  
    {  
     stringToCheck = mt.Text;  
    }  
    return IsDashedOrWhitespace(stringToCheck);  
   }  
   private static bool IsDashedOrWhitespace(string text)  
   {  
    if (String.IsNullOrEmpty(text))  
     return false;  
    // Use a simple Regular Expression to check whether  
    // the string passed in consists only of spaces and/or  
    // underlines  
    return  
     Regex.Match(  
      text, "^[ _]+$", RegexOptions.IgnoreCase  
     ).Success;  
   }  
  }  
 }  

O código é copiado mesmo do original é bem útil, pode ser adaptado para outras aplicações como remover os textos vazios gerados pelo PLS-CADD e fazer coisas adicionais como reposicionamento de texto.

Comentários

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