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

22/09/2015

Нахождение конечных точек оси цилиндрического твердого тела

В недавнем запросе от разработчика потребовалось найти конечные точки оси цилиндрического твердого тела. Для этого требуется найти круглые ребра тела и найти их центры. Я вспомнил про элегантный образец кода Gilles Chanteau на форуме, который использует Linq запрос к BRep API здесь. Мы немного изменим его код чтобы получить концы осей цилиндра. Вот немного модифицированный код и благодарности Gilles.

Код - C#: [Выделить]
  1. [CommandMethod("FindCylinderAxis")]
  2.  public  void  FindCylinderAxis()
  3.  {
  4.      Document doc
  5.      = Application.DocumentManager.MdiActiveDocument;
  6.      Editor ed = doc.Editor;
  7.  
  8.      PromptEntityOptions peo
  9.      = new  PromptEntityOptions("Укажите цилиндр: " );
  10.      peo.SetRejectMessage
  11.      ("\nНеобходимо указать твердое тело - цилиндр." );
  12.      peo.AddAllowedClass(
  13.      typeof (Autodesk.AutoCAD.DatabaseServices.Solid3d), true );
  14.      PromptEntityResult per = ed.GetEntity(peo);
  15.      if  (per.Status != PromptStatus.OK)
  16.          return ;
  17.  
  18.      using  (Transaction tr
  19.      = doc.Database.TransactionManager.StartTransaction())
  20.      {
  21.          Solid3d sld = tr.GetObject(
  22.          per.ObjectId, OpenMode.ForRead, false ) as  Solid3d;
  23.          Point3d axisPt1 = Point3d.Origin;
  24.          Point3d axisPt2 = Point3d.Origin;
  25.          if  (GetCylinderAxis(sld, ref  axisPt1, ref  axisPt2))
  26.          {
  27.              ed.WriteMessage(String.Format("{0}Точки оси : {1} {2}" ,
  28.              Environment.NewLine,
  29.              axisPt1.ToString(), axisPt2.ToString()));
  30.          }
  31.          else
  32.              ed.WriteMessage(String.Format("{0} Это не цилиндр." ,
  33.              Environment.NewLine));
  34.  
  35.          tr.Commit();
  36.      }
  37.  }
  38.  
  39.  private  bool  GetCylinderAxis(
  40.      Solid3d solid, ref  Point3d axisPt1, ref  Point3d axisPt2)
  41.  {
  42.      bool  isCylinder = false ;
  43.      axisPt1 = Point3d.Origin;
  44.      axisPt2 = Point3d.Origin;
  45.      using  (Brep brep = new  Brep(solid))
  46.      {
  47.          if  (brep.Complexes.Count() != 1)
  48.              return  false ;
  49.          if  (brep.Faces.Count() != 3)
  50.              return  false ;
  51.          BrepEdgeCollection edges = brep.Edges;
  52.          if  (edges.Count() != 2)
  53.              return  false ;
  54.          CircularArc3d[] circles = brep.Edges
  55.              .Select(edge =>
  56.              ((ExternalCurve3d)edge.Curve).NativeCurve
  57.              as  CircularArc3d)
  58.              .Where(circle => circle != null )
  59.              .ToArray();
  60.          if  (circles.Length != 2)
  61.              isCylinder = false ;
  62.          else
  63.          {
  64.              isCylinder =
  65.              (circles[0].Radius == circles[1].Radius &&
  66.              circles[0].Normal.IsParallelTo(circles[1].Normal));
  67.              axisPt1 = circles[0].Center;
  68.              axisPt2 = circles[1].Center;
  69.          }
  70.      }
  71.      return  isCylinder;
  72.  }

 

Источник: http://adndevblog.typepad.com/autocad/2015/09/finding-axis-end-points-of-a-cylindrical-3d-solid.html

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

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

Опубликовано 22.09.2015
Отредактировано 23.09.2015 в 16:25:19