GripOverrule в C3D

Автор Тема: GripOverrule в C3D  (Прочитано 21213 раз)

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

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

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
GripOverrule в C3D
« : 22-12-2017, 03:01:39 »
Друзья, а кто-нибудь успешно применял переопределение ручек в C3D2018?
У меня имеется весьма странная ситуация: есть программа, в которой кроме всего прочего реализовано переопределение ручек для полилинии. В AutoCAD 2017 и C3D 2017 работает без каких либо замечаний; в AutoCAD 2018 так же работает все замечательно, а вот в C3D 2018, при попытке перенести переопределенную ручку вылазит фаталити:


************** Текст исключения **************
System.ArgumentException: Элемент с тем же ключом уже был добавлен.
   в System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   в System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   в AcMgGripOverrule.getGripPoints(AcMgGripOverrule* , AcDbEntity* pSubject, AcArray<AcDbGripData \*\,AcArrayMemCopyReallocator<AcDbGripData \*> >* grips, Double curViewUnitSize, Int32 gripSize, AcGeVector3d* curViewDir, Int32 bitflags)

Именно такая ошибка у меня была, когда я пытался переопределить ручки трассы C3D, а потом узнал, что трассы переопределение ручек не поддерживают в принципе.
Данная проблема наблюдается на всех имеющихся проектах для AutoCAD, где имело место переопределение ручек. Неужели какие-то библиотеки C3D блокируют работу переопределенных ручек, даже для автокадовских объектов?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #1 : 22-12-2017, 11:22:39 »
Теоретически возможно это и баг, но без кода (а точнее готового примера проекта) как ты предлагаешь искать ошибку?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #2 : 22-12-2017, 11:27:01 »
Почитай вот эту тему: http://adn-cis.org/forum/index.php?topic=7814.0
Там ошибка один в один с твоей.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #3 : 22-12-2017, 11:54:37 »

омагад!!!

У меня в том месте вот это:
Код - C# [Выбрать]
  1. using (OpenCloseTransaction trans = new OpenCloseTransaction())

Точно хакеры взломали мой компьютер и переписали этот кусок кода )))
Вечером буду менять транзакцию и проверять.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #4 : 23-12-2017, 03:30:57 »
Похоже, что все-таки парни из Автодеска сломали ручки в C3D2018, причем все - даже автокадовские  :(
Причем в C3D после первого перетаскивания, достаточно выбрать объект, чтобы словить фатальную ошибку.

Вот как работает простое приложение для переопределения ручек полилинии на AutoCAD 2018:


А вот так работает это же приложение в Civil 3D 2018:


Вот исходный код:
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Gi = Autodesk.AutoCAD.GraphicsInterface;
  9. using Autodesk.AutoCAD.Colors;
  10.  
  11. namespace testgrips
  12. {
  13.     public class ImplementClass : IExtensionApplication
  14.     {
  15.         public void Initialize()
  16.         {
  17.             if (Application.DocumentManager.MdiActiveDocument == null)
  18.                 return;
  19.  
  20.             ObjectOverrule.AddOverrule(RXClass.GetClass(typeof(Polyline)), CableLineGripOverruleClass.Instance, true);
  21.         }
  22.  
  23.         public void Terminate() { }
  24.     }
  25.  
  26.     public class CableLineGripOverruleClass : GripOverrule
  27.     {
  28.         public static CableLineGripOverruleClass Instance = new CableLineGripOverruleClass();
  29.  
  30.         public override void GetGripPoints(Entity entity, GripDataCollection grips, double curViewUnitSize, int gripSize, Vector3d curViewDir, GetGripPointsFlags bitFlags)
  31.         {
  32.             Polyline pline = (Polyline)entity;
  33.  
  34.             if (pline.NumberOfVertices > 0)
  35.             {
  36.                 Point3d pnt1 = pline.StartPoint;
  37.                 MoveGripClass grip1 = new MoveGripClass(pnt1);
  38.                 grips.Add(grip1);
  39.  
  40.                 Point3d pnt2 = pline.EndPoint;
  41.                 MoveGripClass grip2 = new MoveGripClass(pnt2);
  42.                 grips.Add(grip2);
  43.             }
  44.         }
  45.  
  46.         public override void MoveGripPointsAt(Entity _ent, GripDataCollection grips, Vector3d offset, MoveGripPointsFlags bitFlags)
  47.         {
  48.             if (grips.Count == 0) return;
  49.  
  50.             Polyline pline = (Polyline)_ent;
  51.  
  52.             Point3d pnt = grips[0].GripPoint;
  53.             Point3d pntm = grips[0].GripPoint + offset;
  54.             Point2d pnt2 = new Point2d(pntm.X, pntm.Y);
  55.             int n = pline.NumberOfVertices;
  56.  
  57.             if (pnt == pline.StartPoint)
  58.                 pline.SetPointAt(0, pnt2);
  59.  
  60.             if (pnt == pline.EndPoint)
  61.                 pline.SetPointAt(n - 1, pnt2);
  62.         }
  63.     }
  64.  
  65.     public class MoveGripClass : GripData
  66.     {
  67.         public MoveGripClass(Point3d _point) : base()
  68.         {
  69.             GripPoint = _point;
  70.         }
  71.  
  72.         public override bool ViewportDraw(Gi.ViewportDraw _wd, ObjectId _entid, DrawType _type, Point3d? _imageGripPoint, int _gripSizeInPixels)
  73.         {
  74.             Point2d unit = _wd.Viewport.GetNumPixelsInUnitSquare(GripPoint);
  75.             double dR = 1 / unit.X;
  76.             double dr = dR / 3.0;
  77.  
  78.             Point3dCollection pnts = new Point3dCollection();
  79.             pnts.Add(new Point3d(GripPoint.X - 1, GripPoint.Y - 1, 0));
  80.             pnts.Add(new Point3d(GripPoint.X, GripPoint.Y + 1, 0));
  81.             pnts.Add(new Point3d(GripPoint.X + 1, GripPoint.Y - 1, 0));
  82.  
  83.             _wd.SubEntityTraits.FillType = Gi.FillType.FillAlways;
  84.             _wd.SubEntityTraits.Color = 1;
  85.             _wd.Geometry.Polygon(pnts);
  86.  
  87.             _wd.SubEntityTraits.FillType = Gi.FillType.FillNever;
  88.             _wd.SubEntityTraits.TrueColor = new EntityColor(0, 0, 0);
  89.             _wd.Geometry.Polygon(pnts);
  90.  
  91.             return true;
  92.         }
  93.     }
  94. }

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #5 : 23-12-2017, 14:30:51 »
Второе видео похоже не полное. Во всяком случае я не понял чем это заканчивается. Ручка вроде перенеслась.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #6 : 23-12-2017, 17:58:18 »
Скринкаст от автодеска перестает записывать, когда автокад падает. Вот полное видео:
http://www.screencast.com/t/Wi5ZIhQIp

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #7 : 23-12-2017, 18:16:32 »
Скринкаст от автодеска перестает записывать, когда автокад падает. Вот полное видео:
http://www.screencast.com/t/Wi5ZIhQIp
Странно. У меня не перестаёт.
Ошибка e0434352h достаточно распространённая. Часто решается обновлением видеодрайвера/отключением аппаратного ускорения видео. Возможно к ручкам прямого отношения не имеет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #8 : 23-12-2017, 19:08:34 »
Отключил аппаратное ускорение - нет изменений. Установил наисвежейший драйвер видео от 20.12.2017 - нет изменений. Включал/отключал аппаратное ускорение с новым драйвером - нет изменений.
Заметил еще одно проявление этой ошибки: если после первого перетаскивания ручки попытаться перетащить вторую, то вся графика, кроме ручек, пропадает. После регенерации графика появляется, но на работу с ручками всегда реагирует одинаково. Если попытаться изменить свойство этой полилинии, появляется интересное сообщение: "Объект был открыт для чтения"
https://www.screencast.com/t/byJjDtWyohp

Эта проблема есть у меня и у моего клиента, который тестирует программу на C3D2018, т.е. это проблема в самом C3D, а не в настройках конкретной машины.
У Димы так же не работают ручки в C3D2018.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #9 : 23-12-2017, 20:21:04 »
Эта проблема есть у меня и у моего клиента, который тестирует программу на C3D2018, т.е. это проблема в самом C3D, а не в настройках конкретной машины.
У Димы так же не работают ручки в C3D2018.
Значит пиши в ADN DevHelp. Возможно какие-то их Overrule в Civil 3D конфликтуют.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #10 : 23-12-2017, 20:23:00 »
Если попытаться изменить свойство этой полилинии, появляется интересное сообщение: "Объект был открыт для чтения"
А это значит, что кто-то (или ты или C3D или какое-то стороннее приложение) открыло полилинию, но забыло её закрыть.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #11 : 23-12-2017, 20:30:47 »
А это значит, что кто-то (или ты или C3D или какое-то стороннее приложение) открыло полилинию, но забыло её закрыть.
Вот это и очень странно: мое приложение (приведенное выше) вообще ничего не делает с полилинией. А это значит, что проблема в самом C3D2018, тем более, что это же приложение прекрасно работает на ACAD2018.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #12 : 23-12-2017, 20:35:12 »
А это значит, что проблема в самом C3D2018, тем более, что это же приложение прекрасно работает на ACAD2018.
Вполне возможно если нет еще какого-то приложения.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #13 : 23-12-2017, 20:44:39 »
Вот это и очень странно: мое приложение (приведенное выше) вообще ничего не делает с полилинией.
Ну не совсем так. Кстати, ты нигде в коде не проверяшь можно ли её менять и вообще полилиния ли тебе на вход пришла. И я не вижу вызова base.MoveGripPointsAt. Так и задумано?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #14 : 23-12-2017, 20:46:55 »
Так и задумано?
Да - это максимально упрощенный пример. В действительности у меня там много различных проверок.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #15 : 23-12-2017, 21:31:27 »
У меня идей не осталось. Вероятнее всего это баг в C3D 2018. Надеюсь, что ты проверил при всех установленных обновлениях. Так что единственный маршрут - отправлять в ADN DevHelp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #16 : 23-12-2017, 21:33:02 »
Так что единственный маршрут - отправлять в ADN DevHelp.
Как раз этого я и хочу. Вы можете отправить такой запрос?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #17 : 23-12-2017, 22:13:17 »
Так что единственный маршрут - отправлять в ADN DevHelp.
Как раз этого я и хочу. Вы можете отправить такой запрос?
Могу. Но тебе нужно подготовить несколько вещей:
1. Приведённый тобой код в виде проекта в zip-архиве (комментарии в коде только английские).
2. Видео как это нормально работает в AutoCAD 2018 (Autodesk Screencast)
3. Видео как это ненормально работает в C3D 2018 (Autodesk Screencast, но укажешь делать видео с полного экрана)
Проверь, что у тебя последняя версия Autodesk Screencast - он недавно обновлялся.
Отправлю.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #18 : 23-12-2017, 22:30:36 »
Попробуй еще этот пример: http://through-the-interface.typepad.com/through_the_interface/2012/09/overriding-the-grips-of-an-autocad-polyline-to-maintain-fillet-segments-using-net.html
Если в C3D 2018 он не работает - значит точно баг.
Запускаешь команду GOO, рисуется полилиния с дугами, дергаешь полилинию за ручки.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #19 : 25-12-2017, 13:23:33 »
Если в C3D 2018 он не работает - значит точно баг.
Не самый лучший пример. Он в Сивиле вообще крайне плохо работает: ручки рисует где-то далеко в космосе от объекта :)
Вот тут я об этом писал: http://forum.dwg.ru/showpost.php?p=1095608&postcount=4

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #20 : 25-12-2017, 13:36:40 »
В той же теме на dwg.ru ниже есть подправленный под Civil код. Загрузил его в 2018 - глючит :(
При первом перемещении ручки - всё ок, но при последующих - ручка отлетает на место, а отображение полилинии пропадает. Регенерация возвращает отображение объекта, но поведение ручек не исправляется.
Видео:

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #21 : 25-12-2017, 13:55:57 »
Ну и, для сравнения, как это должно работать. На примере 2017 версии:

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #22 : 25-12-2017, 14:03:39 »
Дима, у тебя есть готовый проект, который можно с техподдержку заслать? Я смогу его подготовить только после НГ.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #23 : 25-12-2017, 14:06:09 »
Дима, у тебя есть готовый проект, который можно с техподдержку заслать? Я смогу его подготовить только после НГ.
Можешь не торопиться. У них тоже праздники.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #24 : 25-12-2017, 14:06:49 »
Дмитрий Загорулькин
А пример Алексей Терно у тебя тоже приводит к Fatal Error?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #25 : 25-12-2017, 14:25:45 »
А пример Алексей Терно у тебя тоже приводит к Fatal Error?
С тем кодом такая ситуация:
1. Если без изменений кода тестировать - да, фатал эррор.
2. Если изменить код таким образом, то поведение такое же, как у меня в видео выше:
Код - C# [Выбрать]
  1. public class ImplementClass
  2.     //: IExtensionApplication
  3. {
  4.     [CommandMethod("TestGripOverrule")]
  5.     public void AddOverrule()
  6.     {
  7.         ObjectOverrule.AddOverrule(RXClass.GetClass(typeof(Polyline)), CableLineGripOverruleClass.Instance, true);
  8.     }
  9.  
  10.     //public void Initialize()
  11.     //{
  12.     //    if (Application.DocumentManager.MdiActiveDocument == null)
  13.     //        return;
  14.  
  15.     //    ObjectOverrule.AddOverrule(RXClass.GetClass(typeof(Polyline)), CableLineGripOverruleClass.Instance, true);
  16.     //}
  17.  
  18.     //public void Terminate() { }
  19. }    
  20.  
То есть, если добавлять Overrule в методе Initialize, то фаталит. Если командой после полной загрузки Сивила - то просто глючит.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #26 : 25-12-2017, 14:27:33 »
просто глючит
От этого не легче - программа все равно становиться нерабочей.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #27 : 25-12-2017, 14:27:58 »
Можешь не торопиться. У них тоже праздники.
Можно вообще не торопиться. Моё последнее обращение в ADN уже третью неделю без ответа висит :(
От этого не легче - программа все равно становиться нерабочей.
Согласен. Мне такое поведение тоже сильно не нравится. Придётся проверять версию Civil 3D и просто отключать Grip Overrule, если это 2018 версия. Потому что исправить это могут только разработчики Civil. А каких-то возможных обходных путей я лично не вижу.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #28 : 25-12-2017, 14:42:57 »
Можно вообще не торопиться. Моё последнее обращение в ADN уже третью неделю без ответа висит
Я написал Ярославу Решетникову, чтобы он оказал помощь в проталкивании запроса по этой ошибку, но он вернется из отпуска только 8 января, так что, парни, курим бамбук :)

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #29 : 25-12-2017, 14:44:24 »
Придётся проверять версию Civil 3D и просто отключать Grip Overrule, если это 2018 версия.
А что делать, если весь дополнительный функционал реализован через ручки? В этом случае приложение целиком теряет свою функциональность.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #30 : 25-12-2017, 16:53:15 »
Похоже, что и сам C3D использует Overrule для полилиний, но как-то не корректно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #31 : 25-12-2017, 17:04:14 »
Эта проблема не только с полилиниями. Такая же беда с трубами. А свои ручки меток труб и колодцев я уже давно отключил в 2018, потому что они даже с родными ручками глючат, а с переопределёнными сразу в фатал падают. Но об этой проблеме Autodesk уже давно знает.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #32 : 25-12-2017, 17:05:49 »
об этой проблеме Autodesk уже давно знает
Точно знает?

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #33 : 25-12-2017, 17:10:55 »
Я имел в виду, что Autodesk знает о проблеме с метками трубопроводных сетей. На бета-портале можно найти репорт (если есть доступ) и посмотреть, от какого он числа.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #34 : 25-12-2017, 17:17:01 »
А они хоть как-то на это отреагировали или этот отчет там просто висит?

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #35 : 25-12-2017, 17:19:09 »
Я не уверен, что можно свободно распространять информацию о том, что происходит на бета-портале :) Зарегистрируйся и увидишь ;)

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #36 : 25-12-2017, 17:24:52 »
На выходных посмотрю новую бету - как она с ручками справляется.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #37 : 25-12-2017, 17:27:30 »
Если имеешь в виду версию 2018.2, то я именно на ней проверял. Вроде как, более новой версии даже в пре-релизе нет.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #38 : 25-12-2017, 17:32:49 »
Извините, вам запрещён просмотр содержимого спойлеров.
« Последнее редактирование: 25-12-2017, 17:34:10 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #39 : 25-12-2017, 17:35:00 »
Извините, вам запрещён просмотр содержимого спойлеров.
Это конфиденциальная информация, доступная только бета-тестерам. Даже здесь её не следует публиковать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #40 : 26-12-2017, 02:29:23 »
Это конфиденциальная информация, доступная только бета-тестерам. Даже здесь её не следует публиковать.
Даже просто о существовании бета версий??

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #41 : 26-12-2017, 02:34:03 »
Зачем ты у меня об этом спрашиваешь? Перечитай NDA, которое подписывал.
В любом случае о датах выхода бета версий, изменений/добавлений/исключений в них, и т.д. и т.п. мы здесь на форуме обсуждать не имеем права. Так что все разговоры о бета-версиях прекращаем.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #42 : 26-12-2017, 15:02:19 »
Попробовал покопаться в этой проблеме, получил немного сведений.
1. Выбираем объект, происходит первый вызов метода GetGripPoints, рисуются переопределённые ручки - проблем нет. То есть, если ручки не перемещать, то сбоев не возникает.
2. Цепляем ручку, перетаскиваем на новое место. Сразу после перемещения (когда ручка перемещена и кнопка мыши отпущена) происходят ещё два вызова GetGripPoints. При первом вызове не возникает проблем, при втором - при выходе из метода происходит исключение:
Exception thrown: 'System.ArgumentException' in mscorlib.dll
Additional information: Элемент с тем же ключом уже был добавлен. occurred
Полная трассировка исключения:
mscorlib.dll!System.ThrowHelper.ThrowArgumentException(System.ExceptionResource resource) + 0x38 bytes
mscorlib.dll!System.Collections.Generic.Dictionary<System.IntPtr, System.Collections.Generic.List<Autodesk.AutoCAD.DatabaseServices.GripData>>.Insert(System.IntPtr key, System.Collections.Generic.List<Autodesk.AutoCAD.DatabaseServices.GripData> value, bool add) + 0x285 bytes
AcDbMgd.dll!<Module>.AcMgGripOverrule.getGripPoints + 0x013c bytes
Это исключение рушит работу AcDbMgd.dll и потом уже с помощью ручек объект не редактируется и исчезает при попытке переместить ручку - собственно, то самое поведение, которое есть на видео. Думаю, что если дальше продолжать работу после этого исключения, то в какой-то момент вылезет фатал.
Попробовал посмотреть AcMgGripOverrule.getGripPoints в AcDbMgd.dll - класс AcMgGripOverrule помечен как Native, реализации его в этой dll нет. Соответственно, никак не посмотреть, что этот метод делает.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #43 : 26-12-2017, 15:05:11 »
2. Цепляем ручку, перетаскиваем на новое место. Сразу после перемещения (когда ручка перемещена и кнопка мыши отпущена) происходят ещё два вызова GetGripPoints. При первом вызове не возникает проблем, при втором - при выходе из метода происходит исключение:
А тоже самое в чистом AutoCAD 2018 тоже приводит к двум вызовам GetGripPoints?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #44 : 26-12-2017, 15:07:46 »
Ну у меня чистого AutoCAD нет. Но я проверил в C3d 2017 - порядок вызовов точно такой же.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #45 : 26-12-2017, 15:08:54 »
По хорошему в GetGripPoints нужно анализировать что уже есть в grips и не добавлять туда объекты, которые уже там есть.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #46 : 26-12-2017, 15:10:56 »
Я смотрел состав коллекции ручек на входе в метод - она пустая.
Знаете, что забавно - вот так работает без проблем :) :
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.DatabaseServices;
  2. using Autodesk.AutoCAD.Geometry;
  3. using Autodesk.AutoCAD.GraphicsInterface;
  4. using Autodesk.AutoCAD.Runtime;
  5.  
  6. namespace testgrips
  7. {
  8.     public class ImplementClass
  9.     {
  10.         [CommandMethod("TestGripOverrule")]
  11.         public void AddOverrule()
  12.         {
  13.             ObjectOverrule.AddOverrule
  14.                 (RXClass.GetClass(typeof(Line)),
  15.                 CableLineGripOverruleClass.Instance, true);
  16.         }
  17.     }
  18.  
  19.     public class CableLineGripOverruleClass : GripOverrule
  20.     {
  21.         public static CableLineGripOverruleClass Instance
  22.             = new CableLineGripOverruleClass();
  23.  
  24.         public override void GetGripPoints
  25.             (Entity entity, GripDataCollection grips,
  26.             double curViewUnitSize, int gripSize,
  27.             Vector3d curViewDir, GetGripPointsFlags bitFlags)
  28.         {
  29.             if (entity is Line line)
  30.             {
  31.                 if (counter == 0)
  32.                 {
  33.                     Point3d pnt1 = line.StartPoint;
  34.                     MoveGripClass grip1 = new MoveGripClass(pnt1, PointType.Start);
  35.                     grips.Add(grip1);
  36.  
  37.                     Point3d pnt2 = line.EndPoint;
  38.                     MoveGripClass grip2 = new MoveGripClass(pnt2, PointType.End);
  39.                     grips.Add(grip2);
  40.                     counter++;
  41.                 }
  42.             }
  43.         }
  44.  
  45.         int counter = 0;
  46.  
  47.         public override void MoveGripPointsAt
  48.             (Entity entity, GripDataCollection grips,
  49.             Vector3d offset, MoveGripPointsFlags bitFlags)
  50.         {
  51.             if (entity is Line line)
  52.             {
  53.                 counter = 0;
  54.                 foreach (GripData grip in grips)
  55.                 {
  56.                     if (grip is MoveGripClass myGrip)
  57.                     {
  58.                         Point3d newPos3d = myGrip.GripPoint + offset;
  59.                         switch (myGrip.Type)
  60.                         {
  61.                             case PointType.Start:
  62.                                 line.StartPoint = newPos3d;
  63.                                 break;
  64.                             case PointType.End:
  65.                                 line.EndPoint = newPos3d;
  66.                                 break;
  67.                         }
  68.                     }
  69.                 }
  70.             }
  71.         }
  72.     }
  73.  
  74.     public class MoveGripClass : GripData
  75.     {
  76.         public PointType Type;
  77.  
  78.         public MoveGripClass(Point3d _point, PointType ptType) : base()
  79.         {
  80.             GripPoint = _point;
  81.             Type = ptType;
  82.         }
  83.  
  84.         public override bool ViewportDraw
  85.             (ViewportDraw worldDraw, ObjectId entityId,
  86.             GripData.DrawType type, Point3d? imageGripPoint,
  87.             int gripSizeInPixels)
  88.         {
  89.             // Calculate the size of the glyph in WCS
  90.             Point2d glyphSize = worldDraw.Viewport
  91.                 .GetNumPixelsInUnitSquare(this.GripPoint);
  92.             double glyphHeight = (gripSizeInPixels / glyphSize.Y);
  93.             double glyphWeight = (gripSizeInPixels / glyphSize.X);
  94.  
  95.             Matrix3d mx3d = worldDraw.Viewport.ModelToEyeTransform;
  96.             Point3d pt = this.GripPoint.TransformBy(mx3d);
  97.  
  98.             // Draw a glyph
  99.             Point3dCollection pnts = new Point3dCollection();
  100.            
  101.             // rectangle
  102.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y - glyphHeight, pt.Z));
  103.             pnts.Add(new Point3d(pt.X + glyphWeight, pt.Y - glyphHeight, pt.Z));
  104.             pnts.Add(new Point3d(pt.X + glyphWeight, pt.Y + glyphHeight, pt.Z));
  105.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y + glyphHeight, pt.Z));
  106.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y - glyphHeight, pt.Z));
  107.  
  108.             worldDraw.Geometry.PolygonEye(pnts);
  109.  
  110.             return base.ViewportDraw
  111.                 (worldDraw, entityId, type, imageGripPoint, gripSizeInPixels);
  112.         }
  113.     }
  114.  
  115.     public enum PointType
  116.     {
  117.         Start,
  118.         End,
  119.     }
  120. }
То есть, просто игнорируем повторный вызов GetGripPoints после перемещения.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #47 : 26-12-2017, 15:12:05 »
Ну у меня чистого AutoCAD нет.
https://knowledge.autodesk.com/support/autocad/learn-explore/caas/sfdcarticles/sfdcarticles/Startup-switches-for-AutoCAD.html
если запускать с флагом /product ACAD то теоретически должен запускаться чистый AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #48 : 26-12-2017, 15:13:52 »
То есть, просто игнорируем повторный вызов GetGripPoints после перемещения.
Так. А bitFlags в обоих вызовах одинаков? Может быть на него можно ориентироваться?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #49 : 26-12-2017, 15:18:44 »
А bitFlags в обоих вызовах одинаков?
Да, к сожалению, одинаков: DynamicDimensionMode

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #50 : 26-12-2017, 15:22:22 »
То есть, просто игнорируем повторный вызов GetGripPoints после перемещения.
Я только хотел предложить поставить счетчик на вызов этой процедуры ))
Дима, спасибо! Возможно это будет единственным решением.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #51 : 26-12-2017, 15:25:31 »
если запускать с флагом /product ACAD то теоретически должен запускаться чистый AutoCAD.
Я попробовал - та же самая проблема возникает. Может быть, достаточно будет заменить AcDbMgd.dll на аналогичную из чистого AutoCAD?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #52 : 26-12-2017, 15:38:44 »
Я попробовал - та же самая проблема возникает.
Похоже грузятся еще какие-то arx/dbx/dll-файлы, которых нет в чистом AutoCAD.
Может быть, достаточно будет заменить AcDbMgd.dll на аналогичную из чистого AutoCAD?
Думаю, что дело не в ней самой. Более того практически уверен, что они одинаковы, что в чистом AutoCAD, что в C3D. Видимо что-то формирует некорректные параметры для GetGripPoints.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #53 : 26-12-2017, 15:42:32 »
Вот acdbmgd.dll из чистого AutoCAD. Можешь попробовать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #54 : 26-12-2017, 15:52:33 »
Да, абсолютно одинаковы. И замена не помогла.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #55 : 26-12-2017, 16:13:44 »
Вот код метода AcMgGripOverrule.getGripPoints:
Код - C# [Выбрать]
  1. // <Module>
  2. internal unsafe static Acad.ErrorStatus getGripPoints(AcMgGripOverrule* ptr, AcDbEntity* pSubject, AcArray<AcDbGripData *,AcArrayMemCopyReallocator<AcDbGripData *> >* grips, double curViewUnitSize, int gripSize, AcGeVector3d* curViewDir, int bitflags)
  3. {
  4.         GripDataCollection gripDataCollection = null;
  5.         try
  6.         {
  7.                 if (*(ptr + 64L) == 0)
  8.                 {
  9.                         return (Acad.ErrorStatus)1;
  10.                 }
  11.                 GripDataCollection gripDataCollection2 = new GripDataCollection(grips, false);
  12.                 try
  13.                 {
  14.                         gripDataCollection = gripDataCollection2;
  15.                         Vector3d curViewDir2 = new Vector3d(curViewDir);
  16.                         IntPtr unmanagedPointer = new IntPtr((void*)pSubject);
  17.                         AcMgGripOverrule* ptr2 = ptr + 16L;
  18.                         <Module>.gcroot<Autodesk::AutoCAD::DatabaseServices::GripOverrule ^>..PE$AAVGripOverrule@DatabaseServices@AutoCAD@Autodesk@@(ptr2).GetGripPoints((Entity)RXObject.Create(unmanagedPointer, false), gripDataCollection, curViewUnitSize, gripSize, curViewDir2, bitflags);
  19.                         if (gripDataCollection.GetNewItems().Count > 0)
  20.                         {
  21.                                 IntPtr key = new IntPtr((void*)pSubject);
  22.                                 <Module>.gcroot<Autodesk::AutoCAD::DatabaseServices::GripOverrule ^>..PE$AAVGripOverrule@DatabaseServices@AutoCAD@Autodesk@@(ptr2).EntityMap.Add(key, gripDataCollection.GetNewItems());
  23.                         }
  24.                 }
  25.                 catch
  26.                 {
  27.                         ((IDisposable)gripDataCollection).Dispose();
  28.                         throw;
  29.                 }
  30.                 ((IDisposable)gripDataCollection).Dispose();
  31.         }
  32.         catch (Autodesk.AutoCAD.Runtime.Exception arg_95_0)
  33.         {
  34.                 return (Acad.ErrorStatus)arg_95_0.ErrorStatus;
  35.         }
  36.         return (Acad.ErrorStatus)0;
  37. }
  38.  
Судя по всему имеется некая таблица, в качестве ключа для которой указатель на примитив, а значения - коллекция ручек. Так вот если в этой таблице примитив уже присутствует, то EntityMap.Add(key, gripDataCollection.GetNewItems()) приводит к исключению и коллекция ручек чистится. Я так интерпретировал этот код.

Отсюда напрашивается вывод, что одновременно с GripOverrule для конкретного примитива может работать только одно приложение. И C3D похоже всегда использует GripOverrule в отличие от чистого AutoCAD.
Конечно это утверждение нужно проверять...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #56 : 26-12-2017, 16:23:15 »
А ведь есть второй метод:
Код - C# [Выбрать]
  1. public override void GetGripPoints(Entity entity, Point3dCollection gripPoints, IntegerCollection snapModes, IntegerCollection geometryIds)

Он так же приводит к этой ошибке?
У меня нет на работе 2018 и я не смогу сейчас это сам проверить.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #57 : 26-12-2017, 17:27:58 »
Отсюда напрашивается вывод, что одновременно с GripOverrule для конкретного примитива может работать только одно приложение.
Как-то это странно. Я всегда считал, что можно создать несколько GripOverrule для одного объекта и они будут спокойно сосуществовать. Но надо тестировать, и лучше это делать на голом автокаде.
А ведь есть второй метод:
Что-то даже не соображу, как им воспользоваться.
Я только хотел предложить поставить счетчик на вызов этой процедуры ))
Дима, спасибо! Возможно это будет единственным решением.
Как оказалось, просто счётчик - это не совсем корректно. К примеру, выбрали объект несколько раз, но не перемещали точки - счётчик будет "крутить". Или выбрали несколько объектов, у которых ручки совпадают и перетащили за общую ручку - метод GetGripPoints работает тогда так: один раз по очереди для всех объектов, потом ещё раз по очереди для всех объектов. Исключение будет гарантировано словлено. И напоследок, код со счётчиком плохо работает в Civil 3D 2017 - после перемещения ручки пропадают. Подозреваю, что так же он отработает и в голом автокаде. Поэтому, счётчик надо привязывать к конкретному объекту, запускать только после MoveGripPoint и проверять, что работа выполняется именно в Civil 3D 2018. Ну и сам счётчик можно заменить булевым значением: вызывался метод или ещё нет. Я придумал такой костыль - использовать словарь <ObjectId, bool>. Расписывать долго, вот итоговый код:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.Geometry;
  4. using Autodesk.AutoCAD.GraphicsInterface;
  5. using Autodesk.AutoCAD.Runtime;
  6. using System;
  7. using System.Collections.Generic;
  8.  
  9. namespace testgrips
  10. {
  11.     public class ImplementClass
  12.     {
  13.         [CommandMethod("TestGripOverrule")]
  14.         public void AddOverrule()
  15.         {
  16.             ObjectOverrule.AddOverrule(RXClass.GetClass(typeof(Line)), LineGripOverruleClass.Instance, true);
  17.         }        
  18.     }
  19.  
  20.     public class LineGripOverruleClass : GripOverrule
  21.     {
  22.         static LineGripOverruleClass _instance = new LineGripOverruleClass();
  23.  
  24.         static Dictionary<ObjectId, bool> afterGripMoveProcessedDict = new Dictionary<ObjectId, bool>();
  25.  
  26.         public static LineGripOverruleClass Instance => _instance;
  27.  
  28.         LineGripOverruleClass() { }
  29.  
  30.         public override void GetGripPoints
  31.             (Entity entity, GripDataCollection grips,
  32.             double curViewUnitSize, int gripSize,
  33.             Vector3d curViewDir, GetGripPointsFlags bitFlags)
  34.         {
  35.             if (entity is Line line)
  36.             {                
  37.                 if (afterGripMoveProcessedDict.ContainsKey(line.Id))
  38.                 {
  39.                     if (afterGripMoveProcessedDict[line.Id])
  40.                     {
  41.                         afterGripMoveProcessedDict.Remove(line.Id);
  42.                         return;
  43.                     }
  44.                     else
  45.                     {
  46.                         afterGripMoveProcessedDict[line.Id] = true;
  47.                     }
  48.                 }
  49.  
  50.                 Point3d pnt1 = line.StartPoint;
  51.                 MoveGripClass grip1 = new MoveGripClass(pnt1, PointType.Start);
  52.                 grips.Add(grip1);
  53.  
  54.                 Point3d pnt2 = line.EndPoint;
  55.                 MoveGripClass grip2 = new MoveGripClass(pnt2, PointType.End);
  56.                 grips.Add(grip2);
  57.             }
  58.         }
  59.  
  60.         public override void MoveGripPointsAt
  61.             (Entity entity, GripDataCollection grips,
  62.             Vector3d offset, MoveGripPointsFlags bitFlags)
  63.         {
  64.             if (entity is Line line)
  65.             {
  66.                 if (SupportClass.IsCivil2018 && line.Id.IsValid)
  67.                 {
  68.                     afterGripMoveProcessedDict[line.Id] = false;
  69.                 }
  70.                 foreach (GripData grip in grips)
  71.                 {
  72.                     if (grip is MoveGripClass myGrip)
  73.                     {
  74.                         Point3d newPos3d = myGrip.GripPoint + offset;
  75.                         switch (myGrip.Type)
  76.                         {
  77.                             case PointType.Start:
  78.                                 line.StartPoint = newPos3d;
  79.                                 break;
  80.                             case PointType.End:
  81.                                 line.EndPoint = newPos3d;
  82.                                 break;
  83.                         }
  84.                     }
  85.                 }
  86.             }
  87.         }
  88.     }
  89.  
  90.     public class MoveGripClass : GripData
  91.     {
  92.         public PointType Type;
  93.  
  94.         public MoveGripClass(Point3d _point, PointType ptType) : base()
  95.         {
  96.             GripPoint = _point;
  97.             Type = ptType;
  98.         }
  99.  
  100.         public override bool ViewportDraw
  101.             (ViewportDraw worldDraw, ObjectId entityId,
  102.             GripData.DrawType type, Point3d? imageGripPoint,
  103.             int gripSizeInPixels)
  104.         {
  105.             // Calculate the size of the glyph in WCS
  106.             Point2d glyphSize = worldDraw.Viewport
  107.                 .GetNumPixelsInUnitSquare(this.GripPoint);
  108.             double glyphHeight = (gripSizeInPixels / glyphSize.Y);
  109.             double glyphWeight = (gripSizeInPixels / glyphSize.X);
  110.  
  111.             Matrix3d mx3d = worldDraw.Viewport.ModelToEyeTransform;
  112.             Point3d pt = this.GripPoint.TransformBy(mx3d);
  113.  
  114.             // Draw a glyph
  115.             Point3dCollection pnts = new Point3dCollection();
  116.  
  117.             // rectangle
  118.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y - glyphHeight, pt.Z));
  119.             pnts.Add(new Point3d(pt.X + glyphWeight, pt.Y - glyphHeight, pt.Z));
  120.             pnts.Add(new Point3d(pt.X + glyphWeight, pt.Y + glyphHeight, pt.Z));
  121.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y + glyphHeight, pt.Z));
  122.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y - glyphHeight, pt.Z));
  123.  
  124.             worldDraw.Geometry.PolygonEye(pnts);
  125.  
  126.             return base.ViewportDraw
  127.                 (worldDraw, entityId, type, imageGripPoint, gripSizeInPixels);
  128.         }
  129.     }
  130.  
  131.     static class SupportClass
  132.     {
  133.         public static bool IsCivil2018 =
  134.             IsCivilApplication()
  135.             && Application.Version.Major == 22
  136.             && Application.Version.Minor == 0;
  137.  
  138.         /// <summary>
  139.         /// Является ли запущенный AutoCAD Civil'ом
  140.         /// </summary>
  141.         public static bool IsCivilApplication()
  142.         {
  143.             string rootKeyNumber = null;
  144.             Version ver = Application.Version;
  145.             bool ret;
  146.  
  147.             if (ver.Major == 19 && ver.Minor == 1)
  148.                 rootKeyNumber = "D000";
  149.             else if (ver.Major == 20 && ver.Minor == 0)
  150.                 rootKeyNumber = "E000";
  151.             else if (ver.Major == 20 && ver.Minor == 1)
  152.                 rootKeyNumber = "F000";
  153.             else if (ver.Major == 21)
  154.                 rootKeyNumber = "0000";
  155.             else if (ver.Major == 22 && ver.Minor == 0)
  156.                 rootKeyNumber = "1000";
  157.  
  158.             if (string.IsNullOrEmpty(rootKeyNumber))
  159.             {
  160.                 ret = false;
  161.             }
  162.             else
  163.             {
  164.                 ret = HostApplicationServices.Current
  165.                     .MachineRegistryProductRootKey.Contains(rootKeyNumber);
  166.             }
  167.  
  168.             return ret;
  169.         }
  170.     }
  171.  
  172.     public enum PointType
  173.     {
  174.         Start,
  175.         End,
  176.     }
  177. }
  178.  

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #58 : 26-12-2017, 18:20:16 »
Как-то это странно. Я всегда считал, что можно создать несколько GripOverrule для одного объекта и они будут спокойно сосуществовать. Но надо тестировать, и лучше это делать на голом автокаде.
Я еще раз пересмотрел код этого метода и понял, что был неправ и сделал поспешный вывод. Такая таблица вида [указатель на примитив, коллекция  grips] создаётся для каждого GripOverrule. Так что исключение может возникнуть только при повторном вызове AcMgGripOverrule.getGripPoints для того же самого GripOverrule и Entity.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #59 : 26-12-2017, 18:25:25 »
Что-то даже не соображу, как им воспользоваться.
Вместо пары:
Код - C# [Выбрать]
  1. public virtual void GetGripPoints(
  2.     Entity entity,
  3.     GripDataCollection grips,
  4.     double curViewUnitSize,
  5.     int gripSize,
  6.     Vector3d curViewDir,
  7.     GetGripPointsFlags bitFlags
  8. );
  9. public virtual void MoveGripPointsAt(
  10.     Entity entity,
  11.     GripDataCollection grips,
  12.     Vector3d offset,
  13.     MoveGripPointsFlags bitFlags
  14. );

использовать в классе-наследнике GripOverrule пару:

Код - C# [Выбрать]
  1. public virtual void GetGripPoints(
  2.     Entity entity,
  3.     Point3dCollection gripPoints,
  4.     IntegerCollection snapModes,
  5.     IntegerCollection geometryIds
  6. );
  7. public virtual void MoveGripPointsAt(
  8.     Entity entity,
  9.     IntegerCollection indices,
  10.     Vector3d offset
  11. );

Но возможностей у второй пары значительно меньше.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #60 : 26-12-2017, 18:37:11 »
Я еще раз пересмотрел код этого метода и понял, что был неправ и сделал поспешный вывод. Такая таблица вида [указатель на примитив, коллекция  grips] создаётся для каждого GripOverrule. Так что исключение может возникнуть только при повторном вызове AcMgGripOverrule.getGripPoints для того же самого GripOverrule и Entity.
Я так понимаю, потому что в этой строке
Код - C# [Выбрать]
  1. <Module>.gcroot<Autodesk::AutoCAD::DatabaseServices::GripOverrule ^>..PE$AAVGripOverrule@DatabaseServices@AutoCAD@Autodesk@@(ptr2).EntityMap.Add(key, gripDataCollection.GetNewItems());
есть (ptr2)? :)
В этой абракадабре очень легко что-то не заметить...
Но возможностей у второй пары значительно меньше.
Я посмотрел документацию, если ей верить, то обе IntegterCollection в параметрах метода GetGripPoints не используются (not currently in use). Получается, для задания ручек остаётся только Point3dCollection gripPoints. То есть, можно только указать, где будет новая ручка? И потом по её расположению в этой коллекции, в методе MoveGripPointsAt задавать действие? В принципе, если не нужно собственное отображение ручки, тогда это можно использовать. Если, конечно, я правильно понял принцип использования.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #61 : 26-12-2017, 19:00:48 »
А вот этот второй метод исключений не вызывает! Но! Он довольно криво работает. Как это проявляется: при первом перемещении ручки - всё ок. Но если не снимая выделения с объекта снова переместить ручку, то перемещение удваивается. Вот именно так ведут себя ручки меток трубопроводной сети в Civil 3D 2018 и я уже не первый месяц жду, когда же они это исправят. Теперь понятно, откуда ноги растут у такого поведения.
Вот код:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.DatabaseServices;
  2. using Autodesk.AutoCAD.Geometry;
  3. using Autodesk.AutoCAD.Runtime;
  4. using System.Collections.Generic;
  5.  
  6. namespace AcadTest
  7. {
  8.     public class ImplementClass1
  9.     {
  10.         [CommandMethod("TestGripOverrule1")]
  11.         public void AddOverrule()
  12.         {
  13.             ObjectOverrule.AddOverrule(RXClass.GetClass(typeof(Line)), LineGripOverruleClass1.Instance, true);
  14.         }
  15.     }
  16.  
  17.     public class LineGripOverruleClass1 : GripOverrule
  18.     {
  19.         static LineGripOverruleClass1 _instance = new LineGripOverruleClass1();
  20.  
  21.         public static LineGripOverruleClass1 Instance => _instance;
  22.  
  23.         LineGripOverruleClass1() { }
  24.  
  25.         public override void GetGripPoints(Entity entity, Point3dCollection gripPoints, IntegerCollection snapModes, IntegerCollection geometryIds)
  26.         {
  27.             if (entity is Line line)
  28.             {
  29.                 gripPoints.Add(line.StartPoint);
  30.                 gripPoints.Add(line.EndPoint);
  31.             }
  32.         }
  33.  
  34.         public override void MoveGripPointsAt(Entity entity, IntegerCollection indices, Vector3d offset)
  35.         {
  36.             if (entity is Line line)
  37.             {
  38.                 foreach (int ind in indices)
  39.                 {
  40.                     if (ind == 0)
  41.                     {
  42.                         line.StartPoint += offset;
  43.                     }
  44.                     else if (ind == 1)
  45.                     {
  46.                         line.EndPoint += offset;
  47.                     }
  48.                 }
  49.             }
  50.             else
  51.             {
  52.                 base.MoveGripPointsAt(entity, indices, offset);
  53.             }
  54.         }      
  55.     }    
  56. }
Видео этого безобразия:
« Последнее редактирование: 26-12-2017, 19:48:07 от Дмитрий Загорулькин »

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #62 : 26-12-2017, 21:06:41 »
Довольно интересно работает этот метод:
Код - C# [Выбрать]
  1.         public override void GetGripPoints(Entity entity, Point3dCollection gripPoints, IntegerCollection snapModes, IntegerCollection geometryIds)
  2.         {
  3.             Polyline pline = (Polyline)entity;
  4.  
  5.             Point3d p1 = new Point3d(pline.StartPoint.X + 2, pline.StartPoint.Y, 0);
  6.             Point3d p2 = new Point3d(pline.StartPoint.X - 2, pline.StartPoint.Y, 0);
  7.  
  8.             gripPoints.Add(p1);
  9.             gripPoints.Add(p2);
  10.  
  11.             geometryIds.Add(0);
  12.             geometryIds.Add(1);
  13.  
  14.             //base.GetGripPoints(entity, gripPoints, snapModes, geometryIds);
  15.         }

Метод MoveGripPointsAt я не переопределял.


Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #63 : 26-12-2017, 21:10:45 »
Хех, на одну ручку повесил растяжение, а на другую перемещение. Интересно, а если верхнюю точку перекинуть зеркально на другую сторону по вертикали/горизонтали, поведение ручек поменяется?

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #64 : 26-12-2017, 21:21:16 »
а если верхнюю точку перекинуть зеркально на другую сторону по вертикали/горизонтали, поведение ручек поменяется?
Не понял...

Эти ручки привязываются конкретно к начальной вершине, как бы ты не менял саму полилинию.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #65 : 26-12-2017, 21:29:52 »
Если по красной или по жёлтой стрелочке сместить конец полилинии а потом включить переопределение ручек, поменяются ли у ручек действия местами?

Просто как идея, может быть там что-то типа алгоритма: если перпендикуляр можно опустить на полилинию - растяжение, если нельзя - перемещение.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #66 : 26-12-2017, 21:42:44 »
Если по красной или по жёлтой стрелочке сместить конец полилинии а потом включить переопределение ручек, поменяются ли у ручек действия местами?
Нет - точка растяжения всегда остается справа, как ни крути - pline.StartPoint.X + 2

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #67 : 26-12-2017, 21:46:47 »
Тогда другая гипотеза: по умолчанию первой точке назначается растяжение, второй - перемещение, третьей - поворот, четвёртой - масштабирование ... и т.д.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #68 : 26-12-2017, 21:50:31 »
Тогда другая гипотеза: по умолчанию первой точке назначается растяжение, второй - перемещение, третьей - поворот, четвёртой - масштабирование ... и т.д.
Я думаю, что все гораздо проще:
Код - C# [Выбрать]
  1. gripPoints.Add(p1);
  2. gripPoints.Add(p2);
  3.  
  4. geometryIds.Add(0);
  5. geometryIds.Add(1);

Первой ручке присваивается geometryId=0, что означает, что это точка растяжения.

Я был неправ - эти индексы не влияют на ручки. Скорее всего дело в последовательности добавления, но тогда возникает еще больше вопросов...

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #69 : 27-12-2017, 13:21:18 »
Всё гораздо проще. Действия назначаются в базовом методе полилинии MoveGripPointsAt(Entity, IntegerCollection, Vector3d). В нём прописано, что первая ручка - растяжение начальной точки, вторая ручка - перемещение средней точки первого сегмента полилинии, третья точка - растяжение следующей вершины ну и так для всех сегментов полилинии... В конце - ручка с индексом = кол-во вершин*2 - растяжение конечной точки. Все последующие ручки игнорируются.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #70 : 27-12-2017, 13:46:45 »
Все последующие ручки игнорируются.
Если не переопределять метод MoveGripPointsAt.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Александр Ривилис 24-01-2018, 16:16:16

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #71 : 27-12-2017, 16:34:28 »
Такая таблица вида [указатель на примитив, коллекция  grips] создаётся для каждого GripOverrule. Так что исключение может возникнуть только при повторном вызове AcMgGripOverrule.getGripPoints для того же самого GripOverrule и Entity.
Александр Наумович, Вы натолкнули меня на одну шикарную идею, которую удалось реализовать! В таком виде код не привязывается ни к версии, ни к Civil (смотрите строки 37-51):
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.DatabaseServices;
  2. using Autodesk.AutoCAD.Geometry;
  3. using Autodesk.AutoCAD.GraphicsInterface;
  4. using Autodesk.AutoCAD.Runtime;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Reflection;
  8.  
  9. namespace AcadTest
  10. {
  11.     public class ImplementClass
  12.     {
  13.         [CommandMethod("TestAddGripOverrule")]
  14.         public void AddOverrule()
  15.         {
  16.             Overrule.AddOverrule
  17.                 (RXClass.GetClass(typeof(Line)),
  18.                 LineGripOverrule.Instance, true);
  19.         }        
  20.     }
  21.  
  22.     public class LineGripOverrule: GripOverrule
  23.     {
  24.         static LineGripOverrule m_instance = new LineGripOverrule();
  25.        
  26.         public static LineGripOverrule Instance => m_instance;
  27.  
  28.         LineGripOverrule() { }
  29.  
  30.         public override void GetGripPoints
  31.             (Entity entity, GripDataCollection grips,
  32.             double curViewUnitSize, int gripSize,
  33.             Vector3d curViewDir, GetGripPointsFlags bitFlags)
  34.         {
  35.             if (entity is Line line)
  36.             {
  37.                 PropertyInfo entMapPropInfo =
  38.                     GetType().GetProperty
  39.                     ("EntityMap",
  40.                     BindingFlags.Instance
  41.                     | BindingFlags.NonPublic);
  42.  
  43.                 if (entMapPropInfo != null)
  44.                 {
  45.                     var entityMap = entMapPropInfo.GetValue(this)
  46.                         as Dictionary<IntPtr, List<GripData>>;                    
  47.                     if (entityMap.ContainsKey(line.UnmanagedObject))
  48.                     {
  49.                         entityMap.Remove(line.UnmanagedObject);
  50.                     }
  51.                 }
  52.  
  53.                 Point3d pnt1 = line.StartPoint;
  54.                 MoveGripData grip1 = new MoveGripData(pnt1, PointType.Start);
  55.                 grips.Add(grip1);
  56.  
  57.                 Point3d pnt2 = line.EndPoint;
  58.                 MoveGripData grip2 = new MoveGripData(pnt2, PointType.End);
  59.                 grips.Add(grip2);
  60.             }
  61.         }
  62.  
  63.         public override void MoveGripPointsAt
  64.             (Entity entity, GripDataCollection grips,
  65.             Vector3d offset, MoveGripPointsFlags bitFlags)
  66.         {
  67.             if (entity is Line line)
  68.             {
  69.                 foreach (GripData grip in grips)
  70.                 {
  71.                     if (grip is MoveGripData myGrip)
  72.                     {
  73.                         Point3d newPos3d = myGrip.GripPoint + offset;
  74.                         switch (myGrip.Type)
  75.                         {
  76.                             case PointType.Start:
  77.                                 line.StartPoint = newPos3d;
  78.                                 break;
  79.                             case PointType.End:
  80.                                 line.EndPoint = newPos3d;
  81.                                 break;
  82.                         }
  83.                     }
  84.                 }
  85.             }
  86.         }
  87.     }
  88.  
  89.     public class MoveGripData: GripData
  90.     {
  91.         public PointType Type;
  92.  
  93.         public MoveGripData(Point3d _point, PointType ptType) : base()
  94.         {
  95.             GripPoint = _point;
  96.             Type = ptType;
  97.         }
  98.  
  99.         public override bool ViewportDraw
  100.             (ViewportDraw worldDraw, ObjectId entityId,
  101.             GripData.DrawType type, Point3d? imageGripPoint,
  102.             int gripSizeInPixels)
  103.         {
  104.             // Calculate the size of the glyph in WCS
  105.             Point2d glyphSize = worldDraw.Viewport
  106.                 .GetNumPixelsInUnitSquare(this.GripPoint);
  107.             double glyphHeight = (gripSizeInPixels / glyphSize.Y);
  108.             double glyphWeight = (gripSizeInPixels / glyphSize.X);
  109.  
  110.             Matrix3d mx3d = worldDraw.Viewport.ModelToEyeTransform;
  111.             Point3d pt = this.GripPoint.TransformBy(mx3d);
  112.  
  113.             // Draw a glyph
  114.             Point3dCollection pnts = new Point3dCollection();
  115.  
  116.             // rectangle
  117.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y - glyphHeight, pt.Z));
  118.             pnts.Add(new Point3d(pt.X + glyphWeight, pt.Y - glyphHeight, pt.Z));
  119.             pnts.Add(new Point3d(pt.X + glyphWeight, pt.Y + glyphHeight, pt.Z));
  120.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y + glyphHeight, pt.Z));
  121.             pnts.Add(new Point3d(pt.X - glyphWeight, pt.Y - glyphHeight, pt.Z));
  122.  
  123.             worldDraw.Geometry.PolygonEye(pnts);
  124.  
  125.             return base.ViewportDraw
  126.                 (worldDraw, entityId, type, imageGripPoint, gripSizeInPixels);
  127.         }
  128.     }
  129.  
  130.     public enum PointType
  131.     {
  132.         Start,
  133.         End,
  134.     }
  135. }

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #72 : 27-12-2017, 16:40:48 »
Дмитрий Загорулькин
Очень-очень-очень красивый workaround! Люблю я такие вещи!!!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #73 : 27-12-2017, 16:49:29 »
Да, не говорите! Мне тоже такое решение гораздо больше нравится, чем предыдущее! И главное - практически на поверхности было после Вашего сообщения о причинах сбоя!
Проверил в Civil 3D 2017: условие в 47 строке всегда возвращает false. Похоже, что эту коллекцию какие-то внутренние методы чистят, но почему-то не делают этого в 2018 версии.

Оффлайн Алексей ТерноАвтор темы

  • ADN Club
  • ****
  • Сообщений: 381
  • Карма: 33
    • C3D Extensions
  • Skype: alexeyterno
Re: GripOverrule в C3D
« Ответ #74 : 27-12-2017, 17:01:23 »
Круто!!!

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #75 : 27-12-2017, 17:13:15 »
Единственное, что меня смущает - наверное, надо вызывать Dispose для каждой GripData из удаляемой коллекции?
P.S. Попробовал это сделать - Civil падает при перемещении ручек.
Тогда либо оставлять как есть, и надеяться, что всё будет хорошо, либо 49 строку заменить на
Код - C# [Выбрать]
  1. return;

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: GripOverrule в C3D
« Ответ #76 : 27-12-2017, 20:14:21 »
Сам AutoCAD должен вызывать Dispose. Думаю что нужно понаблюдать за памятью в Диспетчере задач.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #77 : 27-12-2017, 20:38:41 »
Я боюсь, что даже если память не будет освобождаться от данных о ручках, то это всё равно как капля в море. Civil её отхапывает прилично при работе. Думаю, что, действительно AutoCAD сам управляет этими данными, раз попытка вмешаться в этот процесс вызывает его крах. Но у себя в приложении решил перестраховаться и не удалять имеющуюся запись, а просто не выполнять код повторного получения ручек. Что так, что так - разницы в работе нет никакой. Ну или, по крайней мере, пока не замечено  :D

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: GripOverrule в C3D
« Ответ #78 : 18-05-2018, 15:13:04 »
В Civil 3D 2019 этот баг исправили. И стандартные метки Сивила стали нормально ручками редактироваться. А вот в 2018 даже со всеми обновлениями-апдейтами баг остаётся. Похоже, это неизлечимый баг версии.