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

24/05/2013

Обеспечение параллельности транзитной графики экрану

Вы можете быть заинтересованы в использовании транзитной графики, которая всегда остаётся параллельной экрану, несмотря на любые изменения вида.

Метод «Editor.PointToWorld» можно использовать для конвертации точки, для которой известны её экранные координаты, чтобы получить её координаты в МСК (WCS). Этот метод можно использовать для вычисления точек в МСК (WCS) для которых известны координаты в ДСК (DCS).

Однако достаточно сложно узнать, когда вид изменится, для того чтобы обновить транзитную графику чтобы она следовала за изменениями вида. Это потому что нет прямого пути с использованием API для того чтобы узнать, параметры вида изменились.

Событие модификации для записи таблицы видовых портов происходит только при изменении видового куба, команд ПАН (PAN), ПОКАЖИ (ZOOM), ТЗРЕНИЯ (VPOINT) и т.д. Панорамирование и зумирование с использованием колеса мыши не вызывает этого события.

В качестве обходного пути можно рассмотреть возможность использования таймера обратного вызова для контроля параметров вида и после изменения параметров вида выполнить перерисовку транзитной графики параллельно экрану (т.е. в ДСК).

Другой способ заключается в использовании события Editor.PointMonitor, но вы не получите уведомление о событии, когда панорамирование / зумирование происходит из командной строки. После того, как курсор мыши находится в редакторе AutoCAD , транзитная графика перерисовывается.

Ниже пример кода, использующий второй путь. Он рисует прямоугольник, который всегда параллелен экрану, при помощи транзитной графики:

Код - C#: [Выделить]
  1. using System.Drawing;
  2. using Autodesk.AutoCAD.GraphicsInterface;
  3.  
  4. public class TestCommands : IExtensionApplication
  5. {
  6.     public static DBObjectCollection _transients = null;
  7.     public double _viewSize = 1.0;
  8.     public Point3d _viewCtr = Point3d.Origin;
  9.     public Point3d _viewDir = Point3d.Origin;
  10.  
  11.     [CommandMethod("DrawTransientRect", CommandFlags.Session)]
  12.     public void DrawTransientRectMethod()
  13.     {
  14.         Document activeDoc
  15.             = Application.DocumentManager.MdiActiveDocument;
  16.         Database db = activeDoc.Database;
  17.         Editor ed = activeDoc.Editor;
  18.  
  19.         // Очищаем предыдущую транзитную графику
  20.         ClearTransientGraphics();
  21.  
  22.         Point2d screenSize
  23.             = (Point2d)Application.GetSystemVariable("SCREENSIZE");
  24.  
  25.         // Ширина и высота прямоугольника
  26.         int width = 20;
  27.         int height = 60;
  28.  
  29.         // Четыре угловые тоски в экранных координатах
  30.         System.Drawing.Point upperLeft
  31.                             = new System.Drawing.Point(20, 20);
  32.  
  33.         System.Drawing.Point upperRight
  34.             = new System.Drawing.Point(upperLeft.X + width, upperLeft.Y);
  35.  
  36.         System.Drawing.Point lowerLeft
  37.             = new System.Drawing.Point(upperLeft.X, upperLeft.Y + height);
  38.  
  39.         System.Drawing.Point lowerRight
  40.             = new System.Drawing.Point(upperLeft.X + width, upperLeft.Y + height);
  41.  
  42.         // Четыре угловые точки в МСК (WCS)
  43.         Point3d upperLeftWorld = ed.PointToWorld(upperLeft, 0);
  44.         Point3d upperRightWorld = ed.PointToWorld(upperRight, 0);
  45.         Point3d lowerLeftWorld = ed.PointToWorld(lowerLeft, 0);
  46.         Point3d lowerRightWorld = ed.PointToWorld(lowerRight, 0);
  47.  
  48.         // Создаём транзитную графику
  49.         Line l1 = new Line(upperLeftWorld, upperRightWorld);
  50.         l1.ColorIndex = 2;
  51.         Line l2 = new Line(upperRightWorld, lowerRightWorld);
  52.         l2.ColorIndex = 2;
  53.         Line l3 = new Line(lowerRightWorld, lowerLeftWorld);
  54.         l3.ColorIndex = 2;
  55.         Line l4 = new Line(lowerLeftWorld, upperLeftWorld);
  56.         l4.ColorIndex = 2;
  57.  
  58.         _transients.Add(l1);
  59.         _transients.Add(l2);
  60.         _transients.Add(l3);
  61.         _transients.Add(l4);
  62.  
  63.         IntegerCollection intCol = new IntegerCollection();
  64.         TransientManager tm = TransientManager.CurrentTransientManager;
  65.         tm.AddTransient
  66.             (
  67.                 l1,
  68.                 TransientDrawingMode.Main,
  69.                 128,
  70.                 intCol
  71.             );
  72.  
  73.         tm.AddTransient
  74.             (
  75.                 l2,
  76.                 TransientDrawingMode.Main,
  77.                 128,
  78.                 intCol
  79.             );
  80.  
  81.         tm.AddTransient
  82.             (
  83.                 l3,
  84.                 TransientDrawingMode.Main,
  85.                 128,
  86.                 intCol
  87.             );
  88.  
  89.         tm.AddTransient
  90.             (
  91.                 l4,
  92.                 TransientDrawingMode.Main,
  93.                 128,
  94.                 intCol
  95.             );
  96.     }
  97.  
  98.     // Очищаем всю транзитную графику
  99.     void ClearTransientGraphics()
  100.     {
  101.         TransientManager tm
  102.                 = TransientManager.CurrentTransientManager;
  103.         IntegerCollection intCol = new IntegerCollection();
  104.         if (_transients != null)
  105.         {
  106.             foreach (DBObject transient in _transients)
  107.             {
  108.                 tm.EraseTransient(
  109.                                     transient,
  110.                                     intCol
  111.                                     );
  112.                 transient.Dispose();
  113.             }
  114.             _transients.Clear();
  115.         }
  116.         else
  117.             _transients = new DBObjectCollection();
  118.     }
  119.  
  120.     #region IExtensionApplication Members
  121.  
  122.     void IExtensionApplication.Initialize()
  123.     {
  124.         Document activeDoc
  125.             = Application.DocumentManager.MdiActiveDocument;
  126.         Editor ed = activeDoc.Editor;
  127.  
  128.         // Подписываемся на событие PointMonitor чтобы перерисовывать
  129.         // транзитную графику в случае любых изменений вида.
  130.         ed.PointMonitor +=
  131.                 new PointMonitorEventHandler(ed_PointMonitor);
  132.     }
  133.  
  134.     void ed_PointMonitor(object sender, PointMonitorEventArgs e)
  135.     {
  136.         Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  137.         double viewSize
  138.             = (double)Application.GetSystemVariable("VIEWSIZE");
  139.  
  140.         Point3d viewCtr
  141.             = (Point3d)Application.GetSystemVariable("VIEWCTR");
  142.  
  143.         Point3d viewDir
  144.             = (Point3d)Application.GetSystemVariable("VIEWDIR");
  145.  
  146.         // Просто проверим не изменились ли параметры вида с момента
  147.         // последней отрисовки транзитной графики
  148.         if (    viewSize != _viewSize ||
  149.                 viewCtr.Equals(_viewCtr) == false ||
  150.                 viewDir.Equals(_viewDir) == false
  151.             )
  152.         {
  153.             _viewSize = viewSize;
  154.  
  155.             _viewCtr
  156.                 = (Point3d)Application.GetSystemVariable("VIEWCTR");
  157.  
  158.             _viewDir = viewDir;
  159.  
  160.             // Перерисовываем транзитную графику если
  161.             // параметры вида изменились
  162.             DrawTransientRectMethod();
  163.         }
  164.     }
  165.  
  166.     void IExtensionApplication.Terminate()
  167.     {
  168.         Document activeDoc
  169.             = Application.DocumentManager.MdiActiveDocument;
  170.         if (activeDoc != null)
  171.         {
  172.             // Отписываемся от события
  173.             Editor ed = activeDoc.Editor;
  174.             ed.PointMonitor -=
  175.                 new PointMonitorEventHandler(ed_PointMonitor);
  176.         }
  177.  
  178.         // Очищаем перед выходом
  179.         ClearTransientGraphics();
  180.     }
  181.  
  182.     #endregion
  183. }

 

Источник: http://adndevblog.typepad.com/autocad/2012/12/retaining-transient-graphics-always-parallel-to-the-screen.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=47.0

Автор перевода: Александр Ривилис
Опубликовано 24.05.2013
Отредактировано 14.04.2015 в 00:41:03