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

01/09/2017

Как выбрать грани соседствующие с выбранным ребром 3DSOLID

Используя BREP API, довольно просто получить смежные грани для выбранного ребра 3DSOLID.

Мы будем использовать Boundary Loop, чтобы получить все петли, в которые входит выбранное ребро для получения соседних граней.

Код - C#: [Выделить]
  1. [CommandMethod("GAF")]
  2. static public void GetAdjacentFaces()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   Database db = doc.Database;
  6.   Editor ed = doc.Editor;
  7.   PromptKeywordOptions pko =
  8.     new PromptKeywordOptions("\nВыберите тип подобъекта:");
  9.   pko.AllowNone = false;
  10.   pko.Keywords.Add("Ребро");
  11.   pko.Keywords.Default = "Ребро";
  12.  
  13.   PromptResult pkr = ed.GetKeywords(pko);
  14.  
  15.   if (pkr.Status != PromptStatus.OK)
  16.     return;
  17.   // Пользователь выбрал Ребро
  18.   SubentityType subentityType = SubentityType.Edge;
  19.  
  20.  
  21.   // Включаем выбор подобъектов
  22.   PromptSelectionOptions pso = new PromptSelectionOptions();
  23.   pso.MessageForAdding = "\nВыберите у твердого тела " +
  24.       pkr.StringResult + ": ";
  25.   pso.SingleOnly = true;
  26.   pso.SinglePickInSpace = true;
  27.   pso.ForceSubSelections = true;
  28.  
  29.   PromptSelectionResult psr = ed.GetSelection(pso);
  30.  
  31.   if (psr.Status != PromptStatus.OK)
  32.     return;
  33.  
  34.   SelectionSet ss = psr.Value;
  35.  
  36.   SelectedObject so = ss[0];
  37.  
  38.   if (!so.ObjectId.ObjectClass.IsDerivedFrom(
  39.       RXClass.GetClass(typeof(Solid3d))))
  40.   {
  41.     ed.WriteMessage(
  42.         "\nВы не выбрали твердое тело - повторите пожалуйста...");
  43.     return;
  44.   }
  45.   // Для сохранения соседних граней
  46.   List<SubentityId> faceIds = new List<SubentityId>();
  47.   using (Transaction Tx = db.TransactionManager.StartTransaction())
  48.   {
  49.     Solid3d solid = Tx.GetObject(so.ObjectId, OpenMode.ForWrite)
  50.         as Solid3d;
  51.  
  52.     SelectedSubObject[] sso = so.GetSubentities();
  53.  
  54.     // Проверяем, что выбранный объект соответствует заданному типу
  55.     if (subentityType != sso[0].FullSubentityPath.SubentId.Type)
  56.     {
  57.       ed.WriteMessage("\nНеправильный тип подобъекта: " +
  58.           sso[0].FullSubentityPath.SubentId.Type +
  59.           ", повторите снова...");
  60.       return;
  61.     }
  62.  
  63.     SubentityId subentityId = sso[0].FullSubentityPath.SubentId;
  64.  
  65.     // Создаём путь к подобъекту для использования в GetSubentity
  66.     FullSubentityPath subEntityPath = new FullSubentityPath(
  67.         new ObjectId[] { solid.ObjectId },
  68.         subentityId);
  69.  
  70.     // Возвращаем примитив (не содержащийся в базе),
  71.     // который представляет подобъект
  72.     using (Entity entity = solid.GetSubentity(subEntityPath))
  73.     {
  74.       ed.WriteMessage("\nТип подобъекта: "
  75.           + entity.ToString());
  76.     }
  77.  
  78.     // Создаём путь для генерации объекта BREP
  79.     FullSubentityPath entityPath = new FullSubentityPath(
  80.         new ObjectId[] { solid.ObjectId },
  81.         new SubentityId(SubentityType.Null, IntPtr.Zero));
  82.  
  83.     using (Edge edge = new Edge(subEntityPath))
  84.     {
  85.       if (subentityType == SubentityType.Edge)
  86.       {
  87.         if (subentityId == edge.SubentityPath.SubentId)
  88.         {
  89.           ed.WriteMessage("\nКривая: " + edge.Curve.ToString());
  90.           // Теперь раскрасим грани.
  91.           foreach (BoundaryLoop loop in edge.Loops)
  92.           {
  93.             // Для простейшего варианта нас будет интересовать внешняя петля
  94.             if (loop.LoopType == LoopType.LoopExterior)
  95.             {
  96.               AcBr.Face face = loop.Face;
  97.               faceIds.Add(face.SubentityPath.SubentId);
  98.             }
  99.           }
  100.  
  101.           if (faceIds.Count > 1)
  102.             foreach (SubentityId subentId in faceIds)
  103.             {
  104.               Color col = Color.FromColorIndex(ColorMethod.ByColor, 1);
  105.               solid.SetSubentityColor(subentId, col);
  106.             }
  107.         }
  108.       }
  109.     }
  110.  
  111.     Tx.Commit();
  112.   }
  113. }
  114.  

 

Источник: http://adndevblog.typepad.com/autocad/2017/08/how-get-adjacent-faces-from-a-selected-edge-in-solid.html

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

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

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