Finding openings attached to a wall

Alexey Abramovsky

April 27, 2017

In Teigha Architecture, objects can be attached to other objects. Such connections are handled by special anchor objects which are stored in a .dwg file just like any other object.

An anchor is represented by the base class AECDbAnchor. The meaning of the connection between objects can be different, for example, windows inserted in a wall or a schedule table attached to an object. Each type of connection is handled by a subclass of AECDbAnchor which implements connection semantics.

These connections are called “relations.” How can we see these relations in a drawing? For example, let’s look at a wall with windows:

The wall is automatically cut in places where windows are inserted. This means that the wall knows about the openings attached to it. If we move the wall, openings move automatically:

This also means that widows know that they are inserted in a wall. Relation “smth is attached to a wall” is handled by the AECDbAnchorEntToWall class and its subclasses.

How it works

In Teigha Architecture there is a special global object called a relation graph. It uses anchor objects to determine relations between objects. When a wall is modified, the relation graph goes through the list of objects related to the wall and calls for each object’s recalculation. Objects use their anchors to recalculate their new positions.

Example

How to find objects attached to a certain wall?

OdDbObjectId idWall; // will be looking for openings attached to wall with this id
OdDbDatabasePtr pDb; // loaded database
// we open and iterate all model space objects (objects on the drawing)
OdDbObjectId idModelSpace = pDb->getModelSpaceId();
OdDbBlockTableRecordPtr pModelSpace = idModelSpace.safeOpenObject();

OdDbObjectIteratorPtr pIt = pModelSpace->newIterator();
OdDbObjectId idWall;
for (pIt->start(); !pIt->done(); pIt->step())
{
    OdDbObjectId id = pIt->objectId();
    // we open each object and cast it to AECDbGeo, because this is the class which stores the anchor. All aec entities are subclasses of this class
    AECDbGeoPtr ptrGeo = AECDbGeo::cast( id.safeOpenObject() );
    if( ptrGeo.isNull() )
        continue;

    // we open the anchor object and check if this anchor type is relation “attached to smth”
    AECDbAnchorToRefPtr pAnchor =
    AECDbAnchorToRef::cast( ptrGeo->GetAnchor().openObject( OdDb::kForRead ) );
    if ( pAnchor.isNull() )
        continue;

    // if this object is attached to the wall, then we have found the object
    if(idWall == pAnchor->GetReference())
    {
        //anchored object found
    }
}

We also could check anchors for the type “smth attached to a wall” like this:

if ( !pAnchor->isKindOf( AECDbAnchorEntToWall::desc() ) )
    continue;