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

ADN Club => AutoCAD .NET API => Тема начата: Балиев от 03-03-2020, 16:20:20

Название: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 03-03-2020, 16:20:20
Есть solid3d. Нужно получить один из его фэйсов по 3-м точкам и экструдировать его. Подскажите, как получить фэйс?

Заранее благодарен.
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Александр Ривилис от 03-03-2020, 16:22:44
Нужно получить один из его фэйсов по 3-м точкам
Это как? Вообще-то Face может быть и не плоским...
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 03-03-2020, 16:37:07
Это как? Вообще-то Face может быть и не плоским...
Известно, что он плоский, поскольку получен Slice'ом на предыдущим этапе.
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Александр Ривилис от 03-03-2020, 16:48:51
Начни отсюда: https://adn-cis.org/forum/index.php?topic=7169.msg21062#msg21062
Там есть алгоритм получения всех SubentId для Solid3d. Тебе нужно будет выбрать только ту, у которой Face соответствует твоим трём точкам.
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 05-03-2020, 16:45:38
Странно... Почему то не срабатывает директива "using Autodesk.AutoCAD.BoundaryRepresentation;".
Пишет: "Error   CS0234   The type or namespace name 'BoundaryRepresentation' does not exist in the namespace 'Autodesk.AutoCAD' (are you missing an assembly reference?)   ".
Что бы это значило? Автокадовские библиотеки вроде загружены...
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Александр Ривилис от 05-03-2020, 16:46:45
Автокадовские библиотеки вроде загружены...
Вроде или загружены? Подозреваю что эта не подключена: acdbmgdbrep.dll
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 05-03-2020, 17:05:04
Подозреваю что эта не подключена: acdbmgdbrep.dll
Правильно подозреваешь. Просто я имел в виду 3 библиотеки из джентльменского набора.
Спасибо!
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 10-03-2020, 13:22:49
А как узнать принадлежит точка фэйсу или нет?
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Александр Ривилис от 10-03-2020, 14:07:53
А как узнать принадлежит точка фэйсу или нет?
Для этого есть метод BrepEntity.GetPointContainment(Point3d point, out PointContainment containment). Значение PointContainment может быть трёх видов:
Код - C# [Выбрать]
  1. public enum PointContainment
  2. {
  3.         Inside, // Внутри
  4.         Outside, // Снаружи
  5.         OnBoundary // На границе
  6. }
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 11-03-2020, 13:13:13
Никак не пойму почему такую конструкцию VS проглатывает:
Код - C# [Выбрать]
  1.                         if (sign == 1)
  2.                         {
  3.                             acSol3D.Layer = sLayerName; // перемещаем на уровень "IdealBendTools"
  4.                             acSol3D.Slice(acPlane1, false);  // >>>>>>>>>>>>>>>>>> ВТОРОЙ РАЗРЕЗ
  5.                             ObjectId[] idSolidSlice = new ObjectId[] { acSol3D.ObjectId };
  6.                             SubentityId subentId = new SubentityId(SubentityType.Null, IntPtr.Zero);
  7.                             FullSubentityPath path = new FullSubentityPath(idSolidSlice, subentId);
  8.                             List<SubentityId> subidSolidSlice = new List<SubentityId>();
  9.                             using (AcBr.Brep brep = new AcBr.Brep(path))
  10.                             {
  11.                                 foreach (AcBr.Face face in brep.Faces)
  12.                                 {
  13.                                     subidSolidSlice.Add(face.SubentityPath.SubentId);
  14.                                 }
  15.                             }
  16.  
  17.                         }
  18.                         else
  19.                         {
  20.                             acSol3DSlice.Layer = sLayerName; // перемещаем на уровень "IdealBendTools"
  21.                             Solid3d acSol3DSlice1 = acSol3DSlice.Slice(acPlane1, true); // >>>>>>>>>>>>>>>>>> ВТОРОЙ РАЗРЕЗ
  22.                             acBlkTblRec.AppendEntity(acSol3DSlice1);
  23.                             acTrans.AddNewlyCreatedDBObject(acSol3DSlice1, true);
  24.                             acSol3DSlice.Erase(true);
  25.                             ObjectId[] idSolidSlice = new ObjectId[] { acSol3DSlice1.ObjectId };
  26.                             SubentityId subentId = new SubentityId(SubentityType.Null, IntPtr.Zero);
  27.                             FullSubentityPath path = new FullSubentityPath(idSolidSlice, subentId);
  28.                             List<SubentityId> subidSolidSlice = new List<SubentityId>();
  29.                             using (AcBr.Brep brep = new AcBr.Brep(path))
  30.                             {
  31.                                 foreach (AcBr.Face face in brep.Faces)
  32.                                 {
  33.                                     subidSolidSlice.Add(face.SubentityPath.SubentId);
  34.                                 }
  35.                             }
  36.  
  37.                         }
  38.  
а про такую:
Код - C# [Выбрать]
  1.                         if (sign == 1)
  2.                         {
  3.                             acSol3D.Layer = sLayerName; // перемещаем на уровень "IdealBendTools"
  4.                             acSol3D.Slice(acPlane1, false);  // >>>>>>>>>>>>>>>>>> ВТОРОЙ РАЗРЕЗ
  5.                             ObjectId[] idSolidSlice = new ObjectId[] { acSol3D.ObjectId };
  6.                          }
  7.                         else
  8.                         {
  9.                             acSol3DSlice.Layer = sLayerName; // перемещаем на уровень "IdealBendTools"
  10.                             Solid3d acSol3DSlice1 = acSol3DSlice.Slice(acPlane1, true); // >>>>>>>>>>>>>>>>>> ВТОРОЙ РАЗРЕЗ
  11.                             acBlkTblRec.AppendEntity(acSol3DSlice1);
  12.                             acTrans.AddNewlyCreatedDBObject(acSol3DSlice1, true);
  13.                             acSol3DSlice.Erase(true);
  14.                             ObjectId[] idSolidSlice = new ObjectId[] { acSol3DSlice1.ObjectId };
  15.                         }
  16.  
  17.                         SubentityId subentId = new SubentityId(SubentityType.Null, IntPtr.Zero);
  18.                         FullSubentityPath path = new FullSubentityPath(idSolidSlice, subentId);
  19.                         List<SubentityId> subids = new List<SubentityId>();
  20.                         using (AcBr.Brep brep = new AcBr.Brep(path))
  21.                         {
  22.                             foreach (AcBr.Face face in brep.Faces)
  23.                             {
  24.                                 subidSolidSlice.Add(face.SubentityPath.SubentId);
  25.                             }
  26.                         }
говорит, что:
Error   CS0103   The name 'idSolidSlice' does not exist in the current context   
Error   CS0103   The name 'subidSolidSlice' does not exist in the current context   
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Александр Ривилис от 11-03-2020, 14:58:39
говорит, что:
Error   CS0103   The name 'idSolidSlice' does not exist in the current context   
Error   CS0103   The name 'subidSolidSlice' does not exist in the current context   
Потому что следует немного изучить C#. ;) Посмотри область видимости idSolidSlice и subidSolidSlice. Вынеси их  определения так, чтобы там где ты к ним обращаешься они были видны...
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 11-03-2020, 16:13:54
Потому что следует немного изучить C#. ;) Посмотри область видимости idSolidSlice и subidSolidSlice. Вынеси их  определения так, чтобы там где ты к ним обращаешься они были видны...
Спасибо, помогло!
PS. Когда нет опыта ни в С#, ни в AutoCAD .NET'e, то такие проколы, к сожалению, неизбежны.
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 23-03-2020, 13:50:04
Начни отсюда: https://adn-cis.org/forum/index.php?topic=7169.msg21062#msg21062
Там есть алгоритм получения всех SubentId для Solid3d. Тебе нужно будет выбрать только ту, у которой Face соответствует твоим трём точкам.
Face выбрал, но не получается экструдировать: не понимаю, как указать первый параметр в методе Solid3d.ExtrudeFacesAlongPath. Пробовал разные варианты, но ответ всегда один: Argument 1: cannot convert from 'Autodesk.AutoCAD.DatabaseServices.SubentityId' to 'Autodesk.AutoCAD.DatabaseServices.SubentityId[]'.
Вот пример моего кода:
Код - C# [Выбрать]
  1.                         Point3d arcStartPoint = new Point3d(lengthX / 2, bendCoor, lengthZ / 2);
  2.                         Arc acArcPath;
  3.                         using (acArcPath = new Arc(arcStartPoint, rBend+hBend/2, 0, alfaBend))
  4.                         {
  5.                             // Add the new object to the block table record and the transaction
  6.                             acBlkTblRec.AppendEntity(acArcPath);
  7.                             acTrans.AddNewlyCreatedDBObject(acArcPath, true);
  8.                         }
  9.  
  10.  
  11.                         PtToCheck = new Point3d(lengthZ / 2, bendCoor, lengthZ / 2);
  12.                         SubentityId subentId = new SubentityId(SubentityType.Null, IntPtr.Zero);
  13.                         FullSubentityPath path = new FullSubentityPath(idSolidSlice, subentId);
  14.                         using (AcBr.Brep brep = new AcBr.Brep(path))
  15.                         {
  16.                             foreach (AcBr.Face face in brep.Faces)
  17.                             {
  18.                                 PointContainment ptContainment = new PointContainment();
  19.                                 using (BrepEntity brepEnt = face.GetPointContainment(PtToCheck, out ptContainment))
  20.                                 {
  21.                                     {
  22.                                         if (ptContainment == PointContainment.Inside)
  23.                                         {
  24.                                            Solid3d bendPart = Solid3d.ExtrudeFacesAlongPath(face.SubentityPath.SubentId, acArcPath);
  25.                                         }
  26.                                     }
  27.                                 }
  28.                             }
  29.                         }
  30.  
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Александр Ривилис от 23-03-2020, 14:19:17
Пробовал разные варианты, но ответ всегда один: Argument 1: cannot convert from 'Autodesk.AutoCAD.DatabaseServices.SubentityId' to 'Autodesk.AutoCAD.DatabaseServices.SubentityId[]'.
Передавать нужно массив SubentityId, а не один SubentityId. И в массиве только один элемент: face.SubentityPath.SubentId
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 08-04-2020, 17:18:33
Не могу понять, почему не выполняется экструзия (при этом никаких ошибок не генерится). Вот кусок кода:

Код - C# [Выбрать]
  1. ...
  2.  Point3d arcCentrePoint = new Point3d(lengthX/2 - (rBend+hBend/2), bendCoor, lengthZ / 2);
  3.  Arc acArcPath;
  4.  using (acArcPath = new Arc(arcCentrePoint, rBend+hBend/2, 0, alfaBend* Math.PI/180))
  5.  {
  6.      Matrix3d curUCSMatrix = acDoc.Editor.CurrentUserCoordinateSystem;
  7.      CoordinateSystem3d curUCS = curUCSMatrix.CoordinateSystem3d;
  8.  
  9.      Vector3d vRot = new Point3d(lengthX / 2, bendCoor, lengthZ / 2).
  10.                      GetVectorTo(new Point3d(lengthX / 2, bendCoor + 10, lengthZ / 2));
  11.      acArcPath.TransformBy(Matrix3d.Rotation(Math.PI / 2, vRot, new Point3d(lengthX / 2, bendCoor, lengthZ / 2)));
  12.  
  13.      acBlkTblRec.AppendEntity(acArcPath);
  14.      acTrans.AddNewlyCreatedDBObject(acArcPath, true);
  15.  }
  16.  
  17.  
  18.  PtToCheck = new Point3d(lengthZ / 2, bendCoor, lengthZ / 2);
  19.  SubentityId subentId = new SubentityId(SubentityType.Null, IntPtr.Zero);
  20.  FullSubentityPath path = new FullSubentityPath(idSolidSlice, subentId);
  21.  using (AcBr.Brep brep = new AcBr.Brep(path))
  22.  {
  23.       foreach (AcBr.Face face in brep.Faces)
  24.      {
  25.          PointContainment ptContainment = new PointContainment();
  26.          using (BrepEntity brepEnt = face.GetPointContainment(PtToCheck, out ptContainment))
  27.          {
  28.              {
  29.                  if (ptContainment == PointContainment.Inside)
  30.                  {
  31.                      SubentityId[] arraySubentityId = new SubentityId[] { face.SubentityPath.SubentId };
  32.                      using (Solid3d extrFromFace = new Solid3d())
  33.                      {
  34.                          extrFromFace.ExtrudeFacesAlongPath(arraySubentityId, acArcPath);
  35.                          acBlkTblRec.AppendEntity(extrFromFace);
  36.                          acTrans.AddNewlyCreatedDBObject(extrFromFace, true);
  37.                      }
  38.                  }
  39.              }
  40.          }
  41.      }
  42. }
  43. ...
  44.  
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Александр Ривилис от 08-04-2020, 17:25:47
Ну наверное потому, что extrFromFace у тебя пустой.
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 08-04-2020, 17:34:34
Ну наверное потому, что extrFromFace у тебя пустой.
Изначально да, но, разве, потом он не "наполняется" в результате исполнения метода экструзии из face'а?
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Александр Ривилис от 08-04-2020, 17:38:25
Ну наверное потому, что extrFromFace у тебя пустой.
Изначально да, но, разве, потом он не "наполняется" в результате исполнения метода экструзии из face'а?
Нет конечно. Эту операцию нужно производить над исходным Solid3d.
Название: Re: Как получить фэйс (face) для экструзии?
Отправлено: Балиев от 10-04-2020, 18:55:05
Нет конечно. Эту операцию нужно производить над исходным Solid3d.
Ну, наконец-то все получилось. Спасибо!