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

ADN Club => AutoCAD .NET API => Тема начата: Вильдар от 10-11-2018, 19:03:20

Название: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 19:03:20
Привет,
Хочу учесть текущий вид при создании объекта.
Чтобы результат получился как "видится на экране".
Но, получается перевернуто на 180 грудусов. Файл во вложении.
Код - C# [Выбрать]
  1.         [CommandMethod(nameof(TestUcs), CommandFlags.Modal)]
  2.         public void TestUcs()
  3.         {
  4.             var doc = Application.DocumentManager.MdiActiveDocument;
  5.             var db = doc.Database;
  6.             using (var t = doc.TransactionManager.StartTransaction())
  7.             {
  8.                 var ucs = doc.Editor.CurrentUserCoordinateSystem;
  9.                 var ms = (BlockTableRecord)db.CurrentSpaceId.GetObject(OpenMode.ForWrite);
  10.                 var pt = doc.Editor.GetPoint("Точка").Value;
  11.                 var pt2 = pt + new Vector3d(3, 6, 0);
  12.                 var line = new Line(pt, pt2);
  13.                 line.TransformBy(ucs);
  14.                 ms.AppendEntity(line);
  15.                 t.AddNewlyCreatedDBObject(line, true);
  16.                 t.Commit();
  17.             }
  18.         }
Получается так (красная линия - как должно быть):
(https://i.postimg.cc/PLr2g9fH/ucs.jpg) (https://postimg.cc/PLr2g9fH)
Название: Re: Необычная UCS
Отправлено: Александр Пекшев aka Modis от 10-11-2018, 19:07:40
Ты получаешь точки в мировой системе координат, создаешь по ним отрезок, а затем его трансформируешь по ПСК. Разве тут есть что-то неожиданное в том, что отрезок повернут? ))
Название: Re: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 19:10:39
А как нужно сделать?
Название: Re: Необычная UCS
Отправлено: Александр Пекшев aka Modis от 10-11-2018, 19:13:50
А как нужно сделать?
При запросе точек через Editor.GetPoint() вроде как система координат не учитывается и точка возвращается с МСК. А значит, тебе ничего и не нужно трансформировать

Хотя, я до их пор не могу понять сути вопроса...
Название: Re: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 19:18:11
Если убрать строку трансформации отрезка, то в результате отрезок в космосе (улетает далеко).
Если трансформировать точку запроса, то получается так (должно быть как красная линия)
(https://i.postimg.cc/GHSqYqbh/ucs2.jpg) (https://postimg.cc/GHSqYqbh)
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 19:18:22
Но, получается перевернуто на 180 грудусов. Файл во вложении.
А ты смотрел, куда у тебя оси этой UCS направлены?
(https://lh3.googleusercontent.com/-rKWRuE4vYYk/W-cEtIWcDNI/AAAAAAAAPPs/QfdgY2ggMoQQtj-Nkk5etF3olrAIssQegCHMYCw/s0/clipboard.png)


Ты учитываешь UCS а не вид.
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 19:19:38
Если трансформировать точку запроса, то получается так (должно быть как красная линия)
Не должно быть. У тебя UCS не по виду. По виду это так:
(https://lh3.googleusercontent.com/-z_uUG6QkQ0k/W-cFB5r8FDI/AAAAAAAAPP0/rCxCWe-N-zwSH-WvUI9q5CG0etjZlVW7ACHMYCw/s0/clipboard2.png)

Название: Re: Необычная UCS
Отправлено: Александр Пекшев aka Modis от 10-11-2018, 19:19:52
Если трансформировать точку запроса, то получается так (должно быть как красная линия)
А если трансформировать не точку запроса, а точку pt2 как раз?
Название: Re: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 19:20:03
Ты учитываешь UCS а не вид.
О, это наверно то! А как учесть вид?
Не знаю, что сделано в файле.
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 19:20:54
При запросе точек через Editor.GetPoint() вроде как система координат не учитывается и точка возвращается с МСК.
Шутишь??? Точки возвращаются в ПСК (UCS), а не в МСК (WCS).
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 19:22:59
О, это наверно то! А как учесть вид?
Не знаю, что сделано в файле.
Если командными методами, то можно переключить UCS:
_UCS _View
Название: Re: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 19:26:33
А не командными можно?
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 19:32:33
А не командными можно?
А не командными ты должен понять что хочешь делать.
Название: Re: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 19:38:21
Нарисовать как видится на экране.
Если взять текущий вид
ViewTableRecord view = doc.Editor.GetCurrentView();
То отличается оно одним свойством CoordinateSystem3d Ucs:
Ucs = {CoordinateSystem3d} "((173.12573185366,173.920538721765,0),(0.675993720675631,0.736907381973554,0),(-0.736907381973554,0.675993720675631,0),(0,0,1))"
Ucs = {CoordinateSystem3d} "((173.12573185366,173.920538721765,0),(0.675993720675631,0.736907381973554,0),(0.736907381973554,-0.675993720675631,0),(0,0,-1))"
Название: Re: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 20:13:49
_UCS _View
А эта команда в интерфейсе есть?

Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 20:17:07
_UCS _View
А эта команда в интерфейсе есть?


В каком интерфейсе? Вбей в командную строку и посмотри результат.
Название: Re: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 20:52:05
Через ком. строку понятно.
Что-то в интерфейсе не нашел соответствия.
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 21:01:02
Через ком. строку понятно.
Что-то в интерфейсе не нашел соответствия.
А зачем это тебе?
Название: Re: Необычная UCS
Отправлено: Вильдар от 10-11-2018, 21:04:58
Для пользователей.
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 21:05:49
Для пользователей.
Ну создай им кнопку.
Название: Re: Необычная UCS
Отправлено: Дмитрий Загорулькин от 10-11-2018, 21:44:00
Тут надо переводить координаты точек грамотно. Ниже - пример того, как это будет работать. Здесь используется P/Invoke для вызова метода трансформации координат точек. Вроде как, можно то же самое сделать и на чистом .NET.
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.Geometry;
  4. using Autodesk.AutoCAD.Runtime;
  5. using System;
  6. using System.Runtime.InteropServices;
  7.  
  8. namespace AcadTest
  9. {
  10.     public class UCSTest
  11.     {
  12.         [CommandMethod(nameof(TestUcs), CommandFlags.Modal)]
  13.         public void TestUcs()
  14.         {
  15.             var doc = Application.DocumentManager.MdiActiveDocument;
  16.             var db = doc.Database;
  17.             using (var t = doc.TransactionManager.StartTransaction())
  18.             {
  19.                 var ucs = doc.Editor.CurrentUserCoordinateSystem;
  20.                 var ms = (BlockTableRecord)db.CurrentSpaceId.GetObject(OpenMode.ForWrite);
  21.                 var ptUcs = doc.Editor.GetPoint("Точка").Value;
  22.                 var ptWcs = ptUcs.TransformCS(UCSType.UCS, UCSType.WCS);
  23.                 var ptDcs = ptWcs.TransformCS(UCSType.WCS, UCSType.DCS);
  24.                 var pt2Dcs = ptDcs + new Vector3d(3, 6, 0);
  25.                 var pt2Wcs = pt2Dcs.TransformCS(UCSType.DCS, UCSType.WCS);
  26.                 var line = new Line(ptWcs, pt2Wcs);                
  27.                 ms.AppendEntity(line);
  28.                 t.AddNewlyCreatedDBObject(line, true);
  29.                 t.Commit();
  30.             }
  31.         }        
  32.     }
  33.  
  34.     static class UCSSupport
  35.     {
  36.         /// <summary>
  37.         /// Перевод координат точки из одной системы в другую
  38.         /// </summary>
  39.         /// <param name="point">Точка</param>
  40.         /// <param name="from">Система координат "из"</param>
  41.         /// <param name="to">Система координат "в"</param>
  42.         /// <returns>Точка с координатами в нужной СК</returns>
  43.         public static Point3d TransformCS(this Point3d point, UCSType from, UCSType to)
  44.         {
  45.             using (ResultBuffer resBufFrom = new ResultBuffer(new TypedValue(5003, from)))
  46.             using (ResultBuffer resBufTo = new ResultBuffer(new TypedValue(5003, to)))
  47.             {
  48.                 double[]
  49.                     coords = point.ToArray(),
  50.                     retVal = new double[3];
  51.                 AcedTrans
  52.                     (coords, resBufFrom.UnmanagedObject,
  53.                     resBufTo.UnmanagedObject, 0, retVal);
  54.                 return new Point3d(retVal);
  55.             }
  56.         }
  57.  
  58.         /// <summary>
  59.         /// http://adndevblog.typepad.com/autocad/2013/page/41/
  60.         /// </summary>
  61.         /// <param name="point">Точки на листе</param>
  62.         /// <param name="fromRb">Система координат "ИЗ"</param>
  63.         /// <param name="toRb">Система координат "В"</param>
  64.         /// <param name="disp"></param>
  65.         /// <param name="result"></param>
  66.         /// <returns></returns>
  67.         [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
  68.         public static extern int AcedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
  69.     }
  70.  
  71.  
  72.     /// <summary>
  73.     /// Тип координатной системы
  74.     /// </summary>
  75.     public enum UCSType
  76.     {
  77.         /// <summary>
  78.         /// Мировая
  79.         /// </summary>
  80.         WCS = 0,
  81.         /// <summary>
  82.         /// Пользовательская
  83.         /// </summary>
  84.         UCS = 1,
  85.         /// <summary>
  86.         /// Экрана
  87.         /// </summary>
  88.         DCS = 2,
  89.         /// <summary>
  90.         /// Экрана пространства листа
  91.         /// </summary>
  92.         PSDCS = 3,
  93.     }
  94. }
  95.  
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 23:28:19
Вроде как, можно то же самое сделать и на чистом .NET.
Можно, хотя и не так просто. А можно используя ActiveX/COM модель: Autodesk.AutoCAD.Interop.IAcadUtility.TranslateCoordinates
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 10-11-2018, 23:54:22
Можно, хотя и не так просто.
Всё-таки не сложно:
Код - C# [Выбрать]
  1. [CommandMethod(nameof(TestUcs), CommandFlags.Modal)]
  2. public void TestUcs()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   Database db = doc.Database;
  6.   using (Transaction t = doc.TransactionManager.StartTransaction())
  7.   {
  8.     Matrix3d UCS2WCS = doc.Editor.CurrentUserCoordinateSystem;
  9.     Matrix3d WCS2DCS = GetWCS2DCS(doc.Editor);
  10.     Point3d pt = doc.Editor.GetPoint("Точка").Value;
  11.     pt = pt.TransformBy(UCS2WCS); pt = pt.TransformBy(WCS2DCS);
  12.     Point3d pt2 = pt + new Vector3d(3, 6, 0);
  13.     pt =  pt.TransformBy(WCS2DCS.Inverse()); pt2 = pt2.TransformBy(WCS2DCS.Inverse());
  14.     Line line = new Line(pt, pt2);
  15.     BlockTableRecord ms = (BlockTableRecord)db.CurrentSpaceId.GetObject(OpenMode.ForWrite);
  16.     ms.AppendEntity(line);
  17.     t.AddNewlyCreatedDBObject(line, true);
  18.     t.Commit();
  19.   }
  20. }
  21. public static Matrix3d GetWCS2DCS(Editor ed)
  22. {
  23.   using (ViewTableRecord vtr = ed.GetCurrentView())
  24.   {
  25.     Matrix3d mat = Matrix3d.PlaneToWorld(vtr.ViewDirection);
  26.     mat = Matrix3d.Displacement(vtr.Target - Point3d.Origin) * mat;
  27.     mat = Matrix3d.Rotation(-vtr.ViewTwist, vtr.ViewDirection, vtr.Target) * mat;
  28.     return mat.Inverse();
  29.   }
  30. }
Название: Re: Необычная UCS
Отправлено: Дмитрий Загорулькин от 11-11-2018, 00:56:46
Вот-вот, как-то так, да  :D
Насколько я помню, в .NET вроде как нет инструмента для перевода в PSDCS и обратно. Поэтому и использовался метод из ObjectARX. А в остальных случаях можно обойтись инструментами .NET
Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 11-11-2018, 01:26:49
Насколько я помню, в .NET вроде как нет инструмента для перевода в PSDCS и обратно
Есть. Тут от Gilles Chanteau набор функций преобразования координат: https://forums.autodesk.com/t5/net/get-the-displaying-coordinates-of-a-viewport-object/td-p/6048418
А тут еще больше: https://www.theswamp.org/index.php?topic=31865.msg373672#msg373672
Название: Re: Необычная UCS
Отправлено: Вильдар от 11-11-2018, 11:41:00
Всё-таки не сложно:
Да, получается то что нужно.
А нельзя как-то вывести одну матрицу применимую к примитиву, из мировой в мировую, но с учетом вида  :o
Т.е. все манипуляции с точками делать в мировой, а потом объект трасформировать.

Название: Re: Необычная UCS
Отправлено: Александр Ривилис от 11-11-2018, 13:21:05
А нельзя как-то вывести одну матрицу применимую к примитиву, из мировой в мировую, но с учетом вида 
Ну и как ты себе это представляешь, если требуется трансформация UCS->WCS->DCS (здесь дополнительные математические операции с координатами в виде)->WCS?
Название: Re: Необычная UCS
Отправлено: Дмитрий Загорулькин от 12-11-2018, 12:16:13
Есть. Тут от Gilles Chanteau набор функций преобразования координат: https://forums.autodesk.com/t5/net/get-the-displaying-coordinates-of-a-viewport-object/td-p/6048418
А тут еще больше: https://www.theswamp.org/index.php?topic=31865.msg373672#msg373672
Вот это клад Вы раскопали! Спасибо!