Pular para o conteúdo principal

Movendo uma SETA no AutoCAD com texto pré-inserido.

Esses dias comecei a trabalhar em um projeto novo que envolve a inserção de setas com informações no desenho. Buscando um pouco me deparei com esse artigo do Kean Walmsley de como posicionar uma seta com o texto pré-inserido.


Isso realmente é um problema, quem usa essa ferramenta de seta (que no meu trabalho é uma raridade, setas são feitas para serem explodidas!) sabe que é dramático você escolhe uma posição para a seta e o ponto de inflexão depois escreve o texto, finalmente você nota que ficou ruim e é obrigado a editar a posição.

O truque é usar o MLeader a partir de um EntityJig.  Primeiro passo usado pelo Kean foi tornar o MLeader seja database-resident para ser acionado - uma técnica que é bastante comum ao movimentar sólidos ou blocos com atributos  (sem perder as informações contidas nele). O MText aparece no início do líder e, em seguida, o líder é exibido da origem até movermos o mouse para iniciar o ciclo Sampler/Update no jig.

Segue o código em C#:

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


namespace AtuoCADNetBlog_Ex240420
{
    public class myLeader
    {
        class DirectionalLeaderJig : EntityJig
        {
            private Point3d _start, _end;
            private string _contents;
            private int _index;
            private int _lineIndex;

            private bool _started;
            public DirectionalLeaderJig(string txt, Point3d start, MLeader ld) : base(ld)
            {
                // Store info that's passed in, but don't init the MLeader
                _contents = txt;
                _start = start;
                _end = start;
                _started = false;

            }


            // A fairly standard Sampler function
            protected override SamplerStatus Sampler(JigPrompts prompts)
            {
                var po = new JigPromptPointOptions();

                po.UserInputControls = (UserInputControls.Accept3dCoordinates |
               UserInputControls.NoNegativeResponseAccepted);

                po.Message = "\nEnd point";
                var res = prompts.AcquirePoint(po);
                if (_end == res.Value)
                {
                    return SamplerStatus.NoChange;
                }

                else if (res.Status == PromptStatus.OK)
                {
                    _end = res.Value;
                    return SamplerStatus.OK;
                }

                return SamplerStatus.Cancel;
            }



            protected override bool Update()
            {
                var ml = (MLeader)Entity;
                if (!_started)
                {
                    if (_start.DistanceTo(_end) > Tolerance.Global.EqualPoint)
                    {
                        // When the jig actually starts - and we have mouse movement -
                        // we create the MText and init the MLeader
                        ml.ContentType = ContentType.MTextContent;

                        var mt = new MText();

                        mt.Contents = _contents;

                        ml.MText = mt;
                        // Create the MLeader cluster and add a line to it
                        _index = ml.AddLeader();

                        _lineIndex = ml.AddLeaderLine(_index);
                        // Set the vertices on the line
                        ml.AddFirstVertex(_lineIndex, _start);

                        ml.AddLastVertex(_lineIndex, _end);
                        // Make sure we don't do this again
                        _started = true;
                    }
                }
                else
                {
                    // We only make the MLeader visible on the second time through

                    // (this also helps avoid some strange geometry flicker)
                    ml.Visible = true;
                    // We already have a line, so just set its last vertex
                    ml.SetLastVertex(_lineIndex, _end);
                }
                if (_started)
                {
                    // Set the direction of the text to depend on the X of the end-point

                    // (i.e. is if to the left or right of the start-point?)
                    var dl = new Vector3d((_end.X >= _start.X ? 1 : -1), 0, 0);

                    ml.SetDogleg(_index, dl);
                }
                return true;
            }
        }

        [CommandMethod("LEADER2")]
        public void myleadercommand()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            
            // Pede ao usuário para inserir o texto 
            PromptStringOptions promptso = new PromptStringOptions("\nEntre com o Texto:");
            promptso.AllowSpaces = true;
            
            //Caso queira manter um texto vazio pára isnerir e pré-visualizar
            promptso.DefaultValue = "TEXTO";


            PromptResult pResult = ed.GetString(promptso);
            
            //Trata o caso que o usuário não entrou com valor ou entrou com um valor inválido
            if (pResult.Status != PromptStatus.OK)
                return;

            //Pede para o usuário entrar com o ponto da seta.
            PromptPointResult ppResult = ed.GetPoint("\nSelecione o ponto inicial da seta");

            //Trata o erro de seleção do ponto
            if (ppResult.Status != PromptStatus.OK)
                return;

            // Para manipular os objetos tipo db-resident é necessário usar a transaction
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false);

                // Criando e passando as informações através de um objeto MLEADER
                //existe outras formas de fazer mas desse jeito a seta nao fica com a tela psicando e não tem risco do usuário
                //acabar clicando em algum lugar e dando um fatality no AutoCAD.
                MLeader mymleader = new MLeader();
                
                //deixa invesivel
                mymleader.Visible = false;
                
                // Criando o jig
                var jig = new DirectionalLeaderJig(pResult.StringResult, ppResult.Value, mymleader);

                // Inclui o objeto já com a posição definida no desenho
                btr.AppendEntity(mymleader);

                tr.AddNewlyCreatedDBObject(mymleader, true);

                // Insere o objeto na tela.
                PromptResult pJigResult = ed.Drag(jig);

                // If all is well, commit
                if (pJigResult.Status == PromptStatus.OK)
                {
                    tr.Commit();                    
                }
                else
                {
                    ed.WriteMessage("Ocorreu um erro na criação da seta, tente novamente.");
                }

            }

        }
  
    }
}

Esse código tem muita aplicação, quem quiser só utilizar já está até compilado, abaixo está a solução do projeto para quem quiser compilar também

Download

Espero ter ajudado mais alguém, até o próximo!

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 gosta ai

Trabalhando mais rápido utilizando Express Tools

Se você não está usando o AutoCAD Express Tools, está perdendo tempo. O Express Tools é uma coleção de pequenas ferramentas de aprimoramento de produtividade que são instaladas com o AutoCAD. Eles são criadas usando as APIs do AutoCAD, como o AutoLISP, e, portanto, não estão disponíveis no AutoCAD LT também (aquela versão baratinha do AutoCAD). Aqui algumas possibilidades do Express Tools Nossa jornada começa com a barra de menus do estilo antigo. Ative-o com o comando MENUBAR e no estado 1. Clique em Express no lado direito e ele será expandido para mostrar mais de 10 categorias de ferramentas. Ainda fui mais longe e nos submenus consegui contar mais de 60 outros comandos. Ferramentas para blocos Existe dentro do Express Tools ferramentas específicas para blocos. vamos a algumas: Copy Nernest Objects - com essa ferramente você pode copiar objetos de dentro de um bloco para fora sem precisar explodir o bloco. Export Atribute Information - Você pode ain