Typical Deep Clone Operation

The following code excerpt shows a typical use of  AcDbDatabase::deepCloneObjects().

To initiate a deep clone operation

  1. Obtain the set of objects to be cloned.
  2. Put the object IDs into a list (of type AcDbObjectIdArray).
  3. Create a new ID map (of class AcDbIdMapping) that will be filled in by the deepCloneObjects() function.
  4. Call the deepCloneObjects() function, passing in the list of objects to be cloned, the owner object ID to which the cloned objects should be appended, and the ID map created in step 1.

In this example, the owner object ID is the model space block table record. The deepCloneObjects() function fills in the object ID map (idMap). The application can then iterate through the objects contained in the map using a special iterator object (AcDbIdMappingIter) and perform additional operations on those objects, such as transforming each object by a certain matrix.

The following code shows a typical use of deepCloneObjects():

void
cloneSameOwnerObjects()
{
    // Step 1:  Obtain the set of objects to be cloned.
    ads_name sset;
    if (acedSSGet(NULL, NULL, NULL, NULL, sset) != RTNORM) {
        acutPrintf("\nNothing selected");
        return;
    }
    // Step 2: Add obtained object IDs to list of objects
    // to be cloned.
    long length;
    acedSSLength(sset, &length);
    AcDbObjectIdArray  objList;
    AcDbObjectId ownerId = AcDbObjectId::kNull;
    for (int i = 0; i < length; i++) {
        ads_name ent;
        acedSSName(sset, i, ent);
        AcDbObjectId objId;
        acdbGetObjectId(objId, ent);
        // Check to be sure this has the same owner as the first
        // object.
        //
        AcDbObject *pObj;
        acdbOpenObject(pObj, objId, AcDb::kForRead);
        if (pObj->ownerId() == ownerId)
            objList.append(objId);
        else if (i == 0) {
            ownerId = pObj->ownerId();
            objList.append(objId);
        }
        pObj->close();
    }
    acedSSFree(sset);
    // Step 3: Get the object ID of the desired owner for
    // the cloned objects.  We'll use model space for
    // this example.
    //
    AcDbBlockTable *pBlockTable;
    acdbHostApplicationServices()->workingDatabase()
        ->getSymbolTable(pBlockTable, AcDb::kForRead);
    AcDbObjectId  modelSpaceId;
    pBlockTable->getAt(ACDB_MODEL_SPACE, modelSpaceId);
    pBlockTable->close();
    // Step 4:  Create a new ID map.
    //
    AcDbIdMapping idMap;
    // Step 5: Call deepCloneObjects().
    //
    acdbHostApplicationServices()->workingDatabase()
        ->deepCloneObjects(objList, modelSpaceId, idMap);
    // Now we can go through the ID map and do whatever we'd
    // like to the original and/or clone objects.
    //
    // For this example, we'll print out the object IDs of
    // the new objects resulting from the cloning process.
    //
    AcDbIdMappingIter iter(idMap);
    for (iter.start(); !iter.done(); iter.next()) {
        AcDbIdPair idPair;
        iter.getMap(idPair);
        if (!idPair.isCloned())
            continue;
        acutPrintf("\nObjectId is: %Ld",
            idPair.value().asOldId());
    }
}