Тема: Редирект dwgIn dwgOut другим объектам

Есть у меня объект

AcDbEntityContainer : AcDbEntity
{
   init( AcDbEntity* pEnt );
   AcDbEntity* pEnt;
   dwgInFields( filer );
   dwgOutFields( filer );
}
AcDbEntityContainer::init( AcDbEntity* pOrigEnt )
{
   pEnt = pOrigEnt->clone(); //считаем что pOrigEnt - не  комплексная (удаление если pEnt != NULL - опускаю)
}

Все transformBy moveGrip getOsnap getGrip worldDraw- редиректим pEnt

AcDbEntityContainer::dwgOutFields( filer )
{
   filer.write( pEnt->isA()->name() );
   pEnt->dwgOut...(filer);
}
AcDbEntityContainer::dwgInFields( filer )
{
   str className;
   filer.read( className );
   pEnt =  classDictionary->getAt(className)->create(); //создаем объект по имени класса через AcRxClass
   pEnt->dwgIn( filer );
}

Такая фенька работает. Т.е. получаем контейнер-обертку для entity.
Внутри документа опять же все работает.
Но! Если копировать объект между базами, то все проходит без ошибок с eOk. Как только объект переезжает в другую базу, то информация теряется... Например была окружность AcDbCircle - она переходит в окружность с конструктором по умолчанию... Т.е. позиция (0,0,0) радиус 1... хотя dwgIn и dwgOut в редиректе отрабатывают с eOk. Т.е. получаем что на каком-то этапе в иерархии dwgIn dwgOut обрывается без сообщения об ошибке. При этом если в след за pEnt->dwg...(filer) - записывать и считывать еще какие-нибудь данные, то они считываются/записываются нормально между базами.
Почему так происходит? Я так понимаю, что dwgIn dwgOut внутри - должны просто читать/писать информацию из filer-a, но получается что там происходит еще что-то типа сразу пытаются оттранслироваться ссылки на слой, тип линий и т.п. - объект переехал из базы в базу - допустим не может найти ссылку на свой слой и... информация убивается либо дальше не читается...
Кто-нибудь может объяснить что еще происходит внутри dwgIn OutFields что приводит к потери данных объекта??? (при этом сам объект как это не парадоксально рисуется, но по дефолту) :(

Re: Редирект dwgIn dwgOut другим объектам

Так у меня нормально работает между документами. Нормально создаются слои, переносится информация о примитивах и т.д. Во всяком случае для простых примитивов:

Acad::ErrorStatus MyContainer::dwgInFields(AcDbDwgFiler* pFiler)
{
  assertWriteEnabled();
  Acad::ErrorStatus es;
  if ((es = AcDbEntity::dwgInFields(pFiler)) != Acad::eOk) {
    return es;
  }
  char myName[64];
  long nameLen;
  pFiler->readInt32(&nameLen);
  pFiler->readItem((void**)&myName,nameLen);
  myName[nameLen]=0;
  AcRxClass* pClass=AcRxClass::cast(acrxClassDictionary->at(myName));
  if(pFiler->filerType()!=AcDb::kIdXlateFiler)
     pEnt=(AcDbEntity*)pClass->create();
  pEnt->dwgInFields(pFiler);
  return pFiler->filerStatus();
}
Acad::ErrorStatus MyContainer::dwgOutFields(AcDbDwgFiler* pFiler) const
{
  assertReadEnabled();
  Acad::ErrorStatus es;
  if ((es = AcDbEntity::dwgOutFields(pFiler)) != Acad::eOk) {
    return es;
  }
  const char *pName;
  pName=pEnt->isA()->name();
  long nameLen=strlen(pName);
  pFiler->writeInt32(nameLen);
  pFiler->writeItem(pName,nameLen);
  pEnt->dwgOutFields(pFiler);
  return pFiler->filerStatus();
}

Посравнивай. Может и найдешь что у тебя не так.

Re: Редирект dwgIn dwgOut другим объектам

Спасибо посмотрю. Но на первый взгляд все в точности совпадает и по моим представлениям должно отрабатывать корректно... (для простых Entity).
Я все тестил под 2002 (2004 не проверял - может отличия в акадах...)
Александр - вопрос: убиваешь ту entity от которой делаешь entity-обертку? А то может они у тебя друг на друга накладываются 100% - ты их вместе селектишь и копируешь - оригинал тащит за собой все слои и т.п. - а клон в контейнере поэтому нормально и вычитывается?

Re: Редирект dwgIn dwgOut другим объектам

Как работает метод init?
Я создаю клон от entity, которая реально вставлена в базу.
Возможно ты делаешь для теста что-то типа
AcDbEntity* pEnt = new AcDbCircle(...);
Т.е. entity у тебя не является резидентом базы... (хотя и клон не в базе, но мало ли какие могут быть отличия при создании клона от объекта в базе или простого создания new)

Re: Редирект dwgIn dwgOut другим объектам

KonstantinM пишет:

вопрос: убиваешь ту entity от которой делаешь entity-обертку?

Да. Точнее делаю ей handOverTo, так что она перестает находится в базе.

Возможно ты делаешь для теста что-то типа
AcDbEntity* pEnt = new AcDbCircle(...);

Нет. В качестве pEnt используется реально сидящий в базе примитив.
Чтоб не морочить тебе голову - отправлю тебе тестовый проект - посмотришь. У меня нет сейчас возможности разбираться что у тебя не так.

Re: Редирект dwgIn dwgOut другим объектам

Попробовал Ваш вариант.
Пытаюсь схватить объект мышью и передвинуть - падает т.к.
if(pFiler->filerType()!=AcDb::kIdXlateFiler)
     pEnt=(AcDbEntity*)pClass->create();
в if не попадаем... создается какая-то копия объекта - в которой pEnt!=NULL, после этого у нас два объекта с указателем на одну pEnt. Как только один умирает - он убивает свой pEnt в деструкторе и оригинальный объект который мы пытаемся тягать падает...
В чем секретный смысл строчки, а точнее условия в if-е?
if(pFiler->filerType()!=AcDb::kIdXlateFiler)
     pEnt=(AcDbEntity*)pClass->create();

Re: Редирект dwgIn dwgOut другим объектам

С падением разобрался.

Re: Редирект dwgIn dwgOut другим объектам

В чем секретный смысл строчки, а точнее условия в if-е?
if(pFiler->filerType()!=AcDb::kIdXlateFiler)

Посмотри в Help'е по контексту kIdXlateFiler. Там описано, что pFiler->filerType()==AcDb::kIdXlateFiler только когда выполняется INSERT, COPY, XREF, WBLOCK

С падением разобрался.

Так уже все в порядке?

Re: Редирект dwgIn dwgOut другим объектам

Да сам в стороне тест написал все работает.
Просто меня смутил один глюк (проверить с вашим примером не могу - т.к. седня mail.ru не работает - а ящик с ника туда указан).
Глюк в том, что для окружности после присвоения ее к entity контейнеру при передвижении за центральную grip точку она ведет себя как изменение радиуса, а нижняя грип точка - передвигает (хотя должна была менять радиус).
Код у меня прост до банальности:
Acad::ErrorStatus WlEntityContainer::moveGripPointsAt(const AcDbIntArray& indices,
                                                const AcGeVector3d& offset)
{
    assertWriteEnabled();
    pCntEnt->moveGripPointsAt(indices, offset);
    return Acad::eOk;
}
Acad::ErrorStatus WlEntityContainer::getGripPoints(AcGePoint3dArray& gripPoints,
                                             AcDbIntArray& osnapModes,
                                             AcDbIntArray& geomIds) const
{
    assertReadEnabled();
   
    pCntEnt->getGripPoints(gripPoints, osnapModes, geomIds);
    return Acad::eOk;
}
Проверить на Вашем примере - то же самое у Вас или нет не могу по причине выше.

Re: Редирект dwgIn dwgOut другим объектам

> KonstantinM
Напиши мне с другого ящика на rivilis#i.com.ua (# сам знаешь на что заменить). Я отошлю тебе пример. Он работает с любыми простыми примитивами.

Re: Редирект dwgIn dwgOut другим объектам

Причина того что я описал выше (пропадание данных) кроется как раз в том, что у меня не было проверки на:
if(pFiler->filerType()!=AcDb::kIdXlateFiler)
Т.е. в тесте ее комментарим и всегда делаем
clearEnt();
pCntEnt= (AcDbEntity*)pClass->create();
Получаем тот эффект, что я описал выше...
Спасибо, что помогли разобраться в причине...
Пойду думать почему она так происходит в глубине т.к. честно признаюсь пока не догоняю из-за чего так происходит...
В хелпе прочитал что - AcDb::kIdXlateFiler когда выполняется INSERT, COPY, XREF, WBLOCK... ну и что? Другие данные ведь вычитываются заново и вполне успешно при любом filerType...

Re: Редирект dwgIn dwgOut другим объектам

> KonstantinM
Глюк подтверждаю. :(

Re: Редирект dwgIn dwgOut другим объектам

Попробовал в AutoCAD 2006 SP1 - там еще хуже. Похоже, что тебе придется проверять типы pEnt и обрабатывать их индивидуально - простой редирект не проходит. :( Что-то они там для простых примитивов "оптимизировали"...

Re: Редирект dwgIn dwgOut другим объектам

А можно чуть подробней - про хуже? Что именно?

Re: Редирект dwgIn dwgOut другим объектам

Оный глюк нашел только для окружности... в 2002
Все остальные приметивы
Arc Ellipse EllipseArc Spline Line Rect MLine отрабатывают нормально...

Re: Редирект dwgIn dwgOut другим объектам

> KonstantinM
Отрезок, когда его начинаешь тащить за одну из точек ускакивает неизвестно куда, окружность тоже... Дальше исследовать даже не хочется...
Если у тебя есть желание анализировать - кидай e-mail. Пришлю простейший проект (точнее два - под AutoCAD 2002 и 2004) - обертку. Дальше будешь исследовать сам. :)

Re: Редирект dwgIn dwgOut другим объектам

P.S.: mail.ru уже работает.

Re: Редирект dwgIn dwgOut другим объектам

konstantinm@woland.iae.nsk.su
P.S.: mail.ru все еще не работает. :( зайти не могу и друзья не могут - пинг идет.

Re: Редирект dwgIn dwgOut другим объектам

Отправил. Надеюсь получишь. :)

Re: Редирект dwgIn dwgOut другим объектам

Вы меня пугаете...
Перевел свой пример в 2006
У меня все так же как и в 2002... (Тот же глюк только с окружностью)
Кстати работает даже полилиния (не знаю почему... но работает и копируется и данные делят между собой т.е. все ОК...)
А вот Draw->3dSurfaces уже не работают...уже падает-с при банальной попытке потоскать по экрану...
Могу отправить Вам свой пример... под 2002 и 2004-6

Re: Редирект dwgIn dwgOut другим объектам

Посмотрел Ваш пример.
Действительно у Вас под 2006 происходит лабуда...
У меня в моем примере все ОК.
От куда Вы взяли этот пример? Просто смотрю что он создан в 2002 году?
Щас передохну - попытаюсь разобраться в причинах - где различия (хотя на первый взгляд все идентично идеологически)
Почему работает с AcDbPolyline я не понимаю :) Но работает... Почему не работает с 3dSurface я не понимаю... вроде она не комплексная...

Re: Редирект dwgIn dwgOut другим объектам

Могу отправить Вам свой пример... под 2002 и 2004-6

Давай. Интересно посмотреть.

А вот Draw->3dSurfaces уже не работают

Подозреваю, что для некоторых встроенных примитивов не все методы реализованы (они самим AutoCAD не вызываются), а некоторые реализованы некорректно - поэтому AutoCAD и падает.

От куда Вы взяли этот пример? Просто смотрю что он создан в 2002 году?

Оттуда... (сам догадайся) :)

Re: Редирект dwgIn dwgOut другим объектам

А лабуда в 2006 (IMHO) из-за:

Adesk::Boolean MyContainer::cloneMeForDragging()
{
  return Adesk::kFalse;
}

Re: Редирект dwgIn dwgOut другим объектам

> Александр Ривилис
----
А лабуда в 2006 (IMHO) из-за:
Adesk::Boolean MyContainer::cloneMeForDragging()
{
  return Adesk::kFalse;
}
----
точно...

Re: Редирект dwgIn dwgOut другим объектам

Отправил то что накропал.
А с 3d surface объектами не работает т.к. это PolygonMesh - комплексная entity :(