ProjectOnToSurface - проекцирование примитивов

Автор Тема: ProjectOnToSurface - проекцирование примитивов  (Прочитано 10270 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн JudasАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Всем привет.
Вопрос по проецированию отрезков на поверхность.
Все отрабатывает нормально при условии, что отрезок один задан.
Если нужно проверить массив с изменяемым нагом, условно на 3DFACE перебрать все точки проекции, то строка 
Код - C# [Выбрать]
  1. Entity[] projectedEntities = surface.ProjectOnToSurface(line, Vector3d.ZAxis);
  2.  
выдает ошибку:
Autodesk.AutoCAD.Runtime.Exception: eGeneralModelingFailure
   в Autodesk.AutoCAD.DatabaseServices.Surface.ProjectOnToSurface(Entity entityToProject, Vector3d projectionDirection)
   в EngineeringProtection.TriangleThalwegLine.CrossLine() в F:\Csharp\Programm\005-EngineeringProtection\EngineeringProtection\EngineeringProtection\02-TriangleThalwegLine.cs:строка 452
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()

Если пересечения нету (а такое может быть) Entity[] =null и все. Если нет, то работаем дальше.
eGeneralModelingFailure - ошибка создания модели??

Код - C# [Выбрать]
  1. // Поиск линии пересечений
  2.         [CommandMethod("CrossLine", CommandFlags.UsePickSet)]
  3.         public static void CrossLine()
  4.         {
  5.             // Доступ к чертежу
  6.             AccessDoc ad = new AccessDoc();
  7.             Database db = ad.DBase;
  8.             Editor ae = ad.Ed;
  9.  
  10.             //Список всех треугольников
  11.             List<Triangle> triangleList = TriangleList();
  12.  
  13.             // границы зон исследования
  14.             FindBorder(out double x1, out double x2, out double y1, out double y2, out double z1, out double z2);
  15.  
  16.             double dx = 0.5;
  17.             double dy = 0.5;
  18.             //
  19.             int n = 0;
  20.  
  21.             using (Transaction tr = db.TransactionManager.StartTransaction())
  22.             {
  23.                 // Таблица записи текущего пространства
  24.                 //BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
  25.                 BlockTableRecord ms = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  26.  
  27.  
  28.                 // Перебираем поверхности
  29.  
  30.                 for (int i = (int)y1; i <= (int)y2; i++)
  31.                 {
  32.                     PromptSelectionResult selectionResult = ae.SelectCrossingWindow(new Point3d(x1 - dx, i - dy, 0), new Point3d(x2 + dx, i + dy, 0));
  33.                     SelectionSet acSSet = selectionResult.Value;
  34.  
  35.                     if (selectionResult.Status == PromptStatus.OK && acSSet.Count > 0)
  36.                     {
  37.                        
  38.                         foreach (SelectedObject selobj in acSSet)
  39.                         {
  40.                             //MessageBox.Show((selobj.GetType()).ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  41.                             //if (selobj.GetType() == typeof(Autodesk.AutoCAD.DatabaseServices.Face))
  42.                             {
  43.                                 //MessageBox.Show((1).ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  44.                                 Face face = (Face)tr.GetObject(selobj.ObjectId, OpenMode.ForWrite);
  45.  
  46.                                 Autodesk.AutoCAD.DatabaseServices.Surface surface = new Autodesk.AutoCAD.DatabaseServices.Surface();
  47.  
  48.                                 surface = Autodesk.AutoCAD.DatabaseServices.Surface.CreateFrom(face);
  49.  
  50.                                 ms.AppendEntity(surface);
  51.                                 tr.AddNewlyCreatedDBObject(surface, true);
  52.                                
  53.                                 for (int j = (int)x1; j <= (int)x2-1; j++)
  54.                                 {
  55.  
  56.                                     Line line = new Line(new Point3d(i, j, 0), new Point3d(i+1, j, 0));
  57.  
  58.                                     //line = new Line(new Point3d(8.7579, 9.2385, 0), new Point3d(17.1127, 9.2385, 0));
  59.                                    
  60.                                     ms.AppendEntity(line);
  61.                                     tr.AddNewlyCreatedDBObject(line, true);
  62.                                    
  63.                                     Entity[] projectedEntities = surface.ProjectOnToSurface(line, Vector3d.ZAxis);
  64.  
  65.                                     if (projectedEntities != null)
  66.                                     {
  67.                                         n++;
  68.                                     }
  69.                                 }
  70.                             }
  71.                         }
  72.                     }
  73.                 }
  74.                 tr.Commit();
  75.             }
  76.             MessageBox.Show(n.ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  77.         }
  78.  

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 167
    • Мои плагины к Автокаду
eGeneralModelingFailure - ошибка создания модели??
Общая ошибка моделирования, то есть в переводе не нормальный язык - "идите лесом, я устала". Ошибка сыпется при всех операциях в 3D, когда разработчики Автокада что-то недопрограммировали. И объекты уже настолько заглюченные, что с ними вообще ничего нельзя сделать.

Оффлайн JudasАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Лекарство есть?

Оффлайн JudasАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Как раз не отрабатывает:
Код - C# [Выбрать]
  1. Entity[] projectedEntities = surface.ProjectOnToSurface(line, Vector3d.ZAxis);
  2. if (projectedEntities != null)
  3.  

null не возвращается, т.е. если отрезок или точка в вертикальной проекции за границей поверхности на которую проецируется, то возвращается  eGeneralModelingFailure, а д.б. null.

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 167
    • Мои плагины к Автокаду
А, ну если вы уже вычислили, в каком именно случае выскакивает этот эксепшн, от проблема решена - перехватывайте и обрабатывайте соответственно тому, что вам надо. Считайте, что крупно повезло - это не недоделка и не хаотический глюк, а такая особенность API. Чаще именно этот эксепшн абсолютно рандомный и ничего не значит. А мог бы быть и фатал...

Оффлайн JudasАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 80
  • Карма: 0
Тогда примерно так:
Код - C# [Выбрать]
  1.       // Поиск линии пересечений
  2.         [CommandMethod("CrossLine", CommandFlags.UsePickSet)]
  3.         public static void CrossLine()
  4.         {
  5.             // Доступ к чертежу
  6.             AccessDoc ad = new AccessDoc();
  7.             Database db = ad.DBase;
  8.             Editor ae = ad.Ed;
  9.  
  10.             //Список всех треугольников
  11.             //List<Triangle> triangleList = TriangleList();
  12.  
  13.             // границы зон исследования
  14.             FindBorder(out double x1, out double x2, out double y1, out double y2, out double z1, out double z2);
  15.  
  16.             // допуски на выборку
  17.             int dx = 3;
  18.             int dy = 3;
  19.            
  20.             //
  21.             int n = 0;
  22.  
  23.             //
  24.             //double[,] data = new double[87, 33];
  25.  
  26.             using (Transaction tr = db.TransactionManager.StartTransaction())
  27.             {
  28.                 // таблица записи текущего пространства
  29.                 BlockTableRecord ms = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  30.  
  31.                 // выбор всех граней
  32.                 PromptSelectionResult selectionResult = ae.SelectCrossingWindow(new Point3d(x1 - dx, y1 - dy, 0), new Point3d(x2 + dx, y2 + dy, 0));
  33.                 SelectionSet acSSet = selectionResult.Value;
  34.                 // проверка на пустой выбор
  35.                 if (selectionResult.Status == PromptStatus.OK && acSSet.Count > 0)
  36.                 {
  37.                     // перебираем поверхности
  38.                     foreach (SelectedObject selobj in acSSet)
  39.                     {
  40.                         // проверка selobj на то, что он 3DFACE
  41.                         //if (selobj.GetType() == typeof(Autodesk.AutoCAD.DatabaseServices.Face))
  42.  
  43.                         // создаем поверхность по 3DFACE
  44.                         Face face = (Face)tr.GetObject(selobj.ObjectId, OpenMode.ForWrite);
  45.                         Autodesk.AutoCAD.DatabaseServices.Surface surface = new Autodesk.AutoCAD.DatabaseServices.Surface();
  46.                         surface = Autodesk.AutoCAD.DatabaseServices.Surface.CreateFrom(face);
  47.                         //ms.AppendEntity(surface);
  48.                         //tr.AddNewlyCreatedDBObject(surface, true);
  49.  
  50.                         for (int i = (int)y1 - dy; i <= (int)y2 + dy; i+=dy)
  51.                         {
  52.                             for (int j = (int)x1 - dx; j <= (int)x2 + dx; j += dx)
  53.                             {
  54.  
  55.                                 // создаем линию для поиска пересечений
  56.                                 Line line = new Line(new Point3d(j, i, 0), new Point3d(j + dx, i, 0));
  57.                                 //ms.AppendEntity(line);      
  58.                                 //tr.AddNewlyCreatedDBObject(line, true);
  59.  
  60.                                 try
  61.                                 {
  62.                                     Entity[] projectedEntities = surface.ProjectOnToSurface(line, Vector3d.ZAxis);
  63.                                     if (projectedEntities != null)
  64.                                     {
  65.                                         n++;
  66.                                     }
  67.                                 }
  68.                                 catch
  69.                                 {
  70.                                     //MessageBox.Show("ИСКЛЮЧЕНИЕ", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  71.                                 }
  72.                             }
  73.                         }
  74.                     }
  75.                 }
  76.                 tr.Commit();
  77.             }
  78.             MessageBox.Show(n.ToString(), "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  79.         }
  80.  

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 167
    • Мои плагины к Автокаду
Ну да. В идеале конечно с перехватом конкретного Rt.Exception с конкретным статусом ex.ErrorStatus == Rt.ErrorStatus.GeneralModelingFailure