Тема: Глюк при отрисовке объекта на нескольких слоях

Мой объект отрисовывается в нескольких слоях. Все замечательно работает, за исключением одной ситуации.
Если на невыделенный объект навести мышкой, он подсвечивается, так вот если увести мышку с рабочего пространства на напель ниструментов так, чтобы подсветка осталась и скрыть один из слоев, на котором рисуется объект, то возникает unhandled exception и кад валится...
Кто подсказать, где может быть ошибка?

Re: Глюк при отрисовке объекта на нескольких слоях

Я, конечно, в ObjARX как свинья в ананасах, но я не понимаю, как один объект может иметь несколько слоев. По-моему, такое невозможно...

Re: Глюк при отрисовке объекта на нескольких слоях

> kpblc
Поверьте на слово :) сам объект - да, не может, он находится на определенном слое. а вот его графика, т.е. отображение может располагаться на разных слоях.

Re: Глюк при отрисовке объекта на нескольких слоях

> kpblc
Это возможно в собственных примитивах (custom entity). Например, примитив состоит из кружка и теста (что-то типа обозначения оси). Кружок на одном слое, текст на другом (не нужно говорить мне, что тоже самое можно сделать при помощи блока с атрибутом). Но такие махинации со слоями запутывают AutoCAD и могут приводить к различным проблемам.

Re: Глюк при отрисовке объекта на нескольких слоях

> Александр Ривилис
Александр, а есть мысли по сути вопроса? :)

Re: Глюк при отрисовке объекта на нескольких слоях

> bird
Сечас потестирую - сообщу. Пока пару наводящих вопросов:
1) Версия AutoCAD?
2) Если объект не выделен, то отключение слоя не разваливает AutoCAD?
3) IMHO что-то не в порядке внутри worldDraw (viewportDraw)

Re: Глюк при отрисовке объекта на нескольких слоях

> Александр Ривилис
1) 2006
2) Глюк возникает только в том случае, если обект не выделен, а только подсвечен при наведении и подвсетка не снялась при перемещении мышки за пределы рабочего поля, во всех прочий случаях работает замечательно и с отключением слоев в том числе.
3) знать бы еще хоть примерно, что не в порядке...

Re: Глюк при отрисовке объекта на нескольких слоях

> bird
Только что проверил у себя в точности то, о чем ты пришешь. Такая ошибка не возникает. Проверял на простейшем примере - примитив состоит из двух окружностей, каждая из них на своем слое.
Не пытаешься ли ты модифицировать примитив внутри worldDraw/viewportDraw()?

Re: Глюк при отрисовке объекта на нескольких слоях

> Александр Ривилис
Да, меняю, это может повлиять?

Re: Глюк при отрисовке объекта на нескольких слоях

> bird
При наведении курсора на примитив AutoCAD открывает примитив, выполняет для него highlight(), а после увода курсора выполняет unhighlight() и закрывает его. Так что пока он подвечен, писать в него (IMHO) нельзя. Кроме того метод worldDraw() всегда понимется AutoCAD как не модифицирующий (т.е. требующий доступа "только для чтения").

Re: Глюк при отрисовке объекта на нескольких слоях

> Александр Ривилис
Уже переписываю, о результатах сообщу. Спасибо огромное, Александр :)

Re: Глюк при отрисовке объекта на нескольких слоях

Уху... точно, могу поддакнуть что модифицировать объект в read-only методах категорически не рекомендуется.

Re: Глюк при отрисовке объекта на нескольких слоях

Однако не помогло :( где-то глюк остался.
Для теста заменил у себя WorldDraw на:
      assertReadEnabled();
    AcGePoint3d p[2];
    p[0].set(0,0,1);
    p[1].set(100,0,1);
    mode->subEntityTraits().setLayer(lid2d);
     // lid2d  - id нужного слоя, он в порядке, проверял..
     // но именно при его скрытии вылетаем
    mode->geometry().polyline(2,p);
    return Acad::eOk;
та же фигня...вылетает...
Есть еще предположения с чем это связанно?

Re: Глюк при отрисовке объекта на нескольких слоях

> bird
Если у тебя последняя строка return Acad::eOk;, т.е. возвращается 0, то соответственно AutoCAD должен вызвать метод viewportDraw(). А в нем примитив не модифицируется?
Попробуй заменить return Acad::eOk; на return Adesk::kTrue; чтобы viewportDraw() не вызывался.

Re: Глюк при отрисовке объекта на нескольких слоях

Уточнения:
1) объект унаследован от AcDbPolilyne
2) Пробовал отключать практически все методы и функции - не помогает
3) Пробовал переопределить метод highlight, такое впечатление, что он совсем не срабатывает, пока его не вызовешь руками (допустим по специально созданной команде)

Re: Глюк при отрисовке объекта на нескольких слоях

> Александр Ривилис
Попробовал - не помогло... Кстати, пробовал переопределить и viewportDraw()...

Re: Глюк при отрисовке объекта на нескольких слоях

Увы! Придется тебе копать глубже...

Re: Глюк при отрисовке объекта на нескольких слоях

Кстати, попробовал переделать пример "editor\palettes"
(у меня аналогичный по составу объект)

Adesk::Boolean asdkBolt::worldDraw(AcGiWorldDraw* mode)
{
    assertReadEnabled();
    drawHead(mode);
    mode->subEntityTraits().setLayer(lid2d);
    drawShaft(mode);
    mode->subEntityTraits().setLayer(lidTop);
    drawThread(mode);
    return AcDbEntity::worldDraw(mode);
}

Получил тот же эффект...
Может это на мысли натолкнет?

Re: Глюк при отрисовке объекта на нескольких слоях

> bird
Пришли полностью переделанный тобой проект  "editor\palettes"
(в архиве) - посмотрю. И опиши точно (лучше в виде картинки), что у тебя в этот момент на инструментальной палитре.

Re: Глюк при отрисовке объекта на нескольких слоях

Есть еще один вопрос... при выводе на плотер во всех режимах, отображаются части объекта, находящиеся на скрытых или отключенных слоях... и никак не убираются... может в worldDraw() проверять скрыт ли слой и не выводить на них элемененты? Или есть другой способ решения? Вообще, это зона ответственности программы или может глюк в Autocad 2006 sp0?

Re: Глюк при отрисовке объекта на нескольких слоях

Да... кажется такая проблема уже была описана:
http://discussion.autodesk.com/thread.j … ID=4972255
Товарищи счастливые обладатели autocad2006 sp1, вас не затруднит проверить, исправлен ли этот глюк в сервис-паке?

Re: Глюк при отрисовке объекта на нескольких слоях

Товарищи счастливые обладатели autocad2006 sp1, вас не затруднит проверить, исправлен ли этот глюк в сервис-паке?

Нет. Но выкрутится достаточно несложно. Достаточно проверять в worldDraw() состояние слоев на которых мы рисуем. Например, так:

Adesk::Boolean MyEntity::worldDraw (AcGiWorldDraw *mode) {
  assertReadEnabled () ;
  if (mode->isDragging()) {
    mode->subEntityTraits().setLayer(layer1);
    mode->geometry().circle(center,fabs(r1),normal);
    mode->subEntityTraits().setLayer(layer2);
    mode->geometry().circle(center,fabs(r2),normal);
  } else {
    AcDbLayerTableRecordPointer pLayer1(layer1,AcDb::kForRead);
    AcDbLayerTableRecordPointer pLayer2(layer2,AcDb::kForRead);
    if (pLayer1.openStatus() == Acad::eOk && !pLayer1->isOff() && !pLayer1->isFrozen()) {
      mode->subEntityTraits().setLayer(layer1);
      mode->geometry().circle(center,r1,normal);
    }
    if (pLayer2.openStatus() == Acad::eOk && !pLayer2->isOff() && !pLayer2->isFrozen()) {
      mode->subEntityTraits().setLayer(layer2);
      mode->geometry().circle(center,r2,normal);
    }
  }
  return Adesk::kTrue;
}

Вариант не самый элегантный, но работает.