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

How to add new objects to a exist blocktablerecord?

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
swaywood
262 Views, 2 Replies

How to add new objects to a exist blocktablerecord?

Hi everyone,

I want to clear all objects in an existing blocktablerecord,

add several new objects, and redefine the block.

I wrote some code according to my own ideas,

but the new block generated is an empty block.

Please help me find out what the problem is.

Thank you

 

    public static ObjectId AddBlockTableRecord(this Database db, string blockName, Point3d Position, params ObjectId[] ids)
    {
      BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForRead);
      BlockTableRecord btr;
      using (Transaction trans = db.TransactionManager.StartTransaction())
      {
        if (!bt.Has(blockName)) 
        {
          btr = new BlockTableRecord();
          btr.Name = blockName;
        }
        else
        {
          btr = (BlockTableRecord)trans.GetObject(bt[blockName], OpenMode.ForWrite);
          foreach (ObjectId id in btr)
          {
            Entity ent = (Entity)trans.GetObject(id, OpenMode.ForWrite);
            ent.Erase();
          }
        }
        btr.Explodable = true;
        btr.Origin = Position;

        foreach (ObjectId id in ids)
        {
          Entity ent = id.Clone<Entity>();
          if (ent.IsNewObject)
          {
            btr.AppendEntity(ent);
          }
        }
        bt.UpgradeOpen();
        if (!bt.Has(blockName))
        {
          bt.Add(btr);
          db.TransactionManager.AddNewlyCreatedDBObject(btr, true);
        }
        else
        {

        }
        foreach (ObjectId id in ids)
        {
          if (!id.IsNull)
          {
            id.GetObject(OpenMode.ForWrite).Erase(true);
          }
        }
        btr.DowngradeOpen();
        bt.DowngradeOpen();
        trans.Commit();
      }
      return bt[blockName];
    }
2 REPLIES 2
Message 2 of 3
_gile
in reply to: swaywood

Hi,

 

You should use the Database.DeepCloneObject method instead of the RXObjectClone one.

IMO, it's also better to move the entities within the block definition instead of defining the BlockTableRecord.Origin property.

And also, you should either strart a new transaction or use the TopTransaction, but not mix both.

public static ObjectId AddBlockTableRecord(this Database db, string blockName, Point3d Position, params ObjectId[] ids)
        {
            ObjectId btrId;
            BlockTableRecord btr;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                var bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (!bt.Has(blockName))
                {
                    btr = new BlockTableRecord();
                    btr.Name = blockName;
                    trans.GetObject(db.BlockTableId, OpenMode.ForWrite);
                    btrId = bt.Add(btr);
                    trans.AddNewlyCreatedDBObject(btr, true);
                }
                else
                {
                    btrId = bt[blockName];
                    btr = (BlockTableRecord)trans.GetObject(btrId, OpenMode.ForWrite);
                    foreach (ObjectId id in btr)
                    {
                        trans.GetObject(id, OpenMode.ForWrite).Erase();
                    }
                }
                btr.Explodable = true;

                var oIds = new ObjectIdCollection(ids);
                var mapping = new IdMapping();
                db.DeepCloneObjects(oIds, btrId, mapping, false);
                var displacement = Matrix3d.Displacement(Position.GetAsVector().Negate());
                foreach (IdPair pair in mapping)
                {
                    if (pair.IsCloned && pair.IsPrimary)
                    {
                        var entity = (Entity)trans.GetObject(pair.Value, OpenMode.ForWrite);
                        entity.TransformBy(displacement);
                    }
                }

                foreach (ObjectId id in ids)
                {
                    if (!id.IsNull)
                    {
                        id.GetObject(OpenMode.ForWrite).Erase(true);
                    }
                }
                trans.Commit();
            }
            return btrId;
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 3
swaywood
in reply to: _gile

thanks Giles

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

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report