CadFrank Posté(e) le 3 mars 2017 Posté(e) le 3 mars 2017 Bonjour , est-il possible de faire une programme en C# pour calculer des block dynamic avec la valeur de la visibilité active& Merci,
(gile) Posté(e) le 4 mars 2017 Posté(e) le 4 mars 2017 Salut, Si j'ai bien compris la question /// <summary> /// Compte les blocs dynamiques groupés par valeur de la propriété spécifiée. /// </summary> /// <param name="db">Base de données du dessin dans lequel s'appliquela méthode.</param> /// <param name="blockName">Nom du bloc.</param> /// <param name="propertyName">Nom de la propriété.</param> /// <returns>Un dictionnaire de paires clé/valeur : valeur de la propriété/nombre d'occurences.</returns> private Dictionary<object, int> CountByDynamicPropertyValue(Database db, string blockName, string propertyName) { using (var tr = db.TransactionManager.StartOpenCloseTransaction()) { var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); if (!bt.Has(blockName)) throw new ArgumentException($"Le bloc '{blockName}' est introuvable."); var btr = (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead); if (!btr.IsDynamicBlock) throw new InvalidOperationException($"Le bloc '{blockName} n'est pas un bloc dynamique."); var blockRefs = new List<BlockReference>(); foreach (ObjectId brId in btr.GetBlockReferenceIds(true, false)) { blockRefs.Add((BlockReference)tr.GetObject(brId, OpenMode.ForRead)); } foreach (ObjectId anonymBtrId in btr.GetAnonymousBlockIds()) { var anonymBtr = (BlockTableRecord)tr.GetObject(anonymBtrId, OpenMode.ForRead); foreach (ObjectId brId in anonymBtr.GetBlockReferenceIds(true, false)) { blockRefs.Add((BlockReference)tr.GetObject(brId, OpenMode.ForRead)); } } return blockRefs .SelectMany(br => br.DynamicBlockReferencePropertyCollection .Cast<DynamicBlockReferenceProperty>() .Where(prop => prop.PropertyName == propertyName)) .ToLookup(prop => prop.Value) .ToDictionary(grp => grp.Key, grp => grp.Count()); } } Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
CadFrank Posté(e) le 4 mars 2017 Auteur Posté(e) le 4 mars 2017 Bonjour Gile, Je crois que tu as surment bien compris la question. Par contre, il me faudrait p-e quelque explication sur comment utiliser ton code. Ce que je veux vraiment faire est selection mes items dans un dessin CAD et ensuite créer une liste des ces élément. [CommandMethod("DBP")] static public void DynamicBlockProps() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptStringOptions pso = new PromptStringOptions( "\nEnter dynamic block name or enter to select: " ); pso.AllowSpaces = true; PromptResult pr = ed.GetString(pso); if (pr.Status != PromptStatus.OK) return; Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { BlockReference br = null; // If a null string was entered allow entity selection if (pr.StringResult == "") { // Select a block reference PromptEntityOptions peo = new PromptEntityOptions( "\nSelect dynamic block reference: " ); peo.SetRejectMessage("\nEntity is not a block."); peo.AddAllowedClass(typeof(BlockReference), false); PromptEntityResult per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) return; // Access the selected block reference br = tr.GetObject( per.ObjectId, OpenMode.ForRead ) as BlockReference; } else { // Otherwise we look up the block by name BlockTable bt = tr.GetObject( db.BlockTableId, OpenMode.ForRead) as BlockTable; if (!bt.Has(pr.StringResult)) { ed.WriteMessage( "\nBlock \"" + pr.StringResult + "\" does not exist." ); return; } // Create a new block reference referring to the block br = new BlockReference( new Point3d(), bt[pr.StringResult] ); } BlockTableRecord btr = (BlockTableRecord)tr.GetObject( br.DynamicBlockTableRecord, OpenMode.ForRead ); // Call our function to display the block properties DisplayDynBlockProperties(ed, br, btr.Name); // Committing is cheaper than aborting tr.Commit(); } } private static void DisplayDynBlockProperties( Editor ed, BlockReference br, string name ) { // Only continue is we have a valid dynamic block if (br != null && br.IsDynamicBlock) { ed.WriteMessage( "\nDynamic properties for \"{0}\"\n", name ); // Get the dynamic block's property collection DynamicBlockReferencePropertyCollection pc = br.DynamicBlockReferencePropertyCollection; // Loop through, getting the info for each property foreach (DynamicBlockReferenceProperty prop in pc) { // Start with the property name, type and description if (prop.PropertyName == "Choisir") { ed.WriteMessage("\nProperty Type Code : " + prop.PropertyTypeCode.ToString()); ed.WriteMessage("\nProperty Value : " + prop.Value.ToString()); ed.WriteMessage("\nProperty UnitsType : " + prop.UnitsType.ToString()); } } } } Avec ce bout de code je peut trouver les propriété, par contre l'indexation de chaque propriéter change a chaque block. Donc, il mes impossible de pouvoir faire une liste avec ce bout de code. :( Par contre, je crois bien que ton code me pointe dans la bonne direction.
(gile) Posté(e) le 4 mars 2017 Posté(e) le 4 mars 2017 Salut, Le code que j'ai posté est une méthode qui collecte tous les blocs du dessin dont le nom correspond à l'argument blockName, les regroupe par valeur égale pour la propriété correspond à l'argument propName et retourne un dictionnaire avec une entrée par groupe dont la valeur est le nombre d’occurrences de blocs ayant cette valeur pour cette propriété. Un exemple de commande qui appelle cette méthode. [CommandMethod("TEST", CommandFlags.UsePickSet)] public void Test() { var doc = Application.DocumentManager.MdiActiveDocument; var db = doc.Database; var ed = doc.Editor; var options = new PromptStringOptions("\nEntrez le nom du bloc: "); options.AllowSpaces = true; var result = ed.GetString(options); if (result.Status != PromptStatus.OK) return; var blockName = result.StringResult; options.Message = "\nEntrez le nom de la propriété: "; result = ed.GetString(options); if (result.Status != PromptStatus.OK) return; var propName = result.StringResult; try { foreach (var item in CountByDynamicPropertyValue(db, blockName, propName)) { ed.WriteMessage($"\n{item.Key} : {item.Value}"); } } catch(System.Exception ex) { ed.WriteMessage($"\nErreur: {ex.Message}"); } } Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
CadFrank Posté(e) le 4 mars 2017 Auteur Posté(e) le 4 mars 2017 ReBonjour, Donc en ce moment, il n'y a rien comme méthode qui détermine que la propriété est la visibilité? Par contre, en AutoLisp cela est possible.. Bon bien je crois que je vais ddevoir faire avec. Merci beaucoup de ton aide.
(gile) Posté(e) le 4 mars 2017 Posté(e) le 4 mars 2017 Donc en ce moment, il n'y a rien comme méthode qui détermine que la propriété est la visibilité? Par contre, en AutoLisp cela est possible.. Si, la classe .NET DynamicBlockReferenceProperty a une propriété PropertyTypeCode qui vaut 5 pour un paramètre de visiblité. [CommandMethod("CountByVis")] public void CountByVis() { var doc = Application.DocumentManager.MdiActiveDocument; var db = doc.Database; var ed = doc.Editor; var options = new PromptStringOptions("\nEntrez le nom du bloc: "); options.AllowSpaces = true; var result = ed.GetString(options); if (result.Status != PromptStatus.OK) return; var blockName = result.StringResult; try { var visibilities = CountByVisibilityState(db, blockName); if (visibilities.Count == 0) ed.WriteMessage($"\nLe bloc '{blockName}' n'a pas d'états de visibilité."); else foreach (var item in visibilities) { ed.WriteMessage($"\n{item.Key} : {item.Value}"); } } catch (System.Exception ex) { ed.WriteMessage($"\nErreur: {ex.Message}"); } } private Dictionary<string, int> CountByVisibilityState(Database db, string blockName) { using (var tr = db.TransactionManager.StartOpenCloseTransaction()) { var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); if (!bt.Has(blockName)) throw new ArgumentException($"Le bloc '{blockName}' est introuvable."); var btr = (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead); if (!btr.IsDynamicBlock) throw new InvalidOperationException($"Le bloc '{blockName} n'est pas un bloc dynamique."); var blockRefs = new List<BlockReference>(); foreach (ObjectId brId in btr.GetBlockReferenceIds(true, false)) { blockRefs.Add((BlockReference)tr.GetObject(brId, OpenMode.ForRead)); } foreach (ObjectId anonymBtrId in btr.GetAnonymousBlockIds()) { var anonymBtr = (BlockTableRecord)tr.GetObject(anonymBtrId, OpenMode.ForRead); foreach (ObjectId brId in anonymBtr.GetBlockReferenceIds(true, false)) { blockRefs.Add((BlockReference)tr.GetObject(brId, OpenMode.ForRead)); } } return blockRefs .SelectMany(br => br.DynamicBlockReferencePropertyCollection .Cast<DynamicBlockReferenceProperty>() .Where(prop => prop.PropertyTypeCode == 5)) // <- filtre la propriété "état de visibilité" .ToLookup(prop => (string)prop.Value) .ToDictionary(grp => grp.Key, grp => grp.Count()); } } Par contre, en LISP (ActiveX) il me semble qu'il n'existe pas d'équivalent (voir ici). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
CadFrank Posté(e) le 4 mars 2017 Auteur Posté(e) le 4 mars 2017 J'ai testé ton code. J'ai une petite question, Est ce que l'état de visibilité correspond a des lookup? Car j'ai toujours plus qu'un élément qui sort dans la ligne de command. J'aimerais avoir si possible l'information relative au class .net d'autoCAD? svp ou bien m'indiquer ou je peux la trouver. Désolé si j'ai du délai sur mes questions j'habitte au Québec :D Merci.
(gile) Posté(e) le 4 mars 2017 Posté(e) le 4 mars 2017 Oui, PropertyTypeCode = 5 vaut pour les paramètres de visibilité et de consultation, c'est pour ça que le nom de la propriété est plus fiable. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
CadFrank Posté(e) le 4 mars 2017 Auteur Posté(e) le 4 mars 2017 Par contre si on voudrais faire une liste de toute les blocks dans un dessin CAD il me faudrais mettre le meme nom d'état de visibilité. Pour être sur que seulement c'est block son choisi. Je vais donc devoir repenser a comment je fais mes blocks pour m'assurer que je choisi le paramettre voulu. Merci encore
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant