Author Topic: Copy blocks in same drawing  (Read 2417 times)

0 Members and 1 Guest are viewing this topic.

shers

  • Guest
Copy blocks in same drawing
« on: June 30, 2015, 01:39:45 PM »
Hi,

I'm trying to copy a particular block in a drawing opened in side database, and paste it at equal distances n times. Here's my code:

Code: [Select]

try
            {
                using (db)
                {
                    db.ReadDwgFile(@"-------.dwg", FileOpenMode.OpenForReadAndAllShare, false, null);
                    db.CloseInput(true);

                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        BlockReference br;
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);

                        foreach (ObjectId id in btr)
                        {
                            Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);

                            if (ent is Line)
                            {
                                Line line = (Line)ent;
                                if (line.Handle.ToString() == "3D5")
                                {
                                    Point3d linePt = new Point3d();
                                    linePt = line.StartPoint;
                                    ed.WriteMessage(linePt.ToString());
                                   
                                    ObjectId brId = ObjectId.Null;

                                    string blockFile = @"--------.dwg";
                                    string blockName = Path.GetFileNameWithoutExtension(blockFile);
                                   
                                    using (Database tempDb =  new Database(false, true))
                                    {
                                        tempDb.ReadDwgFile(blockFile, FileShare.Read, true, null);
                                        brId = db.Insert(blockName, tempDb, false);
                                        tempDb.Dispose();
                                     br = new BlockReference(linePt, brId);
                                        //tr.AddNewlyCreatedDBObject(br, true);
                                    }
                                }
                            }
                        }
                        tr.Commit();
                    }
                    db.SaveAs(@"----------.dwg", DwgVersion.Current);

                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage(ex.ToString());
            }

Unfortunately, it doesn't work. Please help.

Thanks

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: Copy blocks in same drawing
« Reply #1 on: July 01, 2015, 07:31:33 AM »
You've got to add your new BlockReference to ModelSpace.
Revit 2019, AMEP 2019 64bit Win 10

shers

  • Guest
Re: Copy blocks in same drawing
« Reply #2 on: July 03, 2015, 12:17:15 AM »
Thanks for your reply.

I have a new code now. Here it is, which adds the new block reference to the database.

Code - C#: [Select]
  1. using (Database db = new Database(false, true))
  2.                 {
  3.                     db.ReadDwgFile(@"--------------------------y.dwg", FileOpenMode.OpenForReadAndAllShare, false, null);
  4.                     db.CloseInput(true);
  5.  
  6.                     using (Transaction tr = db.TransactionManager.StartTransaction())
  7.                     {
  8.                         BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  9.  
  10.                         BlockTableRecord btrec = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  11.  
  12.                         foreach (ObjectId id in btrec)
  13.                         {
  14.                             Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
  15.  
  16.                             if (ent is BlockReference)
  17.                             {
  18.                                 BlockReference bref = (BlockReference)tr.GetObject(ent.ObjectId, OpenMode.ForRead);
  19.  
  20.                                 if (bref.Name == "XYZ")
  21.                                 {
  22.                                    
  23.                                     btrec.AppendEntity(bref); <-----------Error
  24.                                     tr.AddNewlyCreatedDBObject(bref, true);
  25.                                 }
  26.                                 db.TransactionManager.QueueForGraphicsFlush();
  27.                             }
  28.                         }
  29.                        
  30.                         tr.Commit();
  31.                     }
  32.                     db1.SaveAs(@"1.dwg",DwgVersion.Current);
  33.                 }
  34.             }
  35.             catch(System.Exception ex)
  36.             {
  37.                 MessageBox.Show(ex.ToString());
  38.             }
  39.  

The error I get is eAlreadyInDb. Please help.

Thanks


edit:kdub -> code=csharp
« Last Edit: July 03, 2015, 01:25:12 AM by Kerry »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Copy blocks in same drawing
« Reply #3 on: July 03, 2015, 02:35:37 AM »
Hi,

You have to create a copy of the block reference you found (which is already in the database) and add this copy to the database.
Have a look here.
Speaking English as a French Frog

shers

  • Guest
Re: Copy blocks in same drawing
« Reply #4 on: July 03, 2015, 04:13:39 AM »
The link you have provided is only for entities. But I am looking for block references, where in I have to consider the insertion point and the name.

Thanks

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Copy blocks in same drawing
« Reply #5 on: July 03, 2015, 07:56:41 AM »
The link you have provided is only for entities. But I am looking for block references, where in I have to consider the insertion point and the name.

Thanks

Did you try this way with block references (which are entities) ? if so, could you provide you test code ?
Speaking English as a French Frog

shers

  • Guest
Re: Copy blocks in same drawing
« Reply #6 on: July 04, 2015, 02:16:20 AM »
Code: [Select]
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
 
                            if (ent is BlockReference)
                            {
                                BlockReference bref = (BlockReference)tr.GetObject(ent.ObjectId, OpenMode.ForRead);

Is this what you meant? It is in the above code.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Copy blocks in same drawing
« Reply #7 on: July 04, 2015, 04:51:38 AM »
Try the following CopyBlock() method.
It uses the cloning process shown in the link I provided.
It requires  3 arguments:
  • the database in which some block references to copy are supposed to be inserted and have to be copied, this can be either a side database or the active document one (which makes testing easier) ;
  • the name of the block to search and copy ;
  • a transformation matrix (Matrix3d instance) to apply to the copied block repeferences

Code - C#: [Select]
  1.         private void CopyBlock(Database db, string blockName, Matrix3d xform)
  2.         {
  3.             using (Transaction tr = db.TransactionManager.StartTransaction())
  4.             {
  5.                 BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(
  6.                     SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite);
  7.                 RXClass blockRefClass = RXClass.GetClass(typeof(BlockReference));
  8.                 List<BlockReference> clones = new List<BlockReference>();
  9.                 foreach (ObjectId id in modelSpace)
  10.                 {
  11.                     if (id.ObjectClass == blockRefClass)
  12.                     {
  13.                         BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
  14.                         if (br.Name == blockName)
  15.                         {
  16.                             clones.Add((BlockReference)br.Clone());
  17.                         }
  18.                     }
  19.                 }
  20.                 foreach (BlockReference clone in clones)
  21.                 {
  22.                     clone.TransformBy(xform);
  23.                     modelSpace.AppendEntity(clone);
  24.                     tr.AddNewlyCreatedDBObject(clone, true);
  25.                 }
  26.                 tr.Commit();
  27.             }
  28.         }

calling example (copies "XYZ" references and moves them 15 units along X axis):
Code - C#: [Select]
  1. Database db = HostApplicationServices.WorkingDatabase;
  2. Matrix3d xform = Matrix3d.Displacement(new Vector3d(15.0, 00.0, 0.0));
  3. CopyBlock(db, "XYZ", xform);
Speaking English as a French Frog

shers

  • Guest
Re: Copy blocks in same drawing
« Reply #8 on: July 04, 2015, 05:29:01 AM »
Amazing!! This is what exactly I wanted. Thank you so much!! You saved my life.

I also want to attach a line to the block on adding the second time onward. I will work on it and will share the code.

Thanks  :-)