Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Александр Пекшев aka Modis от 30-08-2017, 13:10:26

Название: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 30-08-2017, 13:10:26
Всем привет!
Мой плагин позволяет в автокадовский примитив добавить определенные расширенные данные (далее - РД), однако при работе нет никакой идентификации, позволяющей узнать о наличии РД в примитиве. Есть конечно функция, которая позволяет их считать, но это уже другое.
А еще в автокаде есть такая штука, как параметризация и у нее есть возможность скрыть/показать запараметризированные примитивы. Думаю, нет смысла объяснять о чем я - все и так понятно:

(https://s26.postimg.org/3p5o6wj7p/Screenshot_10.png) (https://postimg.org/image/3p5o6wj7p/)

Собственно, вопросы:
1. Есть ли в Net API возможность создавать нечто подобное для своих нужд? Чтобы рядом с примитивом, имеющим мои РД, отображался какой-нибудь символ
2. Если на п.1 ответ "да", то второй вопрос - насколько это будет "нагружать" автокад?
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 30-08-2017, 13:12:32
Могу предположить, что это можно сделать с помощью DrawableOverrule
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: avc от 30-08-2017, 13:18:11
А может проще не значок показывать, а просто Entity.Highlight() ? И никаких накладных расходов
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 30-08-2017, 13:27:20
Могу предположить, что это можно сделать с помощью DrawableOverrule
Собственно говоря ты прав. Насколько это будет нагружать AutoCAD ты сможешь проверить только экспериментально.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 30-08-2017, 23:05:57
В общем - идея с Drawable Overrule подходит, но столкнулся с некоторыми проблемами:
1. Хочу дополнительную графику рисовать по принципу точек - в процентах от размера экрана. Вроде где-то видел, как это значение получить, но не могу найти. Буду признателен за подсказку
2. В методе WorldDraw не создаются примитивы. Вот мой пробник с поясняющим комментарием:
Код - C# [Выбрать]
  1. public override bool WorldDraw(Drawable drawable, WorldDraw wd)
  2. {
  3.     var ent = drawable as Entity;
  4.     if (ent != null)
  5.         if (ent.IsModPlusProduct())
  6.         {
  7.             var scale = 1;
  8.             var plane = ent.GetPlane();
  9.  
  10.             Matrix3d ucs = AcApp.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
  11.             var extents = ent.GeometricExtents;
  12.             //var pt = extents.MaxPoint;
  13.             var pt = extents.MaxPoint.TransformBy(ucs.Inverse());
  14.             Point3dCollection points = new Point3dCollection();
  15.             points.Add(new Point3d(pt.X + 30 * scale, pt.Y + 30 * scale, plane.PointOnPlane.Z));
  16.             points.Add(new Point3d(pt.X + 30 * scale, pt.Y + 40 * scale, plane.PointOnPlane.Z));
  17.             points.Add(new Point3d(pt.X + 40 * scale, pt.Y + 40 * scale, plane.PointOnPlane.Z));
  18.             points.Add(new Point3d(pt.X + 40 * scale, pt.Y + 60 * scale, plane.PointOnPlane.Z));
  19.             points.Add(new Point3d(pt.X + 30 * scale, pt.Y + 60 * scale, plane.PointOnPlane.Z));
  20.             points.Add(new Point3d(pt.X + 30 * scale, pt.Y + 70 * scale, plane.PointOnPlane.Z));
  21.             points.Add(new Point3d(pt.X + 60 * scale, pt.Y + 70 * scale, plane.PointOnPlane.Z));
  22.             points.Add(new Point3d(pt.X + 60 * scale, pt.Y + 60 * scale, plane.PointOnPlane.Z));
  23.             points.Add(new Point3d(pt.X + 50 * scale, pt.Y + 60 * scale, plane.PointOnPlane.Z));
  24.             points.Add(new Point3d(pt.X + 50 * scale, pt.Y + 40 * scale, plane.PointOnPlane.Z));
  25.             points.Add(new Point3d(pt.X + 60 * scale, pt.Y + 40 * scale, plane.PointOnPlane.Z));
  26.             points.Add(new Point3d(pt.X + 60 * scale, pt.Y + 30 * scale, plane.PointOnPlane.Z));
  27.             points.Add(new Point3d(pt.X + 30 * scale, pt.Y + 30 * scale, plane.PointOnPlane.Z));
  28.  
  29.             Autodesk.AutoCAD.DatabaseServices.Polyline polyline =
  30.                 new Autodesk.AutoCAD.DatabaseServices.Polyline();
  31.             for (int i = 0; i < points.Count; i++)
  32.             {
  33.                 polyline.AddVertexAt(i, points[i].Convert2d(plane), 0.0, 0.0, 0.0);
  34.             }
  35.             polyline.ColorIndex = 150;
  36.             wd.Geometry.Draw(polyline); // Так не работает - вылетает автокад с фатальной ошибкой
  37.             wd.Geometry.Polyline(points, plane.Normal, IntPtr.Zero); // Так работает, но этого мало
  38.         }
  39.     return base.WorldDraw(drawable, wd);
  40. }
Я в комментарии написал, что этого мало и вот почему: вопрос - можно ли отрисовать как-то закрашенную фигуру? Например, при создании Grip'ов можно нарисовать любую фигуру и закрасить ее нужным цветом. А тут получается только наипростейшая фигура, у которой я не могу поменять ни цвет, ни толщину, не могу создать заливку.
Все примеры, которые я нахожу, совсем на другие темы (
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 30-08-2017, 23:13:55
С заданием цвета разобрался. Делается так:
Код - C# [Выбрать]
  1. short backupColor = wd.SubEntityTraits.Color;
  2. wd.SubEntityTraits.Color = 150;
  3. wd.Geometry.Polyline(points, plane.Normal, IntPtr.Zero);
  4. wd.SubEntityTraits.Color = backupColor;
Остальные вопросы пока не решены

UPD==========================
Как сделать залитый полигон тоже разобрался. Не так уж все и страшно оказалось))
Код - C# [Выбрать]
  1. short backupColor = wd.SubEntityTraits.Color;
  2. wd.SubEntityTraits.FillType = FillType.FillAlways;
  3. wd.SubEntityTraits.Color = 150;
  4. wd.Geometry.Polygon(points);
  5. wd.SubEntityTraits.FillType = FillType.FillNever;
  6. wd.SubEntityTraits.Color = backupColor;

Остался вопрос - размер в процентах от экрана
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 30-08-2017, 23:33:12
Остался вопрос - размер в процентах от экрана
Высота видового экрана в единицах чертежа:
Код - C# [Выбрать]
  1. double height = (double)Application.GetSystemVariable("VIEWSIZE");
Высота и ширина видового экрана в пикселях:
Код - C# [Выбрать]
  1. Point2d screensize = (Point2d)Application.GetSystemVariable("SCREENSIZE");
Думаю этой информации тебе будет достаточно.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 31-08-2017, 09:48:16
Александр Ривилис, спасибо! Освежили память)

Но у меня остался один вопрос из разряда теоретики - вариант как на скрине в топике (для параметризации) сделан явно без использования Drawable Overrule, так как там окошко с кнопкой и контекстным меню. Может это какие-то особые механизмы, к которым нет доступа в API
И еще вопрос - в Civil реализовано отображение предупреждений (треугольник с восклицательным знаком) - вот это ближе к Drawable Overrule по поведению. Но такой значок я лично не представляю как можно нарисовать. Это как реализовано?

(https://s26.postimg.org/5v9nzsuv9/image_2017-08-31_09-43-48.png) (https://postimg.org/image/5v9nzsuv9/)
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Владимир Шу от 31-08-2017, 10:27:51
Но такой значок я лично не представляю как можно нарисовать. Это как реализовано?

Скорее всего это просто символ шрифта, как пример посмотри Segoe UI Symbol там под номером U+26A0 похожий значок
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Ficecream.me%2Fuploads%2F602a23762ab183a59140035bd848d60c.png&hash=ee28d7ebe2e05ad0cf74b02f295d3534)
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 31-08-2017, 10:29:28
Владимир Шу, кхм... Хорошее предположение и вполне логичное. Спасибо. Погляжу символы - может и мне подходящий найдется
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 31-08-2017, 10:44:27
вариант как на скрине в топике (для параметризации) сделан явно без использования Drawable Overrule, так как там окошко с кнопкой и контекстным меню.
Ну это и сделано не с помощью AutoCAD .NET API, а с помощью ObjectARX. Хотя возможно при помощи GripsOverrule это можно сделать. Надо ли только такие сложности?
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 31-08-2017, 10:54:14
Скорее всего это просто символ шрифта, как пример посмотри Segoe UI Symbol там под номером U+26A0 похожий значок
Возможно, хотя я бы был осторожнее со шрифтами, которых может просто не быть на PC.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Владимир Шу от 31-08-2017, 10:59:43
Segoe  это семейство системных шрифтов и в винде с висты...
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 31-08-2017, 11:08:24
Надо ли только такие сложности?
Нет конечно) Просто хотелось понять как они это реализовали
Единственное, что мне не нравится в варианте с Drawable Overrule - то, что если я буду размер "значка" делать в зависимости от размера экрана (в процентах), то он будет перерисовываться после вызова Regen. Я конечно не пробовал, но по опыту работы в Civil почти на 100% уверен, что это так
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 31-08-2017, 11:35:07
Единственное, что мне не нравится в варианте с Drawable Overrule - то, что если я буду размер "значка" делать в зависимости от размера экрана (в процентах), то он будет перерисовываться после вызова Regen.
Ты имеешь в виду, что он будет перерисовывать только после вызова Regen? Чтобы этого избежать придётся потрудится и обрабатывать все изменения размера экрана  (высоты экрана в единицах чертежа), а это несколько различных событий, и выполнять обновление своих примитивов, т.е. делать самостоятельно их регенерацию.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Дмитрий Загорулькин от 31-08-2017, 12:14:09
В методе WorldDraw не создаются примитивы. Вот мой пробник с поясняющим комментарием:
Код - C# [Выбрать]
  1. wd.Geometry.Draw(polyline); // Так не работает - вылетает автокад с фатальной ошибкой
Конечно. Draw только рисует, контролировать закрытие объектов он не умеет. Как минимум, после нужно вызывать Dispose для полилинии.
Единственное, что мне не нравится в варианте с Drawable Overrule - то, что если я буду размер "значка" делать в зависимости от размера экрана (в процентах), то он будет перерисовываться после вызова Regen.
Насколько я помню, в Civil 3D значок предупреждения динамически размеры не изменяет, тоже только после регенерации.
А тут получается только наипростейшая фигура, у которой я не могу поменять ни цвет, ни толщину, не могу создать заливку.
Глянь wd.SubEntityTraits - там всё это можно задать.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 31-08-2017, 12:18:20
Насколько я помню, в Civil 3D значок предупреждения динамически размеры не изменяет, тоже только после регенерации
Я это и написал ))
Я конечно не пробовал, но по опыту работы в Civil почти на 100% уверен, что это так
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Дмитрий Загорулькин от 31-08-2017, 12:40:31
Ок, просто не заметил или не так понял  :)
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Кирилл Захаров от 05-09-2017, 16:13:14
Здравствуйте!
Не подскажете какие-нибудь хорошие статьи и примеры про Drawable Overrule и GripsOverrule?
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 05-09-2017, 16:16:32
Тут (http://spiderinnet1.typepad.com/blog/) и тут (http://through-the-interface.typepad.com/through_the_interface/overrules/) есть примеры. Еще, если погуглить, можно найти. Но если вы ищите на русском, да с объяснениями - увы - нет такого сокровища
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Кирилл Захаров от 05-09-2017, 16:17:56
Спасибо. Да, на английском много вроде.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 05-09-2017, 16:20:11
Вот еще очень интересный блог (http://drive-cad-with-code.blogspot.ru/) - там много хороших примеров, в том числе и по Overrule. Только находится этот блог не на первых страницах гугла, поэтому не все его находят
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 14-09-2017, 11:56:18
Поднимаю тему.
Реализовал я свою задумку
Извините, вам запрещён просмотр содержимого спойлеров.

Вроде ничего там страшного нет такого. Ну как мне кажется. НО! У некоторых пользователей при включенном режиме (при активном DrawableOverrule) при сохранении документа происходит фатал
У меня не получается воспроизвести ошибку, поэтому нужно мнение опытных людей с предположениями о причинах
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Дмитрий Загорулькин от 14-09-2017, 12:13:31
Есть два момента, которые мне сильно не нравятся:
1. wd.SubEntityTraits.FillType не восстанавливается исходное состояние, как это сделано для wd.SubEntityTraits.Color.
2. в методе ShowIcon() нет проверки на то, что MpProductsDrawableOverrule уже было ранее включено.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 14-09-2017, 12:32:33
1. wd.SubEntityTraits.FillType не восстанавливается исходное состояние, как это сделано для wd.SubEntityTraits.Color.
Спасибо, учту. Но это вряд-ли является причиной
2. в методе ShowIcon() нет проверки на то, что MpProductsDrawableOverrule уже было ранее включено
Да, ты прав! Не предусмотрел. Но тоже не критично. Выскакивает ошибка

(https://s26.postimg.org/9wxk9i3yd/Screenshot_4.png) (https://postimg.org/image/9wxk9i3yd/)

Но автокад не падает. Исправлю конечно же, но сейчас это не так страшно

И еще вопрос по теме - можно эту геометрию предусмотреть так, чтобы она была только в модели и не показывалась на листах, и не выходила на печать?
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Дмитрий Загорулькин от 14-09-2017, 15:39:26
Но это вряд-ли является причиной
Я так подозреваю, что причина с большой вероятностью может быть в других участках кода.
можно эту геометрию предусмотреть так, чтобы она была только в модели и не показывалась на листах
Вроде как, для обработки отображения с учётом вариаций на видовых экранах листов, нужно переопределять метод ViewportDraw.
и не выходила на печать?
Единственный вариант, который приходит в голову - отслеживать события запуска-завершения команды печати. Перед выводом на печать, как правило, выполняется регенерация и метод перерисовки, соответственно, вызывается. Поэтому, в методе перерисовки достаточно будет проверить, что в настоящий момент выполняется команда печати, и не рисовать дополнительную геометрию. Но эту идею надо проверять, сам не пробовал.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Владимир Шу от 14-09-2017, 15:42:44
и не выходила на печать?
Цвет меняешь.... может на слой Defpoints перевести маркер?
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 14-09-2017, 15:50:54
Единственный вариант, который приходит в голову - отслеживать события запуска-завершения команды печати.
Думаю, что это должно быть лучше: Context.IsPlotGeneration
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Владимир Шу от 14-09-2017, 15:54:54
http://adn-cis.org/kak-opredelit,-chto-myi-naxodimsya-v-kontekste-pechati.html и статья  есть
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 14-09-2017, 15:56:53
http://adn-cis.org/kak-opredelit,-chto-myi-naxodimsya-v-kontekste-pechati.html и статья  есть
Точно. Я даже забыл, что переводил эту статью.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Владимир Шу от 14-09-2017, 16:12:45
Александр Пекшев aka Modis, в строке 37 падает во время перетаскивания объекта... без фатала, но все таки...
Хотя вот тут http://www.arch-pub.com/Fatal-error-override-WorldDraw_10652461.html пишут, что может и с фаталом упасть..
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 14-09-2017, 16:24:42
У некоторых пользователей при включенном режиме (при активном DrawableOverrule) при сохранении документа происходит фатал
При сохранении или при закрытии документа или при завершении AutoCAD?
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Владимир Шу от 14-09-2017, 16:53:32
Александр Ривилис,  а как можно узнать, что объект в данный момент редактируется, скажем растягивается за ручку (Jig) и соответственно в строке extents = ent.GeometricExtents; обойти ошибку? try-catch как то не очень нравиться.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Ривилис от 14-09-2017, 18:07:52
try-catch как то не очень нравиться.
Ставь try/catch - дешевле будет. Исключение может возникнуть и по другим причинам, а не только потому что растягивают объект. Вообще же при Jig обычно участвуют не сами объекты, а их клоны, т.е. их свойство ObjectId == ObjectId.Null
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Владимир Шу от 14-09-2017, 18:35:55
Ставь try/catch - дешевле будет. Исключение может возникнуть и по другим причинам, а не только потому что растягивают объект. Вообще же при Jig обычно участвуют не сами объекты, а их клоны, т.е. их свойство ObjectId == ObjectId.Null
Спасибо. понял почему падало. Я убрал фильтрацию по объектам ModPlus (if (ent.IsModPlusProduct()) и рисовал значок для всех объектов, а при растягивании, при включенном динамическом вводе, создаются временные размеры, у которых запрос свойства GeometricExtents и вызывает ошибку. и да, у них ObjectId == ObjectId.Null .

Александр Пекшев aka Modis,  еще заметил, что вот эта строка:
var pt = extents.MaxPoint.TransformBy(ucs.Inverse());
не очень хорошее решение, так как может получаться вот так:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Ficecream.me%2Fuploads%2F911c36737aba6593db87284048362348.png&hash=39d321b0164c751655454f7f8107bb08)
Наверное стоит для наследников Curve, брать просто EndPoint ...
И вот это не очень
points.Add(new Gem.Point3d(pt.X + (offset + 00) * scale, pt.Y + (offset + 00) * scale, plane.PointOnPlane.Z));
наверное стоит задавать векторами, в соответствии с направлением линии на конце которой строится иконка...

Уронить автокад в фатал при сохранении пока не удалось.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 18-09-2017, 11:55:16
Спасибо за ответы. С кодом пока не занимался, но учту все, что было описано. У меня как раз есть файл (от пользователя), который точно не открывается при включенном Overrule. Падает с фаталом
var pt = extents.MaxPoint.TransformBy(ucs.Inverse());
не очень хорошее решение, так как может получаться вот так:
Я знаю об этом варианте поворота, но пока ничего не придумал. Брать EndPoint не вариант, т.к. я и обычный блок могу повернуть в "такое состояние"
И вот это не очень
points.Add(new Gem.Point3d(pt.X + (offset + 00) * scale, pt.Y + (offset + 00) * scale, plane.PointOnPlane.Z));
наверное стоит задавать векторами, в соответствии с направлением линии на конце которой строится иконка...
Пока что не вижу причин, чтобы переживать в этом месте )
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Дмитрий Загорулькин от 18-09-2017, 12:22:42
Пока что не вижу причин, чтобы переживать в этом месте )
Причина может быть в том, что поддерживать такой код сложно - он трудночитаемый. И ещё, если нужно будет внести какие-то правки, то это придётся делать одновременно в нескольких строчках. Есть риск, что где-то забудешь изменить.
Название: Re: Визуальная идентификация объектов с определенными расширенными данными
Отправлено: Александр Пекшев aka Modis от 22-09-2017, 01:25:58
Наконец-то дошли руки. Внес изменения с учётом замечаний. Тестовый файл, который точно падал, теперь не падает. Всем спасибо за советы! Надеюсь больше проблем не вылезет

Извините, вам запрещён просмотр содержимого спойлеров.