Author Topic: Copy Dynamic Block  (Read 1981 times)

0 Members and 1 Guest are viewing this topic.

pedroantonio

  • Guest
Copy Dynamic Block
« on: November 07, 2011, 01:10:24 PM »
I need a help with copying a dynamic block inside a drawing (with all already existing settings like atribs, visibilities)
 
I want to programmatically copy a block which is already placed in drawing.
Basically I wanna imitate copy with base point command... Copied block must look the same as original block (same attributes, same visibility state, same layer, same text etc)

As I understand that involves Deep Cloning and creating a new database but I really don't know where to start?
Any help appreciated...

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Copy Dynamic Block
« Reply #1 on: November 07, 2011, 02:15:14 PM »
DeepCloneObjects() seems to work fine for the dymanic properties
 
Code: [Select]
         [CommandMethod("CopyDynamicBlock")]
         public void CopyDynamicBlock()
         {
             Document doc = Application.DocumentManager.MdiActiveDocument;
             Database db = doc.Database;
             Editor ed = doc.Editor;
             PromptEntityOptions peo = new PromptEntityOptions("\nSelect Block");
             peo.SetRejectMessage("\nNot a Block Reference");
             peo.AddAllowedClass(typeof(BlockReference), true);
             using (Transaction trx = db.TransactionManager.StartTransaction())
             {
                 BlockTable bt = (BlockTable)trx.GetObject(db.BlockTableId, OpenMode.ForRead);
                 BlockTableRecord modelSpace = (BlockTableRecord)trx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                 
                 ObjectIdCollection ids = new ObjectIdCollection();
                 
                 ids.Add(ed.GetEntity(peo).ObjectId);
                 IdMapping map = new IdMapping();
                 db.DeepCloneObjects(ids, modelSpace.ObjectId, map, false);
                 
                 foreach (IdPair pair in map)
                 {
                     if (pair.Value.ObjectClass == RXClass.GetClass(typeof(BlockReference)))
                     {
                         BlockReference newBref = (BlockReference)trx.GetObject(pair.Value, OpenMode.ForWrite);
                         newBref.Position = ed.GetPoint("\nSelect Point").Value;
                     }
                 }
                 trx.Commit();
             }
         }

 

pedroantonio

  • Guest
Re: Copy Dynamic Block
« Reply #2 on: November 09, 2011, 02:39:55 PM »
Thanks Jeff!

I am almost there.
Block is copied, with dynamic properties, geometry and attributes(text) - everything is copied
but attributes remains at original position :(
Attribs are not moved to new point that I pick as insertion point for new block...

Can you help

pedroantonio

  • Guest
Re: Copy Dynamic Block
« Reply #3 on: November 11, 2011, 12:24:00 PM »
small bump....
:(

Sadly text stays at original block position and not on new picked point???

pedroantonio

  • Guest
Re: Copy Dynamic Block
« Reply #4 on: November 11, 2011, 01:07:29 PM »
I have find out that after I copy a block and attributes are copied but not on new position if I then do ATTSYNC the attributts will "align" with block.

I still does not know how to correct above code to work correctly


Jeff H

  • Needs a day job
  • Posts: 6144
Re: Copy Dynamic Block
« Reply #5 on: November 11, 2011, 01:23:27 PM »
I will post a solution later when I have time or someone else probably has a better solution

pedroantonio

  • Guest
Re: Copy Dynamic Block
« Reply #6 on: November 11, 2011, 01:26:03 PM »
jeff I will really appreciate it if you find time... thanks in advance

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Copy Dynamic Block
« Reply #7 on: November 14, 2011, 06:24:39 PM »
This is probably not the best but in a hurry and might give you a idea.
 
 
 
Code: [Select]
        [CommandMethod("CopyDynamicBlock")]
        public void CopyDynamicBlock()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect Block");
            peo.SetRejectMessage("\nNot a Block Reference");
            peo.AddAllowedClass(typeof(BlockReference), true);

            using (Transaction trx = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)trx.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord modelSpace = (BlockTableRecord)trx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
 
                ObjectIdCollection ids = new ObjectIdCollection();
                ids.Add(ed.GetEntity(peo).ObjectId);
                IdMapping map = new IdMapping();
                db.DeepCloneObjects(ids, modelSpace.ObjectId, map, false);
 
                BlockReference newBref = null;
                BlockTableRecord blockBtr = null;

                foreach (IdPair pair in map)
                {
                    if (pair.Value.ObjectClass == RXClass.GetClass(typeof(BlockReference)))
                    {
                        newBref = (BlockReference)trx.GetObject(pair.Value, OpenMode.ForWrite);
                        newBref.Position = ed.GetPoint("\nSelect Point").Value;
                        blockBtr = (BlockTableRecord)trx.GetObject(newBref.BlockTableRecord, OpenMode.ForRead);
                    }
                }
 
                foreach (ObjectId id in blockBtr)
                {                 
               
                    if (id.ObjectClass == RXClass.GetClass(typeof(AttributeDefinition)))
                    {
                        AttributeDefinition attDef = (AttributeDefinition)trx.GetObject(id, OpenMode.ForRead);
                        foreach (ObjectId refId in newBref.AttributeCollection)
                        {
                            AttributeReference attRef = (AttributeReference)trx.GetObject(refId, OpenMode.ForWrite);
                            if (attRef.Tag == attDef.Tag)
                            {
                                attRef.Position = attDef.Position;
                                attRef.SetAttributeFromBlock(newBref.BlockTransform);
                           
                            }
 
                       
                        }
                    }
               
                }
                trx.Commit();
            }
        }