• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Active Contributor
    Posts: 40
    Registered: ‎09-04-2012
    Accepted Solution

    Copyiing Block Definition and Block references

    175 Views, 3 Replies
    02-06-2013 02:53 PM

    Hello.

     

    I have a simple case.

     

    I have drawing A and drawing B.

    I have a block definition (block table record) in A as well as block references to said block definition in the model space.

    The block definition contains 2 texts that change from reference to reference when they are created.

     

    What I need to do is copy the references to certain block definition into drawing B.

    I wouldn't care about the block definition being in drawing B but my logic dictates that to copy the block references I would first have to copy the block definition, and that's what I have done, and it works just fine.

    When trying to add the block references (by going through the model space and seeing which Entities match my criteria) it seems to work fine but the references don't show on screen. the layer that the references belong to does get created even when it was not there before creation. This is my code base on an artile by Kean(article):

    Again, the block definition is there, but the references are not showing u.u

          DocumentCollection dm = Application.DocumentManager;
          Editor ed = dm.MdiActiveDocument.Editor;
          Database destDb = dm.MdiActiveDocument.Database;
          Database sourceDb = new Database(false, true);
    
            // Read the DWG into a side database
            sourceDb.ReadDwgFile(orignalDrawingFullPath, System.IO.FileShare.Read, true, "");        
            // Create a variable to store the list of block identifiers
            ObjectIdCollection blockIds1 = new ObjectIdCollection();
            ObjectIdCollection blockIds2 = new ObjectIdCollection();
            Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = sourceDb.TransactionManager;
            using (Transaction myT = tm.StartTransaction())
            {
              // Open the block table
              BlockTable bt = (BlockTable)tm.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);
              // Check each block in the block table
              foreach (ObjectId btrId in bt)
              {
                BlockTableRecord btr = (BlockTableRecord)tm.GetObject(btrId, OpenMode.ForRead, false);
                // Only add named & non-layout blocks to the copy list
                if (btr.Name == "*MODEL_SPACE")
                {
                  foreach (ObjectId item in btr)
                  {
                    if (item.ObjectClass.Name == "AcDbBlockReference")
                    {
                      BlockReference tempBR = (BlockReference)tm.GetObject(item, OpenMode.ForRead, false);
                      if (tempBR.Name == "losa-ne")
                        blockIds2.Add(item);
                    }
                  }
                }
                if (!btr.IsAnonymous && !btr.IsLayout && btr.Name == "losa-ne")
                  blockIds1.Add(btrId);
                btr.Dispose();
              }
    
            }
    
            // Copy blocks from source to destination database
            IdMapping mapping1 = new IdMapping();
            IdMapping mapping2 = new IdMapping();
            sourceDb.WblockCloneObjects(blockIds1, destDb.BlockTableId, mapping1, DuplicateRecordCloning.Replace, true);
            sourceDb.WblockCloneObjects(blockIds2, destDb.BlockTableId, mapping2, DuplicateRecordCloning.Replace, false);

     

     

     

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,167
    Registered: ‎04-09-2008

    Re: Copyiing Block Definition and Block references

    02-06-2013 10:54 PM in reply to: DouceDeux

    Error in this code:

    sourceDb.WblockCloneObjects(blockIds2, destDb.BlockTableId, mapping2, DuplicateRecordCloning.Replace, false);

    You trying to add BlockReferences not to BlockTableRecord (for example, ModelSpace) but to BlockTable. BlockTable can has only BlockTableRecord's but not BlockReference's.


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Active Contributor
    Posts: 40
    Registered: ‎09-04-2012

    Re: Copyiing Block Definition and Block references

    02-07-2013 07:23 AM in reply to: Alexander.Rivilis

    I had to add this code:

    ObjectId modelSpaceId = new ObjectId();
    
    using(Transaction newTran = destDb.TransactionManager.StartTransaction())
    {
      BlockTable newBT = newTran.GetObject(destDb.BlockTableId, OpenMode.ForRead) as BlockTable;
      foreach (ObjectId BTR in newBT)
      {
        BlockTableRecord newBTR = newTran.GetObject(BTR, OpenMode.ForRead) as BlockTableRecord;
        //Used .ToUpper() because the name of the BTR is actually "*Model_Space" and not "*MODEL_SPACE"
        //Could as well just compared to "*MODEL_SPACE"
        if (newBTR.Name.ToUpper() == "*MODEL_SPACE")
        {
          modelSpaceId = BTR;
          newBTR.Dispose();
          break;
        }
        newBTR.Dispose();
      }
    }            }
                newBTR.Dispose();
              }
    	      }

    There was a problem when saving, AutoCAD would crash, so I try changing the following lines and it worked, it saved without a problem.

    sourceDb.WblockCloneObjects(blockIds1, destDb.BlockTableId, mapping1, DuplicateRecordCloning.Replace, false);
            sourceDb.WblockCloneObjects(blockIds2, modelSpaceId, mapping2, DuplicateRecordCloning.Replace, false);

     

     I'm planning to adapt this for use on a referenced drawing, that would mean accessing a table record instead of a side database. The use of that would be the manipulation of individual objects inside the reference block. But to make the changes persistent in the drawing, an event would have to be added to check the insides of the blockreference for the drawing against a dictionary or something like that. I'll update the post when I have something.

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,167
    Registered: ‎04-09-2008

    Re: Copyiing Block Definition and Block references

    02-07-2013 07:33 AM in reply to: DouceDeux

    Maybe this code looks better:

    modelSpaceId = newBT[BlockTableRecord.ModelSpace];

    ?


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.