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

30/05/2013

Преобразование координат точки из пространства Листа в пространство Модели средствами AutoCAD .NET API

Недавно я попытался найти какую-нибудь информацию о том, как преобразовать координаты точки из пространства Листа в пространство Модели и был шокирован тем, что нет простого кода для этого!!! Возможно, я упустил что-то очевидное, тем не менее, я решил создать свой собственный код и поделиться им с вами.

Следующий код использует функцию acedTrans()  (которую мы могли использовать еще во времена ADS версии R11) с использованием PInvoke. Её очень просто использовать, если вы знаете как.

Для запуска и тестирования кода:

  1. Запустите AutoCAD и загрузите следующий код
  2. Переключитесь в пространство листа (щелкните по вкладке Лист или установите TILEMODE в 0)
  3. Создайте Видовой Экран
  4. Убедитесь, что по-прежнему TILEMODE равна 0
  5. Запустите команду ps2ms и укажите мышью точку где-нибудь в Видовом Экране. Вы увидите что Точка (DBPoint) появится точно под курсором, но в пространстве Модели.
  6. Если вы не видите Точку, просто установите системные переменные PDSIZE=10 и PDMODE=98

Надеюсь, вам понравится.

Код - C#: [Выделить]
  1.  
  2.     // конвертация точки из пространства Листа (PS)
  3.     // в пространство Модели (MS) и
  4.     // затем добавление DBPoint в пространство
  5.     // Модели чтобы показать указанную точку
  6.     // Автор: Fenton Webb, DevTech,
  7.     // Autodesk, 20/Aug/2012
  8. #if NOTACAD2013
  9.   [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint="acedTrans")]
  10. #else
  11.     [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
  12. #endif
  13.     static extern int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
  14.     [CommandMethod("ps2ms", CommandFlags.NoTileMode)]
  15.     static public void ps2ms()
  16.     {
  17.       Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  18.       // Указываем точку в пространстве Листа
  19.       PromptPointResult res = ed.GetPoint("Укажите точку для пространства Модели ");
  20.       if (res.Status == PromptStatus.OK)
  21.       {
  22.         // теперь убедимся, что это будет работать для всех точек зрения
  23.         ResultBuffer psdcs = new ResultBuffer(new TypedValue(5003, 3));
  24.         ResultBuffer dcs = new ResultBuffer(new TypedValue(5003, 2));
  25.         ResultBuffer wcs = new ResultBuffer(new TypedValue(5003, 0));
  26.         double[] retPoint = new double[] { 0, 0, 0 };
  27.  
  28.         // преобразуем из DCS пространства Листа (PSDCS) RTSHORT=3 в
  29.         // DCS текущего Видового Экрана пространства Модели RTSHORT=2
  30.         acedTrans(retPoint, psdcs.UnmanagedObject, dcs.UnmanagedObject, 0, retPoint);
  31.         // DCS текущего Видового Экрана пространства Модели RTSHORT=2
  32.         // в WCS RTSHORT=0
  33.         acedTrans(retPoint, dcs.UnmanagedObject, wcs.UnmanagedObject, 0, retPoint);
  34.  
  35.         ObjectId btId = ed.Document.Database.BlockTableId;
  36.         // создаём новую Точку (DBPoint) и добавляем её к пространству Модели to show where we        
  37.         // чтобы увидеть где указали
  38.         using (DBPoint pnt = new DBPoint(new Point3d(retPoint[0], retPoint[1], retPoint[2])))
  39.         using (BlockTable bt = btId.Open(OpenMode.ForRead) as BlockTable)
  40.         using (BlockTableRecord ms = bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite)
  41.                         as BlockTableRecord)
  42.           ms.AppendEntity(pnt);
  43.       }
  44.     }
  45.  

 

Примечание переводчика: Есть лучший вариант кода от Gilles Chanteau:

Код - C#: [Выделить]
  1. [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
  2. static extern int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
  3. [CommandMethod("ps2ms", CommandFlags.NoTileMode)]
  4. static public void ps2ms()
  5. {
  6.    Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  7.    // Указываем точку в пространстве Листа
  8.    PromptPointResult res = ed.GetPoint("Укажите точку в пространстве Модели");
  9.    if (res.Status == PromptStatus.OK)
  10.    {
  11.        // Преобразование точки из PS в MS
  12.        ResultBuffer rbPSDCS = new ResultBuffer(new TypedValue(5003, 3));
  13.        ResultBuffer rbDCS = new ResultBuffer(new TypedValue(5003, 2));
  14.        ResultBuffer rbWCS = new ResultBuffer(new TypedValue(5003, 0));
  15.        double[] retPoint = new double[] { 0, 0, 0 };
  16.        ed.SwitchToModelSpace(); // Переключаемся в пространство модели
  17.        using (Viewport vp = (Viewport)ed.CurrentViewportObjectId.Open(OpenMode.ForRead))
  18.        {
  19.            // преобразуем из DCS пространства Листа (PSDCS) RTSHORT=3
  20.            // в DCS пространства Модели текущего Видового Экрана RTSHORT=2
  21.            acedTrans(res.Value.ToArray(),
  22.                                                rbPSDCS.UnmanagedObject, rbDCS.UnmanagedObject, 0, retPoint);
  23.            // Преобразуем из DCS пространства Модели текущего Видового Экрана RTSHORT=2
  24.            // в WCS RTSHORT=0
  25.            acedTrans(retPoint,
  26.                                                rbDCS.UnmanagedObject, rbWCS.UnmanagedObject, 0, retPoint);
  27.        }
  28.        ed.SwitchToPaperSpace(); // Возвращаемся в пространство Листа
  29.  
  30.        // Создаём Точку (DBPoint) и добавляем её в пространство Модели
  31.        // чтобы видеть где указан точка
  32.        using (DBPoint pnt = new DBPoint(new Point3d(retPoint[0], retPoint[1], retPoint[2])))
  33.        using (BlockTable bt = ed.Document.Database.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
  34.        using (BlockTableRecord ms = bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite) as BlockTableRecord)
  35.            ms.AppendEntity(pnt);
  36.    }
  37. }
  38.  

 

Источник: http://adndevblog.typepad.com/autocad/2012/03/converting-paper-space-point-to-model-space-using-autocadnet.html

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

Опубликовано 30.05.2013
Отредактировано 04.07.2013 в 02:03:42