Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Overriding the wblockClone() Function

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

To customize the copying stage of the wblock cloning operation:

  1. Create an object of the same type as the current object, and add it to the database.
  2. Create a wblock 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 referenced by the current object with hard ownership or hard pointer references. This can be done by calling the defaultProcessReferences() method of the wblock clone filer. It will follow through all hard ownership and hard pointer references of the object and call the wblockClone() method of referenced objects.
  7. Return the cloned object.

OdDbObjectPtr ExDcEntity::subWblockClone(OdDbIdMapping& idMap, OdDbObject* /*owner*/, bool bPrimary) const
{
  // do not use the owner - override appendToOwner() virtual function 
  // if you need some special ownership processing

  // 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 is an xref bind operation and this entity is in paper space, then return,
  // as xref bind doesn't support cloning entities in paper space.
  //
  OdDbDatabase* pDb = database();
  if (idMap.deepCloneContext() == OdDb::kDcXrefBind && ownerId() == pDb->getPaperSpaceId())
  {
    return OdDbObjectPtr();
  }

  // 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 OdDbWblockCloneFiler makes a list of HardOwnership and HardPointer IDs.
  // These references must be cloned during a wblock operation.
  //
  OdDbWblockCloneFilerPtr pFiler = OdDbWblockCloneFiler::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 hard references.
  //
  pFiler->defaultProcessReferences();
  // Where default processing iterates through hard references
  // and call wblockClone() method. Actually it does the following:
  //
  //OdDbObjectId hardId;
  //pFiler->start();
  //while (pFiler->nextReference(hardId))
  //{
  //  hardId.safeOpenObject()->wblockClone(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.