3

I'm trying to write a method that prompts the user to select all the entities they want to combine into a block and then joins them together into a block and returns the block reference. Right now it looks like this.

        /// <summary>
        /// Returns all entities in an AutoCAD drawing in a list
        /// </summary>
        public static List<Entity> GetEntitiesInDrawing()
        {
            List<Entity> entitiesToReturn = new List<Entity>(); //Blocks that will be returned
            Transaction tr = _database.TransactionManager.StartTransaction();
            DocumentLock docLock = _activeDocument.LockDocument();

            using (tr)
            using (docLock)
            {
                BlockTableRecord blockTableRecord = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(_database), OpenMode.ForRead);
                foreach (ObjectId id in blockTableRecord)
                {
                    try
                    {
                        Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                        entitiesToReturn.Add(ent);
                    }
                    catch (InvalidCastException)
                    {
                        continue;
                    }
                }
            }
            return entitiesToReturn;
        }
        /// <summary>
        /// Prompts the user for a number of entities and then joins them into a block
        /// </summary>
        public static BlockReference JoinEntities()
        {
            BlockReference blkToReturn = null;
            List<Entity> entitiesToJoin = PromptUserForEntities();
            foreach (Entity ent in entitiesToJoin)
            {
                // ToDo: Join entities into blkToReturn
            }
            return blkToReturn;

        }

My problem is that I have no idea how or if it is possible to take a list of entities and join them into a blockreference.

Nick Gilbert
  • 4,159
  • 8
  • 43
  • 90

2 Answers2

4

Kean covered this in his blog: Creating an AutoCAD block using .NET

Miiir
  • 731
  • 1
  • 9
  • 12
3

In summary:

  1. use Editor.Getselection so the user can select the entities
  2. create a blockTableRecord (BTR) on the BlockTable (from Database.BlockTableId)
  3. append all entities to the newly created BTR, here you may need to create new entities or move ownership (see BlockTableRecord.AssumeOwnershipOf method)
  4. create a new blockreference that points to the BTR
  5. open the Model Space (or Paper Space) and append the block reference to it
  6. optional: erase all original entities from the model space (avoid duplicated), if you haven't changed ownership

The post mentioned can help, but it creates new entities (and doesn't move from model to the block definition (step #3)

Augusto Goncalves
  • 8,493
  • 2
  • 17
  • 44
  • I followed that procedure and now its throwing an eAlreadyInDb error every time I try to append an entity to the new BTR. You can see my full code here http://forums.autodesk.com/t5/net/joining-entities-into-a-block-programmatically/m-p/5651349/highlight/false#M44682 at post #4 – Nick Gilbert May 26 '15 at 20:32
  • that's expected: you cannot append and entity to 2 block table records... see my suggestion above, #3, try with AssumeOwnershipOf also, a block table record cannot contain entities until is already on the database... so add the BTR first, then move the entities to it. – Augusto Goncalves May 27 '15 at 22:27