GripOverrule в C3D

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

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

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

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

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 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 видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение