Drawings SDK Developer Guide > Working with .dwg Files > Introduction > Basics of Database Operations and Database Objects > Overview of Blocks
Overview of Blocks

Entities in the database belong to blocks which are represented by OdDbBlockTableRecord objects. OdBlockTableRecord is a container storing a list of entities. Each entity can be owned by one OdDbBlockTableRecord only. The block table in a newly created database has three predefined records, *MODEL_SPACE, *PAPER_SPACE, and *PAPER_SPACE0, which represent model space and the two pre-defined paper space layouts. Additional records are added whenever the user creates new blocks (block records).

OdDbBlockTableRecord can be called a block definition and the block table can be called the block definition table. The geometry defined by a block definition can be inserted into a drawing using block reference entities. Block references are represented by OdDbBlockReference objects and store transformation (position, scale, rotation), other properties, and reference to a block definition. This allows geometry to be defined once and inserted into a drawing multiple times in different positions, orientation, etc.

For example, car wheel geometry can be defined once and inserted four (or more) times in a drawing to represent a car.

Block definitions also can contain block references to other blocks; block references can be nested. For example, a drawing representing a car parking site can contain multiple insertions of blocks that represent a car, and that car block can contain 4 references to a wheel block.

Creating blocks

To create a new instance of the Block Table Record object, declare a smart pointer to the record object and use the pseudo-constructor of the corresponding type of record object:


OdDbBlockTableRecordPtr pBTR = OdDbBlockTableRecord::createObject();

After the creation, the name of the OdDbBlockTableRecord object must be set, and then the object can be added into the database by adding it to the block table:


OdDbBlockTableRecordPtr pBTR = OdDbBlockTableRecord::createObject();
pBTR->setName("NewBlock");
OdDbObjectId btrId = pTable->add(pBTR);

Appending entities to a block

To append entities to blocks, OdDbBlockTableRecord objects contain the appendOdDbEntity() method. For example, to append a line entity to the block:


pBTR->appendOdDbEntity(pLine);

At this point the entity becomes a database resident.

Inserting blocks into the drawing

To insert the block into a drawing, Block Reference objects should be created for block definitions. Generally, the procedure of inserting blocks into a drawing consists of the following steps:

  1. Create a block reference entity (OdDbBlockReference object).
  2. Call the setBlockTableRecord() method to specify the object ID of the referenced block table record.
  3. Append the block reference to a block table record (model space, paper space, or some other block).

The following example demonstrates an implementation of this procedure:


  OdDbObjectId brefId;
  
  /**********************************************************************/
  /* Add the block reference to the BlockTableRecord                    */
  /**********************************************************************/
  OdDbBlockReferencePtr pBlkRef = OdDbBlockReference::createObject();
  pBlkRef->setDatabaseDefaults(bBTR->database());
  brefId = bBTR->appendOdDbEntity(pBlkRef);

  /**********************************************************************/
  /* Set some properties                                                */
  /**********************************************************************/
  pBlkRef->setBlockTableRecord(btrId);
  pBlkRef->setScaleFactors(OdGeScale3d(xscale, yscale, 1.0));

One block can be inserted multiple times (BlockTableRecord contains a number of references). You can get a list of Object IDs of all corresponding block references for the block using the getBlockReferenceIds() method:


OdDbObjectIdArray bRefArray;
block->getBlockReferenceIds(bRefArray);

Iterating through entities inside block

To iterate through entities that belong to a block, the mechanism of iterators is used (see also Accessing Database Objects).

An Iterator object is created for the Block Table Record by the newIterator method and intended for traversing between the entities which are inside the block:


OdDbObjectIteratorPtr OdDbBlockTableRecord::newIterator(bool atBeginning = true, bool skipDeleted = true, bool sorted = false) const; 

The following routine illustrates how to iterate through entities of the Model Space block:


  /********************************************************************/
  /* Get a SmartPointer to a new ObjectIterator                       */
  /********************************************************************/
  OdDbObjectIteratorPtr pEntIter = pModelSpace->newIterator();
    
  /********************************************************************/
  /* Step through the BlockTableRecord                                */
  /********************************************************************/
  for (; !pEntIter->done(); pEntIter->step())
  {
    /********************************************************************/
    /* Dump the Entity                                                  */
    /********************************************************************/
    OdDbEntityPtr pEntity = pEntIter->entity();
    printf("ObjectID: %lx\n", pEntity->objectId());
    printf("Class name: %ls\n", toString(pEntity->isA()).c_str());
  }

Example of creating blocks

The following two functions demonstrate creating a block and adding block references.


/************************************************************************/
/* Add a block definition to the specified database                     */
/*                                                                      */
/* Note that the BlockTable and BlockTableRecord are implicitly closed  */
/* when before this function returns.                                   */
/************************************************************************/
OdDbObjectId addBlock(OdDbDatabase* pDb, const OdString& name)
{
  OdDbObjectId            id;
  OdDbBlockTablePtr       pTable  = pDb->getBlockTableId().safeOpenObject(OdDb::kForWrite);
  OdDbBlockTableRecordPtr pRecord = OdDbBlockTableRecord::createObject();
  
  /**********************************************************************/
  /* Block must have a name before adding it to the table.              */
  /**********************************************************************/
  pRecord->setName(name);
  
  /**********************************************************************/
  /* Add the record to the table.                                       */
  /**********************************************************************/
  id = pTable->add(pRecord);
  return id;
}

/************************************************************************/
/* Add a block reference to the specified BlockTableRecord              */
/************************************************************************/
OdDbObjectId addInsert(OdDbBlockTableRecord* bBTR,
                                 const OdDbObjectId& btrId, 
                                 double xscale,               
                                 double yscale)               
{
  OdDbObjectId brefId;
  
  /**********************************************************************/
  /* Add the block reference to the BlockTableRecord                    */
  /**********************************************************************/
  OdDbBlockReferencePtr pBlkRef = OdDbBlockReference::createObject();
  pBlkRef->setDatabaseDefaults(bBTR->database());
  brefId = bBTR->appendOdDbEntity(pBlkRef);

  /**********************************************************************/
  /* Set some properties                                                */
  /**********************************************************************/
  pBlkRef->setBlockTableRecord(btrId);
  pBlkRef->setScaleFactors(OdGeScale3d(xscale, yscale, 1.0));
  return brefId;
}

Anonymous blocks

There are several special types of blocks called anonymous blocks which are used for supporting dynamic blocks, hatch patterns, dimensions, and groups. These blocks have names with a special format that begins with a prefix followed by the block number: *TN, where T is the type of the anonymous block and N is the integer number of the block.

Prefix Anonymous Block Type
*UN Uniformly scaled blocks
*EN Non-uniformly scaled blocks
*DN Dimensions
*AN Groups

Anonymous blocks are just containers for graphical entities that are normally hidden from the user. Although not created with a graphical purpose, they appear in the database and are very common. Every dynamic block or dimension has anonymous blocks, as well as tables, associative arrays, etc. Anonymous blocks can also appear, for example, when a user copies geometry to the clipboard and then pastes it as a block.

Uniformly scaled blocks can be exploded.

Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.