.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Iterating block (block in a block) in C#

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
maxime.didaoui
4743 Views, 3 Replies

Iterating block (block in a block) in C#

Hi everyone,

 

I'm a french dude so sorry if my English isn't well enough.

 

I'm new with AutoCAD (2012) and I'm trying to create a commandmethod which allow to select and see what's in the block selected.

I already looked some forums but they used the database instead of the promptselection.

 

- http://forums.autodesk.com/t5/NET/simple-example-of-iterating-a-collection-eg-blocks/td-p/2553278

- http://forums.autodesk.com/t5/NET/How-to-iterate-through-items-of-a-block-reference-in-Dotnet/m-p/...

 

This is my code:

 

    

   [CommandMethod("SelectBlock")]

        public void SelectBlock()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Database db = HostApplicationServices.WorkingDatabase;
            Transaction tr = db.TransactionManager.StartTransaction();

           try
            {
                PromptSelectionOptions opts = new PromptSelectionOptions();
                opts.MessageForAdding = "Select block references:";
                PromptSelectionResult res = ed.GetSelection(opts);

                if (res.Status != PromptStatus.OK){return;}

                 SelectionSet selSet = res.Value;
                 ObjectId[] ids = selSet.GetObjectIds();

                 foreach (ObjectId blkId in ids)
                    {
                   if (blkId != null)
                   {
                       // Open the Block table record Model space for read
                       BlockTableRecord acBlkTblRec = tr.GetObject(blkId, OpenMode.ForRead) as BlockTableRecord;
                        //acBlkTblRec is still null

// Step through the Block table record
if (acBlkTblRec != null) { foreach (ObjectId asObjId in acBlkTblRec) { Entity e = (Entity)tr.GetObject(asObjId, OpenMode.ForRead); ed.WriteMessage(e.ToString()); } } } } tr.Commit(); } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage(("Exception: " + ex.Message)); } finally { tr.Dispose(); } } } }

 Everything is fine until the bold line. In fact, I find the block selected (it contains 4 blocks) and go inside the first foreach, but when I instantiate my BlockTableRecord, acBlkTblRec stay "null" and the second foreach is ignored. Do you have any idea about what happended ?

 

I use AutoCad 2012 and Visual Studio 2010.

 

Thank you in advance for your precious help Cat Happy

 

Max

 

 

 

 

3 REPLIES 3
Message 2 of 4
fsztuczny
in reply to: maxime.didaoui

Hi

1. Not if (blkId != null), should be:

if ( !blkid.IsErased )

2. Not BlockTableRecord acBlkTblRec = tr.GetObject(blkId, OpenMode.ForRead) as BlockTableRecord; should be:

BlockReference blRef = tr.GetObject( blkId, OpenMode.ForRead ) as BlockReference;

if( blRef != null )

{

...

}

 

or

 

Entity ent = tr.GetObject(blkId, OpenMode.ForRead) as Entity;

if( ent.GetType() == typeof( BlockReference ) )

{

BlockReference blRef = ent as BlockReference;

...

//Now you can open BlockTableRecord:

BlockTableRecord acBlkTblRec = tr.GetObject( blRef.BlockTableRecord, OpenMode.ForRead ) as BlockTableRecord

}

Message 3 of 4
_gile
in reply to: maxime.didaoui

Salut,

 

Il semble que tu ne connaisse pas bien la différence entre une définition de bloc (BlockTableRecord) et une référence de bloc (BlockReference).

Une définition de bloc est un objet "non graphique" stocké dans la table des blocs (BlockTable) qui est une sorte de collection d'entités (les espaces objet et papier sont aussi de type BlockTableRecord).

Une référence de bloc est une représentation géométrique (entité graphique) d'une définition de bloc. Elle est insérée dans un espace objet ou papier ou dans une autre définition de bloc (un objet de type BlockTableRecord).

 

Quand on sélectionne un bloc dans le dessin, c'est une référence de bloc qu'on sélectionne et on peut pas accéder directement aux entités composant ce bloc. On n'y accède que par la définition du bloc.

 

        [CommandMethod("SelectBlock")]

        public void SelectBlock()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // A selection filter to select only block references
                SelectionFilter filter = new SelectionFilter(
                    new TypedValue[1] { new TypedValue(0, "INSERT") });

                PromptSelectionOptions opts = new PromptSelectionOptions();
                opts.MessageForAdding = "Select block references:";
                PromptSelectionResult res = ed.GetSelection(opts);

                if (res.Status != PromptStatus.OK) { return; }

                SelectionSet selSet = res.Value;
                ObjectId[] ids = selSet.GetObjectIds();

                foreach (ObjectId blkId in ids)
                {
                    if (blkId != null)
                    {
                        // Open the Block reference for read (no need for type checking because as the selection filter did it)
                        BlockReference acBlkRef = (BlockReference)tr.GetObject(blkId, OpenMode.ForRead) as BlockReference;

                        // Open the Block table record of the selected reference for read
                        BlockTableRecord acBlkTblRec =
                            (BlockTableRecord)tr.GetObject(acBlkRef.BlockTableRecord, OpenMode.ForRead);

                        // Step through the Block table record
                        ed.WriteMessage("\n\n{0}", acBlkRef.Name);
                        foreach (ObjectId asObjId in acBlkTblRec)
                        {
                            Entity e = (Entity)tr.GetObject(asObjId, OpenMode.ForRead);
                            ed.WriteMessage("\n{0}", e);
                        }
                    }
                }
                tr.Commit();
            }
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 4
maxime.didaoui
in reply to: _gile

Salut Gile,

 

Merci pour cette réponse détaillée, je pense avoir maintenant saisi la différence, et ça marche à merveille.

 

Je vais continuer de me documenter là dessus.

 

And I would like to thank you too fsztuczny, it works now.

 

Maxime

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost