See the top rated post in this thread. Click here

Page 2 of 2 FirstFirst 12
Results 11 to 12 of 12

Thread: Command to build a list for dynamic blocks

  1. #11
    I could stop if I wanted to
    Join Date
    2007-08
    Posts
    201
    Login to Give a bone
    0

    Default Re: Command to build a list for dynamic blocks

    Hi,

    I tried to make something more generic with a GetCountByVisibility function which takes the block name and the visibility property name as parameters.
    This function uses some extension methods to get the effective name of a block reference and make a selection filtering with the block effective name.

    Salut,
    J'ai essayé de faire quelque chose de plus générique avec la fonction GetCountByVisibility qui prend le nom du bloc et le nom du paramètre de visibilité comme arguments.
    Cette fonction utilise quelques méthodes d'extension pour obtenir le nom effectif du bloc et faire une sélection en filtrant sur le nom effectif du bloc.


    C# code
    Code:
    using System;
    using System.Collections.Generic;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.EditorInput;
    using Autodesk.AutoCAD.Internal;
    using Autodesk.AutoCAD.Runtime;
    
    namespace CountByVisibilityState
    {
        public class Commands
        {
            [CommandMethod("Test")]
            public void Test()
            {
                Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
                Dictionary<string, long> result = GetCountByVisibility("ElecBaseboard", "Puissance plinthe");
                foreach (KeyValuePair<string, long> pair in result)
                {
                    ed.WriteMessage("\n{0} = {1}", pair.Key, pair.Value);
                }
            }
    
            // Retourne un dictionnaire dont les clés sont les états de visibilité et la valeur
            // le nombre de blocs correspondant dans la sélection.
            private Dictionary<string, long> GetCountByVisibility(string blockName, string propName)
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                Database db = doc.Database;
                // Valeur de retour
                Dictionary<string, long> result = new Dictionary<string, long>();
                // Sélection des blocs en fonction du nom effectif
                PromptSelectionResult psr = ed.SelectBlockByName(blockName);
                if (psr.Status != PromptStatus.OK)
                    return result;
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    // Parcourir le jeu de sélection
                    foreach (ObjectId id in psr.Value.GetObjectIds())
                    {
                        // Ouverture du bloc en écriture
                        BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
                        // Parcourir la collection de propriétés dynamiques
                        foreach (DynamicBlockReferenceProperty prop in br.DynamicBlockReferencePropertyCollection)
                        {
                            // Si le nom de la propriété correspond...
                            if (prop.PropertyName.Equals(propName, StringComparison.CurrentCultureIgnoreCase))
                            {
                                // Valeur de la propriété (état de visiblité)
                                string state = (string)prop.Value;
                                // Si le dictionnaire contient déjà cet état, on incrément le nombre
                                if (result.ContainsKey(state))
                                    result[state]++;
                                // Sinon, on ajoute une nouvelle entrée
                                else
                                    result.Add(state, 1);
                            }
                        }
                    }
                    tr.Commit();
                }
                return result;
            }
        }
    
    
        // Méthodes d'extension
        static class Extensions
        {
            // Modèle pour le(s) nom(s) de bloc (accepte les caractères génériques)
            private static string _pattern;
    
            // Retourne le nom effectif du bloc
            public static string GetEffectiveName(this BlockReference br)
            {
                return br.IsDynamicBlock ?
                    ((BlockTableRecord)br.DynamicBlockTableRecord.GetObject(OpenMode.ForRead)).Name :
                    br.Name;
            }
    
            // Retourne une instance de PromptSelectionResult en filtrant les blocs dont le nom effectif correspond au modèle.
            // 
            public static PromptSelectionResult SelectBlockByName(this Editor ed, string pattern, params TypedValue[] filter)
            {
                _pattern = pattern;
                PromptSelectionResult psr = null;
                using (Transaction tr = ed.Document.TransactionManager.StartTransaction())
                {
                    try
                    {
                        // Abonnement à l'évènement SelectionAdded
                        ed.SelectionAdded += new SelectionAddedEventHandler(onSelectionAdded);
                        psr = ed.GetSelection(new SelectionFilter(filter));
                    }
                    finally
                    {
                        // Désabonnement à l'évènement SelectionAdded
                        ed.SelectionAdded -= new SelectionAddedEventHandler(onSelectionAdded);
                    }
                }
                return psr;
            }
    
            // Gestionnaire de l'évènnement SelectionAdded : 
            // supprime du jeu de sélection les blocs dont le nom ne correspond pas au modèle
            private static void onSelectionAdded(object sender, SelectionAddedEventArgs e)
            {
                List<int> toRemove = new List<int>();
                SelectionSet ss = e.AddedObjects;
                for (int i = 0; i < ss.Count; i++)
                {
                    // Si l'objet sélectionné n'est pas un bloc, il est supprimé du jeu de sélection
                    if (ss[i].ObjectId.ObjectClass.DxfName != "INSERT")
                    {
                        toRemove.Add(i);
                        continue;
                    }
                    BlockReference br = (BlockReference)ss[i].ObjectId.GetObject(OpenMode.ForRead);
                    // Si le nom effectif du bloc ne correspond pas au modèle, il est supprimé du jeu de sélection 
                    if (!Utils.WcMatch(br.GetEffectiveName().ToUpper(), _pattern.ToUpper()))
                        toRemove.Add(i);
                }
                foreach (int i in toRemove) e.Remove(i);
            }
        }
    }

  2. #12
    I could stop if I wanted to
    Join Date
    2007-08
    Posts
    201
    Login to Give a bone
    0

    Default Re: Command to build a list for dynamic blocks

    VB code
    Code:
    Imports System.Collections.Generic
    Imports Autodesk.AutoCAD.ApplicationServices
    Imports Autodesk.AutoCAD.DatabaseServices
    Imports Autodesk.AutoCAD.EditorInput
    Imports Autodesk.AutoCAD.Internal
    Imports Autodesk.AutoCAD.Runtime
    
    Namespace CountByVisibilityState
    
        Public Class Commands
            <CommandMethod("Test")> _
            Public Sub Test()
                Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
                Dim result As Dictionary(Of String, Long) = GetCountByVisibility("ElecBaseboard", "Puissance plinthe")
                For Each pair As KeyValuePair(Of String, Long) In result
                    ed.WriteMessage(vbLf & "{0} = {1}", pair.Key, pair.Value)
                Next
            End Sub
    
            ' Retourne un dictionnaire dont les clés sont les états de visibilité et la valeur
            ' le nombre de blocs correspondant dans la sélection.
            Private Function GetCountByVisibility(blockName As String, propName As String) As Dictionary(Of String, Long)
                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim ed As Editor = doc.Editor
                Dim db As Database = doc.Database
                ' Valeur de retour
                Dim result As New Dictionary(Of String, Long)()
                ' Sélection des blocs en fonction du nom effectif
                Dim psr As PromptSelectionResult = ed.SelectBlockByName(blockName)
                If psr.Status <> PromptStatus.OK Then
                    Return result
                End If
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    ' Parcourir le jeu de sélection
                    For Each id As ObjectId In psr.Value.GetObjectIds()
                        ' Ouverture du bloc en écriture
                        Dim br As BlockReference = DirectCast(tr.GetObject(id, OpenMode.ForRead), BlockReference)
                        ' Parcourir la collection de propriétés dynamiques
                        For Each prop As DynamicBlockReferenceProperty In br.DynamicBlockReferencePropertyCollection
                            ' Si le nom de la propriété correspond...
                            If prop.PropertyName.Equals(propName, StringComparison.CurrentCultureIgnoreCase) Then
                                ' Valeur de la propriété (état de visiblité)
                                Dim state As String = DirectCast(prop.Value, String)
                                ' Si le dictionnaire contient déjà cet état, on incrément le nombre
                                If result.ContainsKey(state) Then
                                    result(state) += 1
                                Else
                                    ' Sinon, on ajoute une nouvelle entrée
                                    result.Add(state, 1)
                                End If
                            End If
                        Next
                    Next
                    tr.Commit()
                End Using
                Return result
            End Function
        End Class
    
    
        ' Méthodes d'extension
        Module Extensions
    
            ' Modèle pour le(s) nom(s) de bloc (accepte les caractères génériques)
            Private _pattern As String
    
            ' Retourne le nom effectif du bloc
            <System.Runtime.CompilerServices.Extension()> _
            Public Function GetEffectiveName(br As BlockReference) As String
                Return IIf(br.IsDynamicBlock, DirectCast(br.DynamicBlockTableRecord.GetObject(OpenMode.ForRead), BlockTableRecord).Name, br.Name)
            End Function
    
            ' Retourne une instance de PromptSelectionResult en filtrant les blocs dont le nom effectif correspond au modèle.
            <System.Runtime.CompilerServices.Extension()> _
            Public Function SelectBlockByName(ed As Editor, pattern As String, ParamArray filter As TypedValue()) As PromptSelectionResult
                _pattern = pattern
                Dim psr As PromptSelectionResult = Nothing
                Using tr As Transaction = ed.Document.TransactionManager.StartTransaction()
                    Try
                        ' Abonnement à l'évènement SelectionAdded
                        AddHandler ed.SelectionAdded, New SelectionAddedEventHandler(AddressOf onSelectionAdded)
                        psr = ed.GetSelection(New SelectionFilter(filter))
                    Finally
                        ' Désabonnement à l'évènement SelectionAdded
                        RemoveHandler ed.SelectionAdded, New SelectionAddedEventHandler(AddressOf onSelectionAdded)
                    End Try
                End Using
                Return psr
            End Function
    
            ' Gestionnaire de l'évènnement SelectionAdded : 
            ' supprime du jeu de sélection les blocs dont le nom ne correspond pas au modèle
            Private Sub onSelectionAdded(sender As Object, e As SelectionAddedEventArgs)
                Dim toRemove As New List(Of Integer)()
                Dim ss As SelectionSet = e.AddedObjects
                For i As Integer = 0 To ss.Count - 1
                    ' Si l'objet sélectionné n'est pas un bloc, il est supprimé du jeu de sélection
                    If ss(i).ObjectId.ObjectClass.DxfName <> "INSERT" Then
                        toRemove.Add(i)
                        Continue For
                    End If
                    Dim br As BlockReference = DirectCast(ss(i).ObjectId.GetObject(OpenMode.ForRead), BlockReference)
                    ' Si le nom effectif du bloc ne correspond pas au modèle, il est supprimé du jeu de sélection 
                    If Not Utils.WcMatch(br.GetEffectiveName().ToUpper(), _pattern.ToUpper()) Then
                        toRemove.Add(i)
                    End If
                Next
                For Each i As Integer In toRemove
                    e.Remove(i)
                Next
            End Sub
        End Module
    End Namespace

Page 2 of 2 FirstFirst 12

Similar Threads

  1. 2013: Did Flatten command wreck my Dynamic Blocks
    By Mac Demer in forum Dynamic Blocks - Technical
    Replies: 1
    Last Post: 2013-04-05, 12:25 PM
  2. Dynamic blocks - parts list
    By ONE77TA in forum AutoCAD Mechanical - Wish List
    Replies: 0
    Last Post: 2010-06-02, 07:47 PM
  3. Dynamic blocks and Stretch command
    By pawel-l in forum Dynamic Blocks - Technical
    Replies: 3
    Last Post: 2010-05-18, 04:16 PM
  4. Express Tools command CDORDER ruins Dynamic Blocks
    By Thumbs in forum Dynamic Blocks - Technical
    Replies: 3
    Last Post: 2007-03-15, 04:10 PM
  5. Gatte command not working with Dynamic Blocks
    By Mlabell in forum AutoCAD General
    Replies: 8
    Last Post: 2007-02-21, 01:13 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •