Тема: Как перейти от DBRO к NDBRO?

Столкнулся с такой проблемой, необходимо заменить объект в  одном .dwg-файле на объект из другого файла. Для этого использую функцию handOverTo(). В качестве параметра ей необходимо передать non database resident object(NDBRO). Как я понимаю тот объект, что я считаю из базы как параметр не подойдет, так как он database resident object(DBRO). Вопрос в том как перейти от этого NDBRO объекта к DBRO объекту, который можно было бы передать как параметр в handOverTo()?

Re: Как перейти от DBRO к NDBRO?

AcDbObject::clone()

Re: Как перейти от DBRO к NDBRO?

> Александр Ривилис
Пытался сделать AcDbObject::deepClone(), но затем метод isDBRO() полученного объекта возвращает True...

Re: Как перейти от DBRO к NDBRO?

> Solmar
1) Я написал clone() а не deepClone()
2) Где это ты нашел метод isDBRO()?

Re: Как перейти от DBRO к NDBRO?

> Александр Ривилис
Ага, попробовал с clone(), вроде заработало, но у меня есть сомнения, связанные со сложными объектами, насколько корректно оно будет работать со сложными объектами, где присутствуют ссылки на другие объекты?
А isDBRO() это мое творение :))

Re: Как перейти от DBRO к NDBRO?

Если объект сложный, то clone() не поможет.
Вооружись методом AcDbObject::wblockClone().

Re: Как перейти от DBRO к NDBRO?

> Glusha
wblockClone() в данном контексте использовать нельзя, т.к. образуется результирующий объект/объекты тоже станут DBRO.

> Solmar
А со сложными объектами вообще использовать handOverTo() нужно крайне осторожно!

Re: Как перейти от DBRO к NDBRO?

> Александр Ривилис
wblockClone() нужно использовать (т.е. как составную часть wblockCloneObjects()). Понятно, необходимо будет выполнить дополнительные действия по модификации объектов AcDbHard*Id в объектах, так или иначе связанных с первичным. Да, полученный объект будет резидентом БД, но это не страшно.

Re: Как перейти от DBRO к NDBRO?

> Glusha
Это "страшно" для метода handOverTo(), как требовалось в постановке задачи. Но мне изначально непонятно зачем такие сложности с использованием handOverTo(), если действительно при помощи wblockClone() (а еще лучше при помощи AcDbDatabase::wblockCloneObjects()) выполнить копирование объектов, а старые поудалять.

Re: Как перейти от DBRO к NDBRO?

> Александр Ривилис
Для handOverTo() резидентный объект страшен, но он передаваться не будет. Как уже упоминалось, создаём нерезидентный клон и не забываем подправить соответствующие ссылки склонированных wblockCloneObjects() объектов.
Хотя, мороки без handOverTo() будет меньше, но кто знает, что необходимо автору...

Re: Как перейти от DBRO к NDBRO?

Если необходимо сохранить у заменяемых объектов AcDbObjectId, то
я бы пошел таким путем:
1) wblockCloneObjects() для всех соответствующих объектов из второй базы.
2) Зная новые AcDbObjectId (используя AcDbIdMapping из wblockCloneObjects()) я бы при помощи AcDbObject::swapIdWith махнул местами AcDbObjectId у них.
3) Ну и объекты с вновь появившимися AcDbObjectId я бы поудалял.
Эта схема мне видится более "чистой", чем с AcDbObject::handOverTo()

Re: Как перейти от DBRO к NDBRO?

В том и дело, что интересует не сохранение AcDbObjectId, а сохранение AcDbHandle и метод handOverTo() - это единственное, что я нашел для этой цели.

Re: Как перейти от DBRO к NDBRO?

> Solmar
Э, батенька! Тут то вы и не правы. smileСмена AcDbObjectId приводит к смене AcDbHandle. Если не верите - вот тестовый пример:

static void SwitchID(void)
{
  ads_point p; ads_name en1,en2;
  if (acedEntSel(_T("\nВыберите первый примитив: "),en1,p) == RTNORM &&
      acedEntSel(_T("\nВыберите второй примитив: "),en2,p) == RTNORM) {
     AcDbObjectId id1,id2; acdbGetObjectId(id1,en1); acdbGetObjectId(id2,en2);
     AcDbEntityPointer pEnt(id1,AcDb::kForWrite);
     if (pEnt.openStatus() == Acad::eOk) {
       pEnt->list();
       pEnt->swapIdWith(id2);
       pEnt->list();
     }
  }
}

Обратите внимание на метки (Handle) примитивов.

Re: Как перейти от DBRO к NDBRO?

> Александр Ривилис
Попробовал тестовый пример и действительно оказалось, что хэндлы меняются. Александр, спасибо!