30/05/2013
Преобразование координат точки из пространства Листа в пространство Модели средствами AutoCAD .NET API
Недавно я попытался найти какую-нибудь информацию о том, как преобразовать координаты точки из пространства Листа в пространство Модели и был шокирован тем, что нет простого кода для этого!!! Возможно, я упустил что-то очевидное, тем не менее, я решил создать свой собственный код и поделиться им с вами.
Следующий код использует функцию acedTrans() (которую мы могли использовать еще во времена ADS версии R11) с использованием PInvoke. Её очень просто использовать, если вы знаете как.
Для запуска и тестирования кода:
- Запустите AutoCAD и загрузите следующий код
- Переключитесь в пространство листа (щелкните по вкладке Лист или установите TILEMODE в 0)
- Создайте Видовой Экран
- Убедитесь, что по-прежнему TILEMODE равна 0
- Запустите команду ps2ms и укажите мышью точку где-нибудь в Видовом Экране. Вы увидите что Точка (DBPoint) появится точно под курсором, но в пространстве Модели.
- Если вы не видите Точку, просто установите системные переменные PDSIZE=10 и PDMODE=98
Надеюсь, вам понравится.
Код - C#: [Выделить]
- // конвертация точки из пространства Листа (PS)
- // в пространство Модели (MS) и
- // затем добавление DBPoint в пространство
- // Модели чтобы показать указанную точку
- // Автор: Fenton Webb, DevTech,
- // Autodesk, 20/Aug/2012
- #if NOTACAD2013
- [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint="acedTrans")]
- #else
- [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
- #endif
- static extern int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
- [CommandMethod("ps2ms", CommandFlags.NoTileMode)]
- static public void ps2ms()
- {
- Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
- // Указываем точку в пространстве Листа
- PromptPointResult res = ed.GetPoint("Укажите точку для пространства Модели ");
- if (res.Status == PromptStatus.OK)
- {
- // теперь убедимся, что это будет работать для всех точек зрения
- ResultBuffer psdcs = new ResultBuffer(new TypedValue(5003, 3));
- ResultBuffer dcs = new ResultBuffer(new TypedValue(5003, 2));
- ResultBuffer wcs = new ResultBuffer(new TypedValue(5003, 0));
- double[] retPoint = new double[] { 0, 0, 0 };
- // преобразуем из DCS пространства Листа (PSDCS) RTSHORT=3 в
- // DCS текущего Видового Экрана пространства Модели RTSHORT=2
- acedTrans(retPoint, psdcs.UnmanagedObject, dcs.UnmanagedObject, 0, retPoint);
- // DCS текущего Видового Экрана пространства Модели RTSHORT=2
- // в WCS RTSHORT=0
- acedTrans(retPoint, dcs.UnmanagedObject, wcs.UnmanagedObject, 0, retPoint);
- ObjectId btId = ed.Document.Database.BlockTableId;
- // создаём новую Точку (DBPoint) и добавляем её к пространству Модели to show where we
- // чтобы увидеть где указали
- using (DBPoint pnt = new DBPoint(new Point3d(retPoint[0], retPoint[1], retPoint[2])))
- using (BlockTable bt = btId.Open(OpenMode.ForRead) as BlockTable)
- using (BlockTableRecord ms = bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite)
- as BlockTableRecord)
- ms.AppendEntity(pnt);
- }
- }
Примечание переводчика: Есть лучший вариант кода от Gilles Chanteau:
Код - C#: [Выделить]
- [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
- static extern int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
- [CommandMethod("ps2ms", CommandFlags.NoTileMode)]
- static public void ps2ms()
- {
- Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
- // Указываем точку в пространстве Листа
- PromptPointResult res = ed.GetPoint("Укажите точку в пространстве Модели");
- if (res.Status == PromptStatus.OK)
- {
- // Преобразование точки из PS в MS
- ResultBuffer rbPSDCS = new ResultBuffer(new TypedValue(5003, 3));
- ResultBuffer rbDCS = new ResultBuffer(new TypedValue(5003, 2));
- ResultBuffer rbWCS = new ResultBuffer(new TypedValue(5003, 0));
- double[] retPoint = new double[] { 0, 0, 0 };
- ed.SwitchToModelSpace(); // Переключаемся в пространство модели
- using (Viewport vp = (Viewport)ed.CurrentViewportObjectId.Open(OpenMode.ForRead))
- {
- // преобразуем из DCS пространства Листа (PSDCS) RTSHORT=3
- // в DCS пространства Модели текущего Видового Экрана RTSHORT=2
- acedTrans(res.Value.ToArray(),
- rbPSDCS.UnmanagedObject, rbDCS.UnmanagedObject, 0, retPoint);
- // Преобразуем из DCS пространства Модели текущего Видового Экрана RTSHORT=2
- // в WCS RTSHORT=0
- acedTrans(retPoint,
- rbDCS.UnmanagedObject, rbWCS.UnmanagedObject, 0, retPoint);
- }
- ed.SwitchToPaperSpace(); // Возвращаемся в пространство Листа
- // Создаём Точку (DBPoint) и добавляем её в пространство Модели
- // чтобы видеть где указан точка
- using (DBPoint pnt = new DBPoint(new Point3d(retPoint[0], retPoint[1], retPoint[2])))
- using (BlockTable bt = ed.Document.Database.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
- using (BlockTableRecord ms = bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite) as BlockTableRecord)
- ms.AppendEntity(pnt);
- }
- }
Обсуждение: http://adn-cis.org/forum/index.php?topic=74.0
Опубликовано 30.05.2013
Отредактировано 04.07.2013 в 02:03:42
Отредактировано 04.07.2013 в 02:03:42