Тема: Почему откопированные объекты не отображаются в 3dOrbit?

Есть Custom Entity.
Если добавлять объекты на план в команде (ADD...), то они добавляются и при выполнении команды 3dOrbit - корректно отображаются.
Далее если поместить на экран несколько копий данного объекта(Copy), то все проходит корректно, но при вызове команды 3dOrbit - они не отображаются.
Метод getGeomExtends() - возвращает корректные значения и написан правильно.
Если объект и его копии выделить и запустить команду 3dOrbit для выделенных объектов, то опять же все отображается корректно. Т.е. глюк проявляется только в невыделенном режиме объектов в 3dOrbit..
Если чертеж сохранить и повторно открыть, то все объекты  успешно отображаются и глюк проходит.
Кто-нибудь сталкивался с подобным или/и знает причину и как вылечить? Заранее благодарен.

Re: Почему откопированные объекты не отображаются в 3dOrbit?

Акад 2002.

Re: Почему откопированные объекты не отображаются в 3dOrbit?

Методом исключения нашел причину данного глюка:
Данный глюк появляется если в Custom Entity переопределить метод
Acad::ErrorStatus deepClone(AcDbObject* pOwner,
                                AcDbObject*& pClonedObject,
                                AcDbIdMapping& idMap,
                                Adesk::Boolean isPrimary) const;
Реализацию этого метода я взял из примера deepClone - ObjectARX
Acad::ErrorStatus WlEntityContainer::deepClone(AcDbObject* pOwner,
                                         AcDbObject*& pClonedObject,
                                         AcDbIdMapping& idMap,
                                         Adesk::Boolean isPrimary) const
{
    assertReadEnabled();
    // TODO: implement this function.
    // You should always pass back pClonedObject == NULL
    // if, for any reason, you do not actually clone it
    // during this call.  The caller should pass it in
    // as NULL, but to be safe, we set it here as well.
    //
    pClonedObject = NULL;
    // If this object is in the idMap and is already
    // cloned, then return.
    //
    bool isPrim = false;
    if (isPrimary)
        isPrim = true;
    AcDbIdPair idPair(objectId(), (AcDbObjectId)NULL,
                      false, isPrim);
    if (idMap.compute(idPair) && (idPair.value() != NULL))
        return Acad::eOk;
    // Create the clone
    //
    WlEntityContainer *pClone = (WlEntityContainer*)isA()->create();
    if (pClone != NULL)
        pClonedObject = pClone;    // set the return value
    else
        return Acad::eOutOfMemory;
    AcDbDeepCloneFiler filer;
    dwgOut(&filer);
    filer.seek(0L, AcDb::kSeekFromStart);
    pClone->dwgIn(&filer);
    bool bOwnerXlated = false;
    if (isPrimary)
    {
        AcDbBlockTableRecord *pBTR =
            AcDbBlockTableRecord::cast(pOwner);
        if (pBTR != NULL)
        {
            pBTR->appendAcDbEntity(pClone);
            bOwnerXlated = true;
        }
        else
        {
            pOwner->database()->addAcDbObject(pClone);
        }
    } else {
        pOwner->database()->addAcDbObject(pClone);
        pClone->setOwnerId(pOwner->objectId());
        bOwnerXlated = true;
    }
    // This must be called for all newly created objects
    // in deepClone.  It is turned off by endDeepClone()
    // after it has translated the references to their
    // new values.
    //
    pClone->setAcDbObjectIdsInFlux();
    // Add the new information to the idMap.  We can use
    // the idPair started above.
    //
    idPair.setValue(pClonedObject->objectId());
    idPair.setIsCloned(Adesk::kTrue);
    idPair.setIsOwnerXlated(bOwnerXlated);
    idMap.assign(idPair);
    // Using the filer list created above, find and clone
    // any owned objects.
    //
    AcDbObjectId id;
    while (filer.getNextOwnedObject(id)) {
        AcDbObject *pSubObject;
        AcDbObject *pClonedSubObject;
        // Some object's references may be set to NULL,
        // so don't try to clone them.
        //
        if (id == NULL)
            continue;
        // Open the object and clone it.  Note that we now
        // set "isPrimary" to kFalse here because the object
        // is being cloned, not as part of the primary set,
        // but because it is owned by something in the
        // primary set.
        //
        acdbOpenAcDbObject(pSubObject, id, AcDb::kForRead);
        pClonedSubObject = NULL;
        pSubObject->deepClone(pClonedObject,
                              pClonedSubObject,
                              idMap, Adesk::kFalse);
        // If this is a kDcInsert context, the objects
        // may be "cheapCloned".  In this case, they are
        // "moved" instead of cloned.  The result is that
        // pSubObject and pClonedSubObject will point to
        // the same object.  So, we only want to close
        // pSubObject if it really is a different object
        // than its clone.
        //
        if (pSubObject != pClonedSubObject)
            pSubObject->close();
        // The pSubObject may either already have been
        // cloned, or for some reason has chosen not to be
        // cloned.  In that case, the returned pointer will
        // be NULL.  Otherwise, since we have no immediate
        // use for it now, we can close the clone.
        //
        if (pClonedSubObject != NULL)
            pClonedSubObject->close();
    }
    return Acad::eOk;
}
Что еще не хватает в переопределении этого метода, чтоб глюк с пропаданием откопированного объекта в 3dOrbit исчез?

Re: Почему откопированные объекты не отображаются в 3dOrbit?

На уровне идеи - я не проверял:
Внутри этого метода после close() для клонированного примитива и его субримитивов открой их для записи, выполни recordGraphicsModified(true) и закрой их. Это помогло для правильного отображения всех вершин  AcDb3dPolyline в команде 3DORBIT. Возможно поможет и в данном случае.

Re: Почему откопированные объекты не отображаются в 3dOrbit?

Александр, спасибо, но не помогло... :) Что надо сделать остается тайной.
Помогло так: Банальный редирект AcDbEntity основной части, а дальше делаю свои действия.
Acad::ErrorStatus
XXXX::deepClone(AcDbObject*    pOwner,
                    AcDbObject*&   pClonedObject,
                    AcDbIdMapping& idMap,
                    Adesk::Boolean isPrimary) const
{
    assertReadEnabled();
    pClonedObject = NULL;
    Acad::ErrorStatus dcRes = AcDbEntity::deepClone(pOwner, pClonedObject, idMap, isPrimary);
    if ( pClonedObject == NULL )
        return dcRes;
    subDeepClone(pOwner,
                 pClonedObject,
                 idMap,
                 isPrimary);
    return Acad::eOk;
}
В subDeepClone - делаю свои необходимые действия по копированию некоторых объектов, на которые ссылается объект через AcDbHardPointerId-ы. (И в subDeepClone - можно проверять для надежности не сделана ли уже копия нужного объекта, если нет, то делать).
В данном конкретном случае надо было чтобы объект тащил за собой копии некоторых других объектов на которые ссылался через AcDbHardPointerId-ы.