Create Block around existing Entities (No User Input)

Create Block around existing Entities (No User Input)

mcoH3VZV
Advocate Advocate
631 Views
2 Replies
Message 1 of 3

Create Block around existing Entities (No User Input)

mcoH3VZV
Advocate
Advocate

Hi,

 

I am wondering how I can block a group of entities (just circles, rectangles, etc) where the entities already exist in a drawing. Attached is the code I have so far, but it just does nothing.

 

The tr transaction is committed just after this method.

 

Am I missing a piece?  Thank you,

0 Likes
Accepted solutions (1)
632 Views
2 Replies
Replies (2)
Message 2 of 3

_gile
Consultant
Consultant

Hi,

Here's an example which mimics the BLOCK command.

        [CommandMethod("MAKEBLOCK")]
        public static void MakeBlockCmd()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var selection = ed.GetSelection();
            if (selection.Status != PromptStatus.OK)
                return;
            var ids = new ObjectIdCollection(selection.Value.GetObjectIds());
            var pointResult = ed.GetPoint("\nSpecify insertion point: ");
            if (pointResult.Status != PromptStatus.OK)
                return;
            var point = pointResult.Value.TransformBy(ed.CurrentUserCoordinateSystem);
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (bt.Has("NEW_BLOCK"))
                    return;

                // create a new block definition
                tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
                var btr = new BlockTableRecord();
                btr.Name = "NEW_BLOCK";
                var btrId = bt.Add(btr);
                tr.AddNewlyCreatedDBObject(btr, true);

                // add copies of selected entities to the block definition
                var mapping = new IdMapping();
                db.DeepCloneObjects(ids, btrId, mapping, false);

                // displace the clones within the block definition
                // and erase the source entities
                var xform = Matrix3d.Displacement(point.GetAsVector().Negate());
                foreach (ObjectId id in ids)
                {
                    var pair = mapping[id];
                    if (pair.IsCloned)
                    {
                        var clone = (Entity)tr.GetObject(pair.Value, OpenMode.ForWrite);
                        clone.TransformBy(xform);
                    }
                    var entity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                    entity.Erase();
                }

                // insert the newly created block
                var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                var br = new BlockReference(point, btrId);
                curSpace.AppendEntity(br);
                tr.AddNewlyCreatedDBObject(br, true);
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 3

_gile
Consultant
Consultant
Accepted solution

Closer to your request (No User Input):

private static void MakeBlock(Database db, ObjectIdCollection ids, Point3d insertionPoint, bool eraseSourceEntities)
        {
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (bt.Has("NEW_BLOCK"))
                    return;

                // create a new block definition
                tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
                var btr = new BlockTableRecord();
                btr.Name = "NEW_BLOCK";
                var btrId = bt.Add(btr);
                tr.AddNewlyCreatedDBObject(btr, true);

                // add copies of selected entities to the block definition
                var mapping = new IdMapping();
                db.DeepCloneObjects(ids, btrId, mapping, false);

                // displace the clones within the block definition
                var xform = Matrix3d.Displacement(insertionPoint.GetAsVector().Negate());
                foreach (ObjectId id in ids)
                {
                    var pair = mapping[id];
                    if (pair.IsCloned)
                    {
                        var clone = (Entity)tr.GetObject(pair.Value, OpenMode.ForWrite);
                        clone.TransformBy(xform);
                    }
                    var entity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                    entity.Erase();
                }

                // insert the newly created block
                ObjectId ownerId = ((Entity)tr.GetObject(ids[0], OpenMode.ForRead)).OwnerId;
                var space = (BlockTableRecord)tr.GetObject(ownerId, OpenMode.ForWrite);
                var br = new BlockReference(insertionPoint, btrId);
                space.AppendEntity(br);
                tr.AddNewlyCreatedDBObject(br, true);

                // erase source entities
                if (eraseSourceEntities)
                {
                    foreach (ObjectId id in ids)
                    {
                        var entity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                        entity.Erase();
                    }
                }
                tr.Commit();
            }
        }

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub