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

29/06/2017

Как установить ось Z ПСК вдоль линии в .NET

Вопрос: Имеются различные линии в AutoCAD (отрезки, полилинии, сплайны). Как можно установить ось Z текущей ПСК вдоль линии в указанной пользователем точке?

Ответ: Ниже приведён код, который позволяет установить ось Z ПСК вдоль выбранной пользователем линии. В качестве начала координат ПСК выбирается точка на линии, ближайшая к указанной пользователем точке:

Код - C#: [Выделить]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. #pragma warning disable 0618
  9.  
  10. [assembly: CommandClass(typeof(SetUcsWithLine.MyCommands))]
  11.  
  12. namespace SetUcsWithLine
  13. {
  14.   public class MyCommands
  15.   {
  16.     [CommandMethod("SetUcsWithLine")]
  17.     public void SetUcsWithLineFunc()
  18.     {
  19.       Document doc = Application.DocumentManager.MdiActiveDocument;
  20.       if (doc == null) return;
  21.       Editor ed = doc.Editor;
  22.       Database db = doc.Database;
  23.       // Запрашиваем у пользователя линию, вдоль которой будет направлена ось Z ПСК
  24.       PromptEntityOptions peOpts = new PromptEntityOptions("Выберите линию:");
  25.       peOpts.SetRejectMessage("Это не линия");
  26.       peOpts.AddAllowedClass(typeof(Curve), false);
  27.       PromptEntityResult peRs = ed.GetEntity(peOpts);
  28.       if (peRs.Status != PromptStatus.OK) return;
  29.       // Точка начала координат в указанной пользователем точке
  30.       Point3d ptOrig = peRs.PickedPoint.TransformBy(ed.CurrentUserCoordinateSystem);
  31.       Vector3d zAxis = GetTangenVectorOfCurve(peRs.ObjectId, ref ptOrig).GetNormal();
  32.       Vector3d xAxis = zAxis.GetPerpendicularVector().GetNormal();
  33.       Vector3d yAxis = xAxis.RotateBy(Math.PI * 0.5, zAxis);
  34.       Matrix3d mat =
  35.         Matrix3d.AlignCoordinateSystem(Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
  36.                                        ptOrig, xAxis, yAxis, zAxis);
  37.       // Устанавливаем новую ПСК
  38.       ed.CurrentUserCoordinateSystem = mat;
  39.       ed.Regen();
  40.     }
  41.     /// <summary>
  42.     /// Получение вектора вдоль линии, указанной её ObjectId и точкой на линии
  43.     /// Функция уточняет точку на линии, находя ближайшую к ней в проекции взгляда
  44.     /// </summary>
  45.     /// <param name="id"></param>
  46.     /// <param name="pt"></param>
  47.     /// <returns></returns>
  48.     public Vector3d GetTangenVectorOfCurve(ObjectId id, ref Point3d pt)
  49.     {
  50.       Vector3d v = Vector3d.ZAxis;
  51.       Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  52.       using (Curve cv = id.Open(OpenMode.ForRead) as Curve) {
  53.         Vector3d viewDir = ((Point3d)Application.GetSystemVariable("VIEWDIR")).GetAsVector();
  54.         viewDir.TransformBy(ed.CurrentUserCoordinateSystem);
  55.         pt = cv.GetClosestPointTo(pt, viewDir, false);
  56.         v = cv.GetFirstDerivative(pt);
  57.       }
  58.       return v;
  59.     }
  60.   }
  61. }

Автор: Александр Ривилис

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

Опубликовано 29.06.2017