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

07/11/2016

Как получить 3D-полилинию, по которой получается тело сдвига

Вопрос: Имеется труба - твердое тело, полученной сдвигом круга (Circle) по траектории, образованной 3D-полилинией (3DPoly). Как получить вершины 3D-полилинии?

Ответ: Вариантов решения этой задачи несколько:

1)    Использование метода GetGripPoints. Для тела у которого не очищена история редактирования если пропустить первые четыре ручки, то мы получим вершины 3D-полилинии. Но если история очищена, то получить вершины таким образом не получится, так как расположение ручек совсем другое:

2)    Использовать BREP .NET API для получения информации о вершинах.

Второй вариант мы и рассмотрим, так как он более универсальный. Нам следует получить все ребра (Edge) твердого тела, выделить из них круглые (CircularArc3d) и эллиптические (EllipticalArc3d) и найти их центры.

Вот пример кода:

Код - 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. using Autodesk.AutoCAD.BoundaryRepresentation;
  8.  
  9. [assembly: CommandClass(typeof(GetSweepAxis.MyCommands))]
  10.  
  11. namespace GetSweepAxis
  12. {
  13.  
  14.   public class MyCommands
  15.   {
  16.  
  17.     [CommandMethod("FindSweepAxis")]
  18.     public void FindCylinderAxis()
  19.     {
  20.       Document doc = Application.DocumentManager.MdiActiveDocument;
  21.       Editor ed = doc.Editor;
  22.       PromptEntityOptions peo =
  23.           new PromptEntityOptions("\nУкажите твердое тело: ");
  24.       peo.SetRejectMessage("\nЭто не твердое тело.");
  25.       peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Solid3d), true);
  26.       PromptEntityResult per = ed.GetEntity(peo);
  27.       if (per.Status != PromptStatus.OK)
  28.         return;
  29.  
  30.       using (Transaction tr =
  31.              doc.Database.TransactionManager.StartTransaction())
  32.       {
  33.         Solid3d sld =
  34.              tr.GetObject(per.ObjectId, OpenMode.ForRead, false) as Solid3d;
  35.         Point3dCollection pts = new Point3dCollection();
  36.         if (GetCylinderAxis(sld, ref  pts))
  37.         {
  38.           for (int i = 0; i < pts.Count; i++)
  39.           {
  40.             ed.WriteMessage("\nВершина N{0} = {1}", i, pts[i]);
  41.           }
  42.         }
  43.         else
  44.         {
  45.           ed.WriteMessage("\nЭто не твердое тело сдвига!");
  46.         }
  47.         tr.Commit();
  48.       }
  49.     }
  50.  
  51.     private bool GetCylinderAxis(Solid3d solid, ref Point3dCollection pts)
  52.     {
  53.       using (Brep brep = new Brep(solid))
  54.       {
  55.         BrepEdgeCollection edges = brep.Edges;
  56.         foreach (Edge edge in edges)
  57.         {
  58.           Curve3d curv = ((ExternalCurve3d)edge.Curve).NativeCurve;
  59.           if (curv is CircularArc3d)
  60.           {
  61.             CircularArc3d circle = curv as CircularArc3d;
  62.             if (!pts.Contains(circle.Center)) pts.Add(circle.Center);
  63.           }
  64.           else if (curv is EllipticalArc3d)
  65.           {
  66.             EllipticalArc3d circle = curv as EllipticalArc3d;
  67.             if (!pts.Contains(circle.Center)) pts.Add(circle.Center);
  68.           }
  69.         }
  70.       }
  71.       return (pts.Count > 1) ? true : false;
  72.     }
  73.   }
  74. }

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

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

Опубликовано 07.11.2016
Отредактировано 07.11.2016 в 02:02:50