.NET

.NET

Reply
Valued Contributor
Jean-Marc68
Posts: 94
Registered: ‎01-03-2007
Message 1 of 6 (668 Views)
Accepted Solution

Selecting text at insertion point of other text

668 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

 

Valued Mentor
gasty1001
Posts: 471
Registered: ‎04-11-2010
Message 2 of 6 (650 Views)

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

 

Valued Contributor
Jean-Marc68
Posts: 94
Registered: ‎01-03-2007
Message 3 of 6 (634 Views)

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.
 
Valued Contributor
Jean-Marc68
Posts: 94
Registered: ‎01-03-2007
Message 4 of 6 (629 Views)

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;
        }
    }
}

 

ADN Support Specialist
Balaji_Ram
Posts: 693
Registered: ‎03-21-2011
Message 5 of 6 (593 Views)

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

Valued Contributor
Jean-Marc68
Posts: 94
Registered: ‎01-03-2007
Message 6 of 6 (575 Views)

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.

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.