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

Block-Functions (Select, Explode, etc.)

22 REPLIES 22
SOLVED
Reply
Message 1 of 23
klahie
5203 Views, 22 Replies

Block-Functions (Select, Explode, etc.)

Hi community!

 

I have a C#-WPF-Application. In this application there is a list of blocks in my drawing. When I click one of these blocks in the listbox I have several button-functions. 

 

One of them:

Select the in the list selected block in the drawing.

 

Another:

Explode the in the list selected block.

 

I found several topics with Selection, but none of them worked for me. I'm looking for a selection via ObjectId or blockname of a single block, in the most cases the selectionfilter needs an array(?). 

And I'm absolutly helpless with block-explosion. Smiley Sad

 

I'm really new to Autocad and C#-Addin-programming. Smiley Indifferent

 

Thank you in advance!

Greets

Klaus

22 REPLIES 22
Message 2 of 23
chiefbraincloud
in reply to: klahie

This blog post explains the selection filter mechanism

http://through-the-interface.typepad.com/through_the_interface/2008/07/conditional-sel.html

 

What you basically need for the selection filter (by blockname) is:

TypedValue[] SSfilter = {
	new TypedValue(0, "INSERT"),
	new TypedValue(2, "BLOCKNAME")
};

 If you have objectid(s) and want them to be selected in the editor, you use editor.SetImpliedSelection(objectid())

 

Assuming you are using the managed API, there are two ways to explode a BlockReference, one is the Explode method inherited from entity.  You pass in a DbObjectCollection, and AutoCAD fills the collection with the entities generated from the explode.  You are then responsible for either adding them to the database, or disposing of them when you are done, depending on your needs.

 

The other is BlockReference.ExplodeToOwnerSpace().  That one automatically appends the generated entities to the parent of the block reference.  This could be the Model space, or a paper space layout, or even another block if the block was nested.  The Block must be uniformly scaled in both methods.

Dave O.                                                                  Sig-Logos32.png
Message 3 of 23
klahie
in reply to: klahie

Okay, first problem: Selection:

 

I tried the Selection like this:

public void selectBlock(string blockName)
{
   BlockTableRecord btr = null;
   Editor ed = doc.Editor;
   using (tr = db.TransactionManager.StartTransaction())
   {
      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
      foreach (ObjectId objId in bt)
      {
         btr = (BlockTableRecord)tr.GetObject(objId, OpenMode.ForWrite);

         if (blockName == btr.Name)
         {
            TypedValue[] tvs = new TypedValue[] {
               new TypedValue(
                  (int)DxfCode.Operator,
                  "<or"
               ),
               new TypedValue (
                  (int)DxfCode.BlockName,
                  btr.Name
               ),
               new TypedValue(
                  (int)DxfCode.Operator,
                  "or>"
               )
            };

            SelectionFilter sf = new SelectionFilter(tvs);
            PromptSelectionResult psr = ed.SelectAll(sf);
            ed.WriteMessage("\nFound {0} entit{1}.", psr.Value.Count, (psr.Value.Count == 1 ? "y" : "ies"));
         }
      }
   }
}

I know, I could simply give the blockName to the DxfCode.BlockName-variable without foreach and so on, but I also tried it with objectId. Hmm, theeditor-message shows up that AutoCAD finds one entity. But this entity isn't selected!? Smiley Sad

 

But Kean Walmsley also writes in his blog: " This simply tells you how many entities met the selection criteria - it doesn't leave them selected for use by further commands.".


Okay, now... How do I leave it selected for use by further commands? Smiley Wink

 

I've also tried the selection like you posted it with :

new TypedValue(0, "INSERT"),
new TypedValue(2, blockName)

 If this is, what you've meant, it doesn't work for me either.

 

And I didn't get your point with the objectId-selection, my editor wants an array of ObjectIds. Should I create an Array of ObjectIds with the objectid of the block on the first position? Smiley Sad

But if I get it working with the blockname, I do not need the selection by objectid. I simply want the easiest way to select the block. Smiley Wink

__________________________________

 

Second problem: Explosion

 

My block is a BlockTableRecord. How do I get a BlockReference to work with my BlockTableRecord?

 

Many thanks!

Klaus

 


Message 4 of 23
chiefbraincloud
in reply to: klahie

Well, I've already done all this once, then when I went to post it, the discussion group kicked me out, so here goes again.

 

First, I think you need to do a little research on the difference between a BlockTableRecord, and a BlockReference.  It has been covered on this discussion group so I'm not going to get into here, especially because I have no idea what your experience level with AutoCAD is.

 

Kean's comment "This simply tells you how many entities met the selection criteria - it doesn't leave them selected for use by further commands."  Means that the entities are not left selected in the editor, there is a selection set created (psr.value) that can be used by code to do other things with the selection, they just don't appear to be selected to the user after function ends.

 

I have worked up these two quick examples of how to get the objects you want and leave them selected in the editor after your command completes.  One piece that is not shown here is the the CommandMethod that is called to use this code must have the "CommandFlags.Redraw" set.

 

public void selectBlock(string blockName)
{
Database db = HostApplicationServices.WorkingDatabase;
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
    try
    {
        BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead, false, true);
        if (bt.Has(blockName))
        {
            ObjectId btrid = bt[blockName];
            if (!btrid.IsEffectivelyErased)
            {
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(btrid, OpenMode.ForRead, false, true);
                ObjectIdCollection brefIDs = btr.GetBlockReferenceIds(true, false);
                ObjectId[] oids = new ObjectId[brefIDs.Count];
                brefIDs.CopyTo(oids, 0);
                ed.SetImpliedSelection(oids);
            }
        }
        trans.Commit();
    }
    catch (System.Exception ex)
    {
        //
    }
}
}

public void selectBlock2(string blockName)
{
Database db = HostApplicationServices.WorkingDatabase;
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
TypedValue[] tvs = new TypedValue[] {
	new TypedValue(0, "INSERT"),
	new TypedValue(2, blockName)
};
SelectionFilter sf = new SelectionFilter(tvs);
PromptSelectionResult psr = ed.SelectAll(sf);
if (psr.Status == PromptStatus.OK)
{
    ed.SetImpliedSelection(psr.Value.GetObjectIds());
}
}

 I would use the second method, as it does not require a transaction, but the first method does demonstrate something that may be useful for your Explode problem.

 

You can not call Explode on a BlockTableRecord.  You also can not "Select" them using selection methods or filters.  There is no graphical representation of a BlockTableRecord.

 

So you say you have a BlockTableRecord.  If all you want is to find out what is in that BlockTableRecord, you can iterate through it's contents with a For Each of DbObject.  I am assuming that is not what you want, and that what you want is to Explode the BlockReferences that point to that BlockTableRecord.  The first example above shows how to get the ObjectIds of all BlockReferences that point to a particular BlockTableRecord.  You can then use those ObjectIds to open each BlockReference and call .ExplodeToOwnerSpace if you want to duplicate the behavior of the AutoCAD Explode command (I'm not sure if you have to erase the original block, or if the API does it for you, but the API does add each of the resultant entities to the owner of the BlockReference), or you can call .Explode and the use the results of that explode to do whatever it is you need to do (In which case you must add the objects to the database or dispose of them, and if you want the original block to be erased you have to do that yourself).

 

Give that a shot.  I'll see if I can find a good article describing the difference between a BlockTableRecord and a BlockReference.

 

Dave O.                                                                  Sig-Logos32.png
Message 5 of 23
klahie
in reply to: chiefbraincloud


@chiefbraincloud wrote:

  It has been covered on this discussion group so I'm not going to get into here, especially because I have no idea what your experience level with AutoCAD is.

 


Hmm, well... My AutoCAD-experiences belong to an half-an-hour introduction of a friend of mine. Smiley Frustrated

It is a small project for my school leaving examination. I have to make a little plugin for a company, it isn't really bad for them if it is only a prototype. Smiley Wink

 

Many thanks, the Selection works like a charm! Smiley Happy

 

I tried the explosion like this:

public void explodeBlock(string blockName)
{
   Editor ed = doc.Editor;
   using (tr = db.TransactionManager.StartTransaction())
   {
      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false, true);
      if (bt.Has(blockName)) {
         ObjectId btrid = bt[blockName];
         if (!btrid.IsEffectivelyErased) {
            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrid, OpenMode.ForRead, false, true);

            ObjectIdCollection brefIds = btr.GetBlockReferenceIds(true, false);
            ObjectId[] oids = new ObjectId[brefIds.Count];
            brefIds.CopyTo(oids, 0);
            foreach (ObjectId objid in brefIds) {
               BlockReference br = (BlockReference)tr.GetObject(objid, OpenMode.ForWrite);
               br.ExplodeToOwnerSpace();
            }
         }
      }
   }
}

 I do not really realize if something has changed, can I check this anywhere?

 

Greets

Klaus

Message 6 of 23
chiefbraincloud
in reply to: klahie

first: these two lines are useless in your function

 

ObjectId[] oids = new ObjectId[brefIds.Count];
brefIds.CopyTo(oids, 0);

Second, I would definitely put the ExplodeToOwnerSpace() method inside a Try/Catch, because if the block has a non-uniform scale (ie. the X, Y, and Z scales are not the same) which is not that uncommon, the ExplodeToOwnerSpace method will fail.

 

To see the change, try using your selection tool to select all references of a block.  Look at the drawing window, and you should see some grips (little colored squares), by default there should be one grip per block (but there is a user setting that would cause more grips to show up).

 

then zoom in to where you can see one or more of the blocks. 

 

Run your explode tool on the same blockName.  Then you can perform two tests. one, try using the mouse and selecting a part of the block you have in your view.  If it is exploded, you will now have individual entities (lines, arcs, circles, etc...) instead of multiple entities grouped into a single block, and you will see more than one grip, and the whole block will not be selected, but just the entity or entities you pick.

 

test two, try running your select tool again on the same block.  If the original blocks were erased when they were exploded, you will get zero selected objects.  If not you will have to add a line of code in your for each to erase them manually.

 

Basically not being able to see a difference should be a good thing (if you aren't getting any errors) but the help docs are not clear about whether the original block is erased by ExplodeToOwnerSpace, so you could have a bunch of new entities created right on top of the old block, but what you really want is a bunch of new entities, and no more old block.

Dave O.                                                                  Sig-Logos32.png
Message 7 of 23
klahie
in reply to: chiefbraincloud

Hmm for me it does nothing. Smiley Sad Not even if i call

br.Erase()

 I tried it with the drawing I've got from alfred.neswadba (http://forums.autodesk.com/t5/NET/Edit-a-Block-via-C/m-p/3366541#M27591), you find it attached. Seems not to work. Smiley Sad

 

Oh, the last function I have to implement should copy a block and paste it. For paste there should be a cursor to set the insertpoint for the block (like the usual insert in AutoCAD). How complex would this be? Smiley Wink 

 

Greets

Klaus

Message 8 of 23
Hallex
in reply to: klahie

See if this is working for you,

tested on A2010 only

 

    Public Sub ApplyAttributes(db As Database, tr As Transaction, bref As BlockReference)

        Dim btrec As BlockTableRecord = TryCast(tr.GetObject(bref.BlockTableRecord, OpenMode.ForRead), BlockTableRecord)

        If btrec.HasAttributeDefinitions Then

            Dim atcoll As Autodesk.AutoCAD.DatabaseServices.AttributeCollection = bref.AttributeCollection

            For Each subid As ObjectId In btrec

                Dim ent As Entity = DirectCast(subid.GetObject(OpenMode.ForRead), Entity)

                Dim attDef As AttributeDefinition = TryCast(ent, AttributeDefinition)

                If attDef IsNot Nothing Then

                    Dim attRef As New AttributeReference()

                    attRef.SetDatabaseDefaults()

                    attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)

                    attRef.Position = attDef.Position.TransformBy(bref.BlockTransform)

                    attRef.Tag = attDef.Tag

                    attRef.TextString = attDef.TextString

                    attRef.AdjustAlignment(db)

                    atcoll.AppendAttribute(attRef)

                    tr.AddNewlyCreatedDBObject(attRef, True)

                End If

            Next
        End If
    End Sub
    Public Sub TestInsert()
        Dim blkname As String = "VT_VZ_VZ52_10a_ATT" ''<-- as per as on your drawing
        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor
        Dim db As Database = doc.Database
        Try
            Using docloc As DocumentLock = doc.LockDocument

                Using tr As Transaction = db.TransactionManager.StartTransaction
                    Dim bt As BlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead)

                    If Not bt.Has(blkname) Then
                        MsgBox("Block does not exists")
                        Return
                    End If

                    Dim pto As PromptPointOptions = New PromptPointOptions(vbLf + "Pick a block insertion point: ")
                    Dim ptres As PromptPointResult = ed.GetPoint(pto)
                    Dim ipt As Point3d

                    If ptres.Status <> PromptStatus.Cancel Then
                        ipt = ptres.Value
                    End If

                    Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, False), BlockTableRecord)
                    Dim blk As BlockTableRecord = DirectCast(tr.GetObject(bt(blkname), OpenMode.ForRead, False), BlockTableRecord)
                    Dim bref As New BlockReference(ipt, blk.ObjectId)
                    bref.BlockUnit = UnitsValue.Millimeters
                    bref.Rotation = 0
                    bref.ScaleFactors = New Scale3d(1000.0) ''<-- as per as on your drawing
                    btr.AppendEntity(bref)
                    tr.AddNewlyCreatedDBObject(bref, True)
                    ApplyAttributes(db, tr, bref)
                    ed.Regen()
                    tr.Commit()
                End Using
            End Using
        Catch ex As System.Exception
            MsgBox(ex.Message)
        End Try
    End Sub

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 9 of 23
klahie
in reply to: Hallex

Okay, Explosion is working! Smiley Very Happy

 

Just add an tr.Commit() to my function.... Smiley Embarassed

 

To the insert:

 

I'm not very common with VB, so i translated it with < Convert C# to VB.NET >. What I got is (in your TestInsert()-method):

 

PromptPointOptions pto = new PromptPointOptions(Constants.vbLf + "Pick a block insertion point: ");

 Hmm Constants."anything" doesn't tell me anything, so i've deleted "Constants.", but vbLf is nowhere declared in this method. How do you use it?

 

The second thing:

BlockTableRecord blk = (BlockTableRecord)tr.GetObject(bt(blkname), OpenMode.ForRead, false);

 'bt' is a variable but used like a method, can you explain this to me? 

 

And many thanks to chiefbraincloud for your help at Selection & Explosion! Smiley Very Happy

 

Greets

Klaus

Message 10 of 23
chiefbraincloud
in reply to: klahie

Oops.  I didn't even look to see if you had the .commit in there.

 

vbLf is a constant for a line feed character (in Visual Basic), I don't know if C# has a similar set of constants, but I know you can use chr(13).

 

2nd prob should be square braces instead of parenthesis:

BlockTableRecord blk = (BlockTableRecord)tr.GetObject(bt[blkname], OpenMode.ForRead, false);

 

I didn't look at Hallex's code other than what you posted as conversion problems.

Dave O.                                                                  Sig-Logos32.png
Message 11 of 23
Hallex
in reply to: klahie

Sorry, try converted on C# instead

        public static void ApplyAttributes(Database db, Transaction tr, BlockReference bref)
        {
            BlockTableRecord btrec = tr.GetObject(bref.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;

            if (btrec.HasAttributeDefinitions)
            {
                Autodesk.AutoCAD.DatabaseServices.AttributeCollection atcoll = bref.AttributeCollection;

                foreach (ObjectId subid in btrec)
                {
                    Entity ent = (Entity)subid.GetObject(OpenMode.ForRead);

                    AttributeDefinition attDef = ent as AttributeDefinition;

                    if (attDef != null)
                    {

                        AttributeReference attRef = new AttributeReference();

                        attRef.SetDatabaseDefaults();

                        attRef.SetAttributeFromBlock(attDef, bref.BlockTransform);

                        attRef.Position = attDef.Position.TransformBy(bref.BlockTransform);

                        attRef.Tag = attDef.Tag;

                        attRef.TextString = attDef.TextString;

                        attRef.AdjustAlignment(db);

                        atcoll.AppendAttribute(attRef);

                        tr.AddNewlyCreatedDBObject(attRef, true);

                    }
                }
            }
        }
        [CommandMethod("insBlock", CommandFlags.Modal | CommandFlags.UsePickSet)]
        public void TestInsert()
        {
            string blkname = "VT_VZ_VZ52_10a_ATT";
            //'<-- as per as on your drawing
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            try
            {
                using (DocumentLock docloc = doc.LockDocument())
                {

                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);

                        if (!bt.Has(blkname))
                        {
                            ed.WriteMessage("\nBlock does not exists");
                            return;
                        }

                        PromptPointOptions pto = new PromptPointOptions("\nPick a block insertion point: ");
                        PromptPointResult ptres = ed.GetPoint(pto);
                        Point3d ipt = default(Point3d);

                        if (ptres.Status != PromptStatus.Cancel)
                        {
                            ipt = ptres.Value;
                        }

                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false);
                        BlockTableRecord blk = (BlockTableRecord)tr.GetObject(bt[blkname], OpenMode.ForRead, false);
                        BlockReference bref = new BlockReference(ipt, blk.ObjectId);
                        bref.BlockUnit = UnitsValue.Millimeters;
                        bref.Rotation = 0;
                        bref.ScaleFactors = new Scale3d(1000.0);
                        //'<-- as per as on your drawing
                        btr.AppendEntity(bref);
                        tr.AddNewlyCreatedDBObject(bref, true);
                        ApplyAttributes(db, tr, bref);
                        ed.Regen();
                        tr.Commit();
                    }
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage(ex.Message);
            }
        }

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 12 of 23
chiefbraincloud
in reply to: Hallex

I forgot all about "\n".

 

Shame on me.  My lisp programming skills are getting too rusty.

Dave O.                                                                  Sig-Logos32.png
Message 13 of 23
Hallex
in reply to: chiefbraincloud

But you know many other stuffs,

Regards,

 

Oleg

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 14 of 23
Hallex
in reply to: klahie

What about Copy-Paste, just a quick code almost not tested

 

        [CommandMethod("copypaste", CommandFlags.Modal | CommandFlags.UsePickSet)]
        public void CopyPaste()
        {

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;

            Editor ed = doc.Editor;

            Matrix3d ucs = ed.CurrentUserCoordinateSystem;
            try
            {

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {

                    PromptEntityOptions peo = new PromptEntityOptions("\nSelect a block  >>");

                    peo.SetRejectMessage("\nSelect block only >>");

                    peo.AddAllowedClass(typeof(BlockReference), false);

                    PromptEntityResult res;

                    res = ed.GetEntity(peo);

                    if (res.Status != PromptStatus.OK)

                        return;

                    Entity ent = (Entity)tr.GetObject(res.ObjectId, OpenMode.ForRead);

                    if (ent == null) return;

                    ObjectIdCollection ids = new ObjectIdCollection();

                    ids.Add(ent.ObjectId);

                    ObjectId chkId = ent.ObjectId;

                    BlockReference bref = ent as BlockReference;

                    Point3d pt = Point3d.Origin;

                    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);

                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

                    PromptPointOptions pto = new PromptPointOptions("\nPick a block insertion point: ");

                    PromptPointResult ptres = ed.GetPoint(pto);

                    Point3d ipt=Point3d.Origin;

                    if (ptres.Status != PromptStatus.Cancel)
                    {
                        ipt = ptres.Value;
                    }

                    using (IdMapping map = new IdMapping())
                    {
                        db.DeepCloneObjects(ids, bref.BlockId, map, false);

                        ObjectId clid = map[bref.ObjectId].Value;

                        BlockReference brefclone = (BlockReference)tr.GetObject(clid, OpenMode.ForWrite);

                        brefclone.Position =ipt;

                    }

                    tr.Commit();

                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage(ex.Message);
            }

        }

 

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 15 of 23
klahie
in reply to: chiefbraincloud

EDIT: Wow, wow, wow, I was reading the first page and didn't see the second page Smiley LOL

 

That solved the second problem! Smiley Happy

 

How should I use chr(13)?

 

PromptPointOptions pto = new PromptPointOptions(chr(13) + "Pick a block insertion point: ");

 gives the same problem

 

Greets

Klaus

Message 16 of 23
chiefbraincloud
in reply to: klahie

Well, I am surprised the chr function is not automatically in c#, but anyway, Oleg's code reminded me of the appropriate way to send a newline in c# (and lisp)  use "\nPick a block insertion point: "

Dave O.                                                                  Sig-Logos32.png
Message 17 of 23
klahie
in reply to: chiefbraincloud

Smiley Very Happy That's great!

 

The block is pasted dreamlike. Smiley Happy

 

BUT: When I refresh my blocklist, I havn't got a new entry for the pasted block. That means, in my list is only the old entry. 

 

public void setBlockList()
{
   BlockList = new List<String>();
   using (tr = db.TransactionManager.StartTransaction())
   {
      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
      foreach (ObjectId objId in bt)
      {

         BlockTableRecord btr = (BlockTableRecord)tr.GetObject(objId, OpenMode.ForRead);
         if (isAttDef(btr))
         {
            BlockList.Add(btr.Name);
         }
      }
   }
}

 That is my Blocklist-Function.

 

Do you know why it fails?

 

Greets

Klaus

Message 18 of 23
Hallex
in reply to: klahie

I didn't see nothing wrong with your code

Perhaps you might be want to refresh BlockList first

Something like:

        public void setBlockList()
        {
          List<String>  BlockList = new List<String>();
          Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
          Database db = doc.Database;
          Editor ed = doc.Editor;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            { 
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                foreach (ObjectId objId in bt)
                {
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(objId, OpenMode.ForRead);
                    if (btr.HasAttributeDefinitions)
                   // if (isAttDef(btr))
                    { 
                        BlockList.Add(btr.Name); 
                    } 
                }
            }
            foreach (string bname in BlockList)
            {
                ed.WriteMessage("\n{0}", bname);
            }

        }

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 19 of 23
klahie
in reply to: Hallex

I call my setBlockList()-Function direkt after the Commit. No Copy-Blockname..... Smiley Indifferent 

 

In the commandline (

ed.WriteMessage("\n{0}", bname);

) is only one blockname too, the blockname of blk (using the function you posted).

 

Greets

Klaus

Message 20 of 23
chiefbraincloud
in reply to: klahie

I don't think it is failing.

 

I think you still don't quite understand the difference between a BlockReference and a BlockTableRecord.

 

You are listing BlockTableRecords in your Block List.  When you copy/paste, you are creating a new BlockReference pointing to the same BlockTableRecord as the original copied BlockReference.  This does not create a new BlockTableRecord.

 

There can only be one BlockTableRecord with a given name, but there can (and usually will be) many BlockReferences that point to same BlockTableRecord.  That is really the point of Blocks, that you store the definition of the block (BlockTableRecord) once in the BlockTable, and then you create multiple instances of the block (BlockReference) as many times as needed in the Model or Paper spaces.  This saves space in the database and keeps the drawing size smaller, because the BlockReferences just contain a pointer to the BlockTableRecord, instead of containing all of the information for the lines, polylines and whatever other geometry they might contain.

 

I'm still looking for the old post of mine that explains the difference in greater detail...

Dave O.                                                                  Sig-Logos32.png

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