Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Overriding the deepClone() Function

The deepClone() method of an object cannot be overridden itself. The method subDeepClone() contains all overridable functionality and should be overridden in order to customize the deep clone behavior of an object.

To customize the copying stage of the cloning operation:

  1. Create an object of the same type as the current object, and add it to the database.
  2. Create a deep clone filer and file out to it the current object using its dwgOut() method.
  3. Rewind the filer and read data to the clone using its dwgIn() method.
  4. Append a new record filled in with the information about the current operation to the ID map.
  5. Set the flag signaling that the clone's references have not been translated yet and so they cannot be used in any operations with this object. Call the clone's setOdDbObjectIdsInFlux() method for this purpose.
  6. Clone all objects owned by the current object. This can be done by calling the defaultProcessReferences() method of the deep clone filer. It will follow through all ownership references of the object and call the deepClone() method of referenced objects.
  7. Return the cloned object.

OdDbObjectPtr ExDcEntity::subDeepClone(OdDbIdMapping& idMap, OdDbObject*, bool bPrimary) const
{
  // You should always return NULL if, for any reason,
  // you do not actually clone this object during this call.
  //
  OdDbObjectPtr pClone;

  // Verify database pointer
  //
  if (!idMap.destDb())
  {
    throw OdError(eNoDatabase);
  }

  // If this object is in the idMap and is already cloned, then return.
  //
  OdDbIdPair idPair(objectId());
  if (idMap.compute(idPair) && (idPair.isCloned() || !idPair.value().isNull()))
  {
    return OdDbObjectPtr();
  }

  // Step 1
  // Create the clone and add it to the database.
  //
  pClone = isA()->create();
  idMap.destDb()->addOdDbObject(pClone);

  // Step 2
  // The OdDbDeepCloneFiler makes a list of HardOwnership and SoftOwnership IDs.
  // These references must be cloned during a deepclone operation.
  //
  OdDbDeepCloneFilerPtr pFiler = OdDbDeepCloneFiler::createObject(&idMap);
  dwgOut(pFiler);

  // Step 3
  // Rewind the filer and read the data into the clone.
  //
  pFiler->seek(0L, OdDb::kSeekFromStart);
  pClone->dwgIn(pFiler);

  // Step 4
  // Add the new information to the ID map.
  idPair.setValue(pClone->objectId());
  idPair.setCloned(true);
  idPair.setPrimary(bPrimary);
  idMap.assign(idPair);

  // Step 5
  // Set flag that the cloned object's IDs have not yet been translated
  // and thus cannot be used in any operations on the object.
  // The flag is turned off after the object has translated 
  // the references to their new values.
  //
  pClone->setOdDbObjectIdsInFlux();

  // Step 6
  // Using the filer list created above, clone any owned references.
  //
  pFiler->defaultProcessReferences();
  // Where default processing iterates through owned references
  // and call deepClone() method. Actually it does the following:
  //
  //OdDbObjectId hardId;
  //pFiler->start();
  //while (pFiler->nextReference(hardId))
  //{
  //  hardId.safeOpenObject()->deepClone(idMap);
  //}

  // Step 7
  // Return the cloned object.
  //
  return pClone;
}

See Also

Deep Clone Basics

Advanced Deep Clone Topics

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