Использование маскировки в AcDbEntity

Автор Тема: Использование маскировки в AcDbEntity  (Прочитано 8489 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Добрый вечер! Я начал разрабатывать собственный компонент для AutoCAD на основе AcDbEntity и столкнулся с проблемой создания маскировки, т.е. нужно скрывать все элементы находящиеся позади моего компонента.

Для этих целей в AutoCAD есть элемент - Маскировка (Wipeout), но использовать его в AcDbEntity нужно по-особенному. Еще не успел опробовать данное решение, но что-то мне не нравится.

Есть ли еще какие-то варианты маскирования фона кроме Wipeout и Hatch (заливка области)? Может лучше сделать собственный компонент наследуясь от AcDbWipeot (если это возможно)? Пожалуйста, подскажите в каком направлении рыть, я только начал изучать ObjectARX.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #1 : 04-04-2018, 23:30:41 »
Еще не успел опробовать данное решение, но что-то мне не нравится.
Что именно не нравится?
я только начал изучать ObjectARX.
Начинать изучение ObjectARX с создания Custom Entity - это не лучший вариант.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #2 : 05-04-2018, 09:13:02 »
Начинать изучение ObjectARX с создания Custom Entity - это не лучший вариант.
Ничего не поделать, обстоятельства. Но имея опыт программирования на C++ / C# и разработки под Компас-3D, Solidworks разобраться можно. Я как раз читаю книгу Полещука, вроде всё ясно. Тут дело в другом - возможно я выбрал не оптимальное решение.

Мне нужно сделать простой интеллектуальный объект и тут AcDbEntity идеально подходит (возможно я ошибаюсь). Но как оказалось, нужно ещё прятать (маскировать) объекты за моим объектом. Я нашел два решения:

1) Использовать Wipeout (маскировка). Вроде оптимальное решение, но смущает факт необходимости добавления Wipeout в AcDbBlockTableRecord для возможности отображения. Остальные же графические объекты унаследованные от AcDbEntity можно просто отображать с помощью метода worldDraw(mode).

2) Использовать Hatch (штриховка). Штриховка является ресурсоемким объектом чертежа, плюс нужно сделать так чтобы при печати цвет заливки был белым, а при работе с чертежом цвет заливки был равен цвета фона автокаде.

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #3 : 05-04-2018, 09:17:28 »
А нельзя ли в AcDbEntity или AcDbObject как-то поиграть с рендером?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #4 : 05-04-2018, 10:50:44 »
А нельзя ли в AcDbEntity или AcDbObject как-то поиграть с рендером?
Нет конечно. AcDbEntity вообще ничего не знает про рендер.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #5 : 05-04-2018, 10:54:27 »
Так как бы Вы реализовали данную задачу?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #6 : 05-04-2018, 10:58:20 »
Мне нужно сделать простой интеллектуальный объект и тут AcDbEntity идеально подходит (возможно я ошибаюсь).
Я не знаю что представляет из себя этот "интеллектуальный объект", поэтому сложно дать рекомендации по тому от какого класса следует наследовать.
1) Использовать Wipeout (маскировка). Вроде оптимальное решение, но смущает факт необходимости добавления Wipeout в AcDbBlockTableRecord для возможности отображения. Остальные же графические объекты унаследованные от AcDbEntity можно просто отображать с помощью метода worldDraw(mode).
Проблема связана с тем, что огромную роль играет порядок отображения объектов. Если объекты за твоим объектом будут отрисованы после твоего объекта, то твой объект их не скроет. И тут в игру вступает AcDbSortentsTable, которая управляет порядком прорисовки объектов на уровне блока.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #7 : 12-04-2018, 14:41:18 »
Что-то не вышло как в том примере, фатальная ошибка: Unhandled Access Violation Reading!

В примере создают новый AcDbBlockTableRecord, в который помещают AcDbWipeout. Далее в методе subWorldDraw кастомного объекта открывают AcDbBlockTableRecord и вызывают метод отрисовки. И вроде при создании кастомного объекта все ок. Но когда я хочу перенести свой объект, то возникает фатальная ошибка. Не могу понять из-за чего.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #8 : 12-04-2018, 14:47:38 »
Но когда я хочу перенести свой объект, то возникает фатальная ошибка. Не могу понять из-за чего.
Перенос - это что? Команда _MOVE? Но в примере нет переопределения subTransformBy, который должен вызываться в этом случае. Это же просто минимальный пример.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #9 : 12-04-2018, 14:50:36 »
Да, я про subTransformBy. Я создал свой компонент на основе AcDbEntity и он хорошо переносится. Вся проблема в добавлении AcDbWipeout.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #10 : 12-04-2018, 14:55:27 »
Да, я про subTransformBy. Я создал свой компонент на основе AcDbEntity и он хорошо переносится. Вся проблема в добавлении AcDbWipeout.
Запусти под отладчиком и посмотри что происходит в этом методе. И вообще-то на код нужно глянуть - я по фотографии не лечу. :-)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #11 : 12-04-2018, 15:15:40 »
Когда кастомного объект отрисовывается впервые раз (subWorldDraw), тот можно получить AcDbBlockTableRecord по его AcDbObjectId и все ок. Но когда я начинаю перемещать объект и вызывается отрисовка, то AcDbObjectId равен нулю, что вызывает ошибку! Что-то не могу понять как переменная моего класса обнуляется...

Отмечено как Решение GrandmaSquid3 17-04-2018, 17:46:52

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #12 : 12-04-2018, 15:19:30 »
Но когда я начинаю перемещать объект и вызывается отрисовка, то AcDbObjectId равен нулю, что вызывает ошибку! Что-то не могу понять как переменная моего класса обнуляется...
О! Обрати внимание на методы dwgInFields и dwgOutFields в том примере. Наверняка ты забыл:
Код - C++ [Выбрать]
  1. pFiler->writeHardPointerId(wipeOutId); // <------- в dwgOutFields
и
Код - C++ [Выбрать]
  1. pFiler->readHardPointerId(&wipeOutId); // <------- в dwgInFields
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #13 : 12-04-2018, 18:00:06 »
Ура, работает! Действительно дело в HardPointerId.

Но вот сижу и думаю как это работает... ИД объекта (AcDbObjectId) постоянно меняется?! Мне казалось что методы dwgInFields и dwgOutFields служат только для сохранения файла на диске. Нужно ли удерживать указатель в dxfInFields и dxfOutFields?

Кстати, я решил работать не с AcDbBlockTableRecord в своем кастомного компоненте (как было в примере), а сразу AcDbWipeout, передавая его AcDbObjectId в свой компонент и используя метод acdbOpenAcDbEntity в самом компоненте. Так я могу менять и свойства Wipeout'а (размер и положение) и отрисовывать его. Или это не верно?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #14 : 13-04-2018, 00:31:27 »
Кстати, я решил работать не с AcDbBlockTableRecord в своем кастомного компоненте (как было в примере), а сразу AcDbWipeout, передавая его AcDbObjectId в свой компонент и используя метод acdbOpenAcDbEntity в самом компоненте. Так я могу менять и свойства Wipeout'а (размер и положение) и отрисовывать его. Или это не верно?
А где он в этом случае находится? Анонимный AcDbBlockTableRecord использовался в примере для того, чтобы он "не путался под ногами", т.е. не был виден в чертеже.
Но вот сижу и думаю как это работает... ИД объекта (AcDbObjectId) постоянно меняется?! Мне казалось что методы dwgInFields и dwgOutFields служат только для сохранения файла на диске. Нужно ли удерживать указатель в dxfInFields и dxfOutFields?
Id-объекта не меняется. Меняется только если закрыть dwg-файл и повторно его открыть. dwgInFields и dwgOutFields используются во многих случах, но в данном случае при создании клона примитива, который и перетаскивается, пока оригинальный остаётся на месте. Т.е. сначала срабатывает конструктор твоего класса, создавая новый экземпляр твоего примитива, потом dwgOutFields для оригинального примитива, а затем dwgInFields для новый экземпляра заполняет его значениями.
Создания клона можно избежать если переопределить в своём классе метод subCloneMeForDragging(), чтобы он возвращал  Adesk::kFalse. Но этого лучше не делать, так как вызовет другие побочные эффекты.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #15 : 17-04-2018, 15:03:25 »
Нужно ли удалять AcDbBlockTableRecord (в котором находится AcDbWipeout) при удалении кастомного объеста?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #16 : 17-04-2018, 16:04:46 »
Нужно ли удалять AcDbBlockTableRecord (в котором находится AcDbWipeout) при удалении кастомного объеста?
Во-первых, нет необходимости - _PURGE удалит этот блок, если на него нет никаких ссылок (HardPointerId).
Во-вторых, ты не знаешь в какой момент можно удалять.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #17 : 17-04-2018, 16:26:43 »
Как не знаю? В деструкторе моего кастомного компонента разве нельзя удалить? Хотя предполагаю что и тут есть особенности AutoCAD'а.

Если смотреть "со стороны" то я создаю свой кастомный компонент на основе AcDbEntity. Так как в нем нельзя создать AcDbWipeout, я создаю новую таблицу AcDbBlockTableRecord уже в которой создаю AcDbWipeout. Далее передаю ссылку на таблицу в свой компонент, чтобы смочь отрисовывать содержимое этой этой таблицы. Выходит что при каждом создании моего компонента будет создаваться таблица и в ней маскировка. Когда я буду удалять свой компонент, то таблица с маскировкой будут оставаться (утечка памяти).

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #18 : 17-04-2018, 16:33:24 »
В деструкторе моего кастомного компонента разве нельзя удалить?
Нет. Деструктор "закрывает" объект если он уже в базе, а не удаляет его. Удаляет (точнее ставит пометку об удалении) метод erase() твоего объекта.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #19 : 17-04-2018, 16:40:52 »
Кажется начинаю представлять как это устроено. Но как в итоге быть с таблицей и маскировкой? Если на объект никто не ссылается, то он потом уничтожается?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Использование маскировки в AcDbEntity
« Ответ #20 : 17-04-2018, 16:45:50 »
Если на объект никто не ссылается, то он потом уничтожается?
Во всяком случае _PURGE может его удалить.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн GrandmaSquid3Автор темы

  • ADN OPEN
  • Сообщений: 18
  • Карма: 0
Re: Использование маскировки в AcDbEntity
« Ответ #21 : 17-04-2018, 16:47:36 »
Спасибо!