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
Solved! Go to Solution.
Solved by Balaji_Ram. Go to Solution.
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
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.
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 :
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; } } }
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.