• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Valued Contributor
    Posts: 94
    Registered: ‎01-03-2007
    Accepted Solution

    Selecting text at insertion point of other text

    261 Views, 5 Replies
    12-03-2012 01:49 PM

    Hello,

     

    I need to create a little application (Not the firt one in .NET but my first one for Autocad in C# .NET).

     

    What do I need to do ?

    User select texts on screen. => Making a SelectionSet of those selected texts. DONE

    Foreach select text is on screen another text (on another layer) with the same coordinates.

    Here is my trouble. 

    Foreach text in the first SelectionSet, I try to create a second SelectionSet (filtered to select text only, named acPSResPCode) but that SelectionSet stay always null.

    If I make the SelectionSet without filter I select every lines in the crossingwindows, but no text are selected.

     

    How do I need to do ?

     

    Here's my code (PS : Code for AcadMp 2010)

     

    [CommandMethod("SelectionPP")]
            public void SelectionPP()
            {
                //Récupère le document courant, sa base de données, et demarre une transaction
                Document acDoc = Application.DocumentManager.MdiActiveDocument;
                Database acCurDb = acDoc.Database;
    
                //Récupération de l'éditeur de la base de données courante
                Editor ed = acDoc.Editor;
    
                //Démarre une nouvelle transaction
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    //Création d'un filtre pour récupérer uniquement les textes
                    TypedValue[] acFilList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "TEXT") };
                    SelectionFilter acFilter = new SelectionFilter(acFilList);
                    PromptSelectionOptions acPSOpts = new PromptSelectionOptions();
                    acPSOpts.MessageForAdding = "Cliquez les PP";
                    PromptSelectionResult acPSResPP = ed.GetSelection(acPSOpts, acFilter);
    
                    //Si la sélection a réussi
                    if (acPSResPP.Status == PromptStatus.OK)
                    {
                        SelectionSet acSSetPP = acPSResPP.Value;
                        ObjectId[] acIdsPP = acSSetPP.GetObjectIds();
                        for (int i = 0; i < acIdsPP.Length; i++)
                        {
                            //Récupération de l'objet texte saisi
                            DBText acTextPP = (DBText)acTrans.GetObject(acIdsPP[i], OpenMode.ForRead);
                            //Récupération des coordonnées du Texte saisi
                            Point3d acPoint3DPP = acTextPP.Position;
                            StringBuilder sb = new StringBuilder();
                            //Création d'un point inférieur gauche
                            Point3d acPt1 = new Point3d(acPoint3DPP.X - 0.0001, acPoint3DPP.Y - 0.0001, 0.0);
                            //Création d'un point supérieur droit
                            Point3d acPt2 = new Point3d(acPoint3DPP.X + 0.0001, acPoint3DPP.Y + 0.0001, 0.0);
                            //Sélection de tous les textes dans le rectangle formé par les 2 points
                            PromptSelectionResult acPSResPCode = ed.SelectCrossingWindow(acPt1, acPt2, acFilter);
                             //Si la sélection a réussi
                            if (acPSResPCode.Status == PromptStatus.OK)
                            {
                                SelectionSet acSSetPCodes = acPSResPCode.Value;
                                ObjectId[] acIdsPCodes = acSSetPCodes.GetObjectIds();
                                sb = new StringBuilder();
                                sb.AppendFormat("{0} éléments sélectionnés", acSSetPCodes.Count);
                                Application.ShowAlertDialog(sb.ToString());
                                for (int j = 0; j < acIdsPCodes.Length; j++)
                                {
                                    DBText acTextPCode = null;
                                    acTextPCode = (DBText)acTrans.GetObject(acIdsPCodes[i], OpenMode.ForRead);
                                    sb = new StringBuilder();
                                    sb.AppendFormat("{3}{2}Id : {0}{2}Id sélectionné : {1}", acTextPP.ObjectId, acTextPCode.ObjectId, Environment.NewLine,i);
                                    Application.ShowAlertDialog(sb.ToString());
                                    if (acTextPCode.ObjectId != acTextPP.ObjectId)
                                    {
                                        int intPCode = 0;
                                        if (int.TryParse(acTextPCode.TextString, out intPCode))
                                        {
                                            PP newPP = new PP(acTextPP.TextString, intPCode, acPoint3DPP.X, acPoint3DPP.Y, acPoint3DPP.Z);
                                            sb = new StringBuilder();
                                            sb.AppendFormat("PP : {0}   PCode : {1}{5}Coord : {2},{3},{4}{5}", newPP.NoPP, newPP.PCode, newPP.X, newPP.Y, newPP.Z, Environment.NewLine);
                                            Application.ShowAlertDialog(sb.ToString());
                                        }
                                    }
                                }
                            }
                            else
                            {
                                sb.AppendFormat("Aucun texte trouvé pour le point {0}{2}PromptStatus = {1}", acTextPP.TextString, acPSResPCode.Status, Environment.NewLine);
                                Application.ShowAlertDialog(sb.ToString());
                            }
    
                        }
                    }
                }
            }

     Thanks for your advices,

    Jean-Marc

     

    Please use plain text.
    Mentor
    Posts: 214
    Registered: ‎04-11-2010

    Re: Selecting text at insertion point of other text

    12-03-2012 06:35 PM in reply to: Jean-Marc68

    Hi,

     

    I'm not sure what are you trying to find, but this crude code may help:

     

    private SelectionSet  GetTxtByPosition(Point3d p1, Point3d p2, Point3d txtInsPoint, editor ed)
    {
    	PromptSelectionResult ws = default(PromptSelectionResult);
    	TypedValue[] acTypValAr = new TypedValue[4];
                    SelectionSet wss;
    
    	acTypValAr.SetValue(new TypedValue(DxfCode.Start, "TEXT"), 0);
    	acTypValAr.SetValue(new TypedValue(DxfCode.XCoordinate, txtInsPoint.X), 1);
    	acTypValAr.SetValue(new TypedValue(DxfCode.YCoordinate, txtInsPoint.Y), 2);
    	acTypValAr.SetValue(new TypedValue(DxfCode.ZCoordinate, txtInsPoint.Z), 3);
    
    	SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
    	ws = ed.SelectCrossingWindow(p1, p2, acSelFtr);
    	if (ws.Status == PromptStatus.OK) {
    		wss=ws.Value;
    	}
          return wss;
    }

     It takes 3 points 2 for the crossing window and one for the insertion point of the text , it should return a selection set with the text inserted at that point if any, a null ss if there is no text with that conditions.

     

    Gaston Nunez

     

    Please use plain text.
    Valued Contributor
    Posts: 94
    Registered: ‎01-03-2007

    Re: Selecting text at insertion point of other text

    12-04-2012 06:50 AM in reply to: gasty1001

    Thanks for your answer gasty1001.

     

    What do I try to do ?

     

    I made an sample image. You see 2 text and a block (the cross is a block). Horizontaly is the PP number ans with a 30 degree angle is the PCode.

     

    PP.jpg

     

    A user select PPs in a SelectionSet (that part works)

    For each PP (single line text), I extraxt its insertion point as Point3d.

    I need now find all texts a that position.

    I already tried to create a filter to select only text at that position by the same way as you.

    But I used ed.SelectAll(FILTER);

    With my code and with yours, I receive that error :

    System.NullReferenceException: Object reference not set to an instance of an object.
       at Autodesk.AutoCAD.DatabaseServices.ResultBuffer.TypedValueToResbuf(TypedValue value)
       at Autodesk.AutoCAD.DatabaseServices.ResultBuffer.TypedValuesToResbuf(TypedValue[] values)
       at Autodesk.AutoCAD.DatabaseServices.ResultBuffer..ctor(TypedValue[] values)
       at Autodesk.AutoCAD.EditorInput.FilterExtractor.{ctor}(FilterExtractor* , SelectionFilter filter)
       at Autodesk.AutoCAD.EditorInput.Editor.SelectCrossingWindow(Point3d pt1, Point3d pt2, SelectionFilter filter, Boolean forceSubEntitySelection)
       at Autodesk.AutoCAD.EditorInput.Editor.SelectCrossingWindow(Point3d pt1, Point3d pt2, SelectionFilter filter)
       at Acad2010SaisiePP.Class1.GetTxtByPosition(Point3d p1, Point3d p2, Point3d txtInsPoint, Editor ed) in D:\Visual Studio 2010\Projects\Acad2010SaisiePP\Acad2010SaisiePP\Class1.cs:line 207
       at Acad2010SaisiePP.Class1.SelectionPP() in D:\Visual Studio 2010\Projects\Acad2010SaisiePP\Acad2010SaisiePP\Class1.cs:line 140
       at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
       at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
       at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
       at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()
     
    That error provide from setting coordinates in the filter. 
    If I use filter with only selecting TEXT I have no error. Of course if I use ed.SelectAll(FILTER); It select every text in the drawing. But if I use ed.SelectCrossingWindow(p1, p2, FILTER); selectionSet stay null.
     
    I really don't undersant why.
     
    Please use plain text.
    Valued Contributor
    Posts: 94
    Registered: ‎01-03-2007

    Re: Selecting text at insertion point of other text

    12-04-2012 07:11 AM in reply to: Jean-Marc68

    I forgot to specify line 207 is ws = ed.SelectCrossingWindow(p1, p2, acSelFtr);

    and line 140 is SelectionSet acSSetPCodes = GetTxtByPosition(acPt1, acPt2, acPoint3DPP, ed);

     

    in that code

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using Autodesk.AutoCAD.Runtime;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    
    using Autodesk.AutoCAD.EditorInput;
    using Autodesk.AutoCAD.Geometry;
    
    [assembly: CommandClass(typeof(Acad2010SaisiePP.Class1))]
    
    namespace Acad2010SaisiePP
    {
        public class Class1
        {
            [CommandMethod("AdskGreeting")]
            public void AdskGreeting()
            {
                //Récupère le document courant, sa base de données, et demarre une transaction
                Document acDoc = Application.DocumentManager.MdiActiveDocument;
                Database acCurDb = acDoc.Database;
    
                //Démarre une nouvelle transaction
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    //Ouvre le Block table record pour lecture
                    BlockTable acBlkTbl;
                    acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
    
                    //Ouvre le Model pour écriture
                    BlockTableRecord acBlkTblRec;
                    acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],OpenMode.ForWrite) as BlockTableRecord;
    
                    //Crée un nouvel objet MText et assigne sa position, sa valeur et son textStyle
                    MText objText = new MText();
    
                    //Crée les propriété par défaut de l'objet MText
                    objText.SetDatabaseDefaults();
                    objText.Contents = "Hello World";
                    objText.Location = new Autodesk.AutoCAD.Geometry.Point3d(2,2,0);
                    objText.TextStyleId = acCurDb.Textstyle;
                    
                    //Ajoute l'objet au Model space
                    acBlkTblRec.AppendEntity(objText);
    
                    //Ajoute l'objet à la transaction active
                    acTrans.AddNewlyCreatedDBObject(objText, true);
    
                    //Sauvegarde les changementes et ferme la transaction
                    acTrans.Commit();
    
                }
            }
    
            [CommandMethod("SelectionPP")]
            public void SelectionPP()
            {
                //Récupère le document courant, sa base de données, et demarre une transaction
                Document acDoc = Application.DocumentManager.MdiActiveDocument;
                Database acCurDb = acDoc.Database;
    
                //Récupération de l'éditeur de la base de données courante
                Editor ed = acDoc.Editor;
    
                //Démarre une nouvelle transaction
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    //Création d'un filtre pour récupérer uniquement les textes
                    TypedValue[] acFilList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "TEXT") };
                    SelectionFilter acFilter = new SelectionFilter(acFilList);
                    PromptSelectionOptions acPSOpts = new PromptSelectionOptions();
                    acPSOpts.MessageForAdding = "Cliquez les PP";
                    //Sélection des textes
                    PromptSelectionResult acPSResPP = ed.GetSelection(acPSOpts, acFilter);
    
                    //Si la sélection a réussi
                    if (acPSResPP.Status == PromptStatus.OK)
                    {
                        SelectionSet acSSetPP = acPSResPP.Value;
                        ObjectId[] acIdsPP = acSSetPP.GetObjectIds();
                        for (int i = 0; i < acIdsPP.Length; i++)
                        {
                            //Récupération de l'objet texte saisi
                            DBText acTextPP = (DBText)acTrans.GetObject(acIdsPP[i], OpenMode.ForRead);
                            //Récupération des coordonnées du Texte saisi
                            Point3d acPoint3DPP = acTextPP.Position;
                            StringBuilder sb = new StringBuilder();
                            //Création d'un point inférieur gauche
                            Point3d acPt1 = new Point3d(acPoint3DPP.X - 0.0001, acPoint3DPP.Y - 0.0001, 0.0);
                            //Création d'un point supérieur droit
                            Point3d acPt2 = new Point3d(acPoint3DPP.X + 0.0001, acPoint3DPP.Y + 0.0001, 0.0);
                            //Sélection de tous les textes dans le rectangle formé par les 2 points
    /*                        //Sélection du PCode
                            //Création d'un filtre pour récupérer les textes à une coord 2d
                            TypedValue[] acFilPCodeList = new TypedValue[4];
                            acFilPCodeList.SetValue(new TypedValue((int)DxfCode.Start, "TEXT"), 0);
                            acFilPCodeList.SetValue(new TypedValue((int)DxfCode.XCoordinate, acPoint3DPP.X), 1);
                            acFilPCodeList.SetValue(new TypedValue((int)DxfCode.YCoordinate, acPoint3DPP.Y), 2);
                            acFilPCodeList.SetValue(new TypedValue((int)DxfCode.ZCoordinate, acPoint3DPP.Z), 3);
    
                            SelectionFilter acPCodeFilter = new SelectionFilter(acFilPCodeList);
                            PromptSelectionResult acPSResPCode = ed.SelectCrossingWindow(acPt1, acPt2, acPCodeFilter);
                            //Si la sélection a réussi
                            if (acPSResPCode.Status == PromptStatus.OK)
                            {
                                SelectionSet acSSetPCodes = acPSResPCode.Value;
                                ObjectId[] acIdsPCodes = acSSetPCodes.GetObjectIds();
                                sb = new StringBuilder();
                                sb.AppendFormat("{0} éléments sélectionnés", acSSetPCodes.Count);
                                Application.ShowAlertDialog(sb.ToString());
                                for (int j = 0; j < acIdsPCodes.Length; j++)
                                {
                                    DBText acTextPCode = null;
                                    acTextPCode = (DBText)acTrans.GetObject(acIdsPCodes[i], OpenMode.ForRead);
                                    sb = new StringBuilder();
                                    sb.AppendFormat("{3}{2}Id : {0}{2}Id sélectionné : {1}", acTextPP.ObjectId, acTextPCode.ObjectId, Environment.NewLine, i);
                                    Application.ShowAlertDialog(sb.ToString());
                                    if (acTextPCode.ObjectId != acTextPP.ObjectId)
                                    {
                                        int intPCode = 0;
                                        if (int.TryParse(acTextPCode.TextString, out intPCode))
                                        {
                                            PP newPP = new PP(acTextPP.TextString, intPCode, acPoint3DPP.X, acPoint3DPP.Y, acPoint3DPP.Z);
                                            sb = new StringBuilder();
                                            sb.AppendFormat("PP : {0}   PCode : {1}{5}Coord : {2},{3},{4}{5}", newPP.NoPP, newPP.PCode, newPP.X, newPP.Y, newPP.Z, Environment.NewLine);
                                            Application.ShowAlertDialog(sb.ToString());
                                        }
                                    }
                                }
                            }
                            else
                            {
                                sb.AppendFormat("Aucun texte trouvé pour le point {0}{2}PromptStatus = {1}", acTextPP.TextString, acPSResPCode.Status, Environment.NewLine);
                                Application.ShowAlertDialog(sb.ToString());
                            }
                            */
                            SelectionSet acSSetPCodes = GetTxtByPosition(acPt1, acPt2, acPoint3DPP, ed);
                            if (acSSetPCodes != null)
                            {
                                ObjectId[] acIdsPCodes = acSSetPCodes.GetObjectIds();
                                sb = new StringBuilder();
                                sb.AppendFormat("{0} éléments sélectionnés", acSSetPCodes.Count);
                                Application.ShowAlertDialog(sb.ToString());
                                for (int j = 0; j < acIdsPCodes.Length; j++)
                                {
                                    DBText acTextPCode = null;
                                    acTextPCode = (DBText)acTrans.GetObject(acIdsPCodes[i], OpenMode.ForRead);
                                    sb = new StringBuilder();
                                    sb.AppendFormat("{3}{2}Id : {0}{2}Id sélectionné : {1}", acTextPP.ObjectId, acTextPCode.ObjectId, Environment.NewLine, i);
                                    Application.ShowAlertDialog(sb.ToString());
                                    if (acTextPCode.ObjectId != acTextPP.ObjectId)
                                    {
                                        int intPCode = 0;
                                        if (int.TryParse(acTextPCode.TextString, out intPCode))
                                        {
                                            PP newPP = new PP(acTextPP.TextString, intPCode, acPoint3DPP.X, acPoint3DPP.Y, acPoint3DPP.Z);
                                            sb = new StringBuilder();
                                            sb.AppendFormat("PP : {0}   PCode : {1}{5}Coord : {2},{3},{4}{5}", newPP.NoPP, newPP.PCode, newPP.X, newPP.Y, newPP.Z, Environment.NewLine);
                                            Application.ShowAlertDialog(sb.ToString());
                                        }
                                    }
                                }
                            }
                            else
                            {
                                sb.AppendFormat("Aucun texte trouvé pour le point {0}", acTextPP.TextString);
                                Application.ShowAlertDialog(sb.ToString());
                            }
    
    
                        }
                    }
                }
            }
    
     /*       private SelectionSet GetTxtByPosition(Point3d p1, Point3d p2, Point3d txtInsPoint, Editor ed)
            {
                PromptSelectionResult ws = default(PromptSelectionResult);
                TypedValue[] acTypValAr = new TypedValue[4];
    
                acTypValAr.SetValue(new TypedValue((int)DxfCode.Start, "TEXT"), 0);
                acTypValAr.SetValue(new TypedValue((int)DxfCode.XCoordinate, txtInsPoint.X), 1);
                acTypValAr.SetValue(new TypedValue((int)DxfCode.YCoordinate, txtInsPoint.Y), 2);
                acTypValAr.SetValue(new TypedValue((int)DxfCode.ZCoordinate, txtInsPoint.Z), 3);
    
                SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
                ws = ed.SelectAll(acSelFtr);
                if (ws.Status == PromptStatus.OK)
                {
                    return ws.Value;
                }
                return null;
            }*/
            private SelectionSet GetTxtByPosition(Point3d p1, Point3d p2, Point3d txtInsPoint, Editor ed)
            {
                PromptSelectionResult ws = default(PromptSelectionResult);
                TypedValue[] acTypValAr = new TypedValue[4];
                acTypValAr.SetValue(new TypedValue((int)DxfCode.Start, "TEXT"), 0);
                acTypValAr.SetValue(new TypedValue((int)DxfCode.XCoordinate, txtInsPoint.X), 1);
                acTypValAr.SetValue(new TypedValue((int)DxfCode.YCoordinate, txtInsPoint.Y), 2);
                acTypValAr.SetValue(new TypedValue((int)DxfCode.ZCoordinate, txtInsPoint.Z), 3);
    
                SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
                ws = ed.SelectCrossingWindow(p1, p2, acSelFtr);
                if (ws.Status == PromptStatus.OK)
                {
                    return ws.Value;
                }
                return null;
            }
        }
    
        public class PP
        {
            public string NoPP { get; set; }
            public int PCode { get; set; }
            public double X { get; set; }
            public double Y { get; set; }
            public double Z { get; set; }
            public PP(string noPP, int pCode, double x, double y, double z)
            {
                NoPP = noPP;
                PCode = pCode;
                X = x;
                Y = y;
                z = Z;
            }
        }
    }

     

    Please use plain text.
    ADN Support Specialist
    Balaji_Ram
    Posts: 345
    Registered: ‎03-21-2011

    Re: Selecting text at insertion point of other text

    12-10-2012 04:04 PM in reply to: Jean-Marc68

    Hello Jean-Marc,

     

    I tried your code sample with a few changes and it worked ok.

     

    1) Using ArxDbg snoop tool, we can find that the DXF codes for text entity contains the insertion point as the group code 10. So to provide the insertion point as a filter, I changed the "GetTextByPosition" as :

     

            private SelectionSet GetTxtByPosition(Point3d p1, Point3d p2, Point3d txtInsPoint, Editor ed)
            {
                PromptSelectionResult ws = default(PromptSelectionResult);
                TypedValue[] acTypValAr = new TypedValue[2];
                acTypValAr.SetValue(new TypedValue((int)DxfCode.Start, "TEXT"), 0);
                acTypValAr.SetValue(new TypedValue(10, txtInsPoint), 1);
              
                SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
                //ws = ed.SelectCrossingWindow(p1, p2, acSelFtr);
                ws = ed.SelectAll(acSelFtr);
                if (ws.Status == PromptStatus.OK)
                {
                    return ws.Value;
                }
                return null;
            }

    "SelectAll" instead of "SelectCrossingWindow" is being used in this case as we have already specified the insertion point of the text as a selection filter.

     

    2) This may be a typo while you copied the code, but just wanted to ensure that is the case.

    In the constructor of class PP, it should be "Z = z" instead of "z = Z"

     

    Hope this helps.

     

     

     

     

     

     

     



    Balaji
    Developer Technical Services
    Autodesk Developer Network

    Please use plain text.
    Valued Contributor
    Posts: 94
    Registered: ‎01-03-2007

    Re: Selecting text at insertion point of other text

    12-11-2012 07:13 AM in reply to: Balaji_Ram

    It works perfectly. Thanks Balaji_Ram.

    Please use plain text.