Aller au contenu

Selection de blocs par attributs en .net (C#)


KSJ77

Messages recommandés

Bonjour,

Je voudrais savoir comment complèter/modifier (si c'est possible) ce code avec un fitre supplémentaire afin de pouvoir par exemple selectionner que les blocs ayant l'attribut "TOTO" (peu importe sa valeur)

 

TypedValue[] filter = new TypedValue[2] { new TypedValue(0, "INSERT"), new TypedValue(66, 1) };
           PromptSelectionResult psr = _ed.GetSelection(new SelectionFilter(filter));
           if (psr.Status != PromptStatus.OK) return;

 

Merci d'avance

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Il n'y a pas moyen de filtrer directement par attribut (que ce soit valeur ou étiquette).

Il faut donc ouvrir le bloc et parcourir les attributs. Ceci peut se faire a posteriori une fois la sélection faite ou pendant la sélection en utilisant l’évènement SelectionAdded.

 

        [CommandMethod("CMD")]
       public void TestCommand()
       {
           Editor ed = AcAp.DocumentManager.MdiActiveDocument.Editor;
           TypedValue[] filter = { new TypedValue(0, "INSERT"), new TypedValue(66, 1) };
           ed.SelectionAdded += onSelectionAdded;
           PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));
           ed.SelectionAdded -= onSelectionAdded;
           if (psr.Status == PromptStatus.OK)
               ed.SetImpliedSelection(psr.Value);
       }

       void onSelectionAdded(object sender, SelectionAddedEventArgs e)
       {
           Document doc = ((Editor)sender).Document;
           using (Transaction tr = doc.TransactionManager.StartOpenCloseTransaction())
           {
               ObjectId[] ids = e.AddedObjects.GetObjectIds();
               for (int i = 0; i < ids.Length; i++)
               {
                   BlockReference br =
                       (BlockReference)tr.GetObject(ids[i], OpenMode.ForRead);
                   foreach (ObjectId id in br.AttributeCollection)
                   {
                       AttributeReference att =
                           (AttributeReference)tr.GetObject(id, OpenMode.ForRead);
                       if (att.Tag != "TOTO")
                       {
                           e.Remove(i);
                           break;
                       }
                   }
               }
               tr.Commit();
           }
       }

  • Upvote 1

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Merci pour ta réponse (je vais tester et étudier cela) et puis par la même occasion merci pour tout le reste :) .

 

EDIT:

Fonctionne très bien, par contre si il y a d'autres attributs (par exemple un bloc composé de TOTO et TOTO2) chez moi cela ne fonctionne plus

Lien vers le commentaire
Partager sur d’autres sites

Oups !...

 

J'ai écris un peu vite le gestionnaire d'évènement.

Essaye plutôt comme ça :

 

        void onSelectionAdded(object sender, SelectionAddedEventArgs e)
       {
           Document doc = ((Editor)sender).Document;
           using (Transaction tr = doc.TransactionManager.StartOpenCloseTransaction())
           {
               ObjectId[] ids = e.AddedObjects.GetObjectIds();
               for (int i = 0; i < ids.Length; i++)
               {
                   BlockReference br =
                       (BlockReference)tr.GetObject(ids[i], OpenMode.ForRead);
                   bool found = false;
                   foreach (ObjectId id in br.AttributeCollection)
                   {
                       AttributeReference att =
                           (AttributeReference)tr.GetObject(id, OpenMode.ForRead);
                       if (att.Tag == "TOTO")
                       {
                           found = true;
                           break;
                       }
                   }
                   if (!found)
                       e.Remove(i);
               }
               tr.Commit();
           }
       }

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Tu peux filtrer directement sur l'étiquette d'attribut avec DxfCode.AttributeTag :

 

PromptSelectionResult psr = ed.SelectAll(new SelectionFilter(new TypedValue[]
{
 new TypedValue((int) DxfCode.AttributeTag, "TOTO")
}))

 

Attention, ça te renvoie les références de bloc qui contiennent la référence d'attribut, pas la référence d'attribut elle-même.

Maxence DELANNOY

Développement de compléments aux logiciels Autodesk : AutoCAD, Revit, Inventor, Vault, Navisworks... et autres logiciels de CAO

WIIP - http://wiip.fr

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

je ne crois pas qu'on puisse filtrer directement des références de bloc avec l'étiquette d'un attribut (en tout cas, ça ne fonctionne pas chez moi).

 

DxfCode.AttributeTag = 2, donc le filtre que propose Maxence sera : (2, "TOTO") et filtrera les références de bloc dont le nom est "TOTO" et les définitions d'attribut directement insérées dans l'espace courant dont l'étiquette est "TOTO".

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité