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

ADN Club => AutoCAD .NET API => Тема начата: Judas от 28-02-2021, 16:23:52

Название: Объединение Surface
Отправлено: Judas от 28-02-2021, 16:23:52
День добрый.
Никто не сталкивался с задачей объединения Surface в одну большую поверхность? Есть много треугольников (Face), по ним создается Surface, а потом уже общая....но...
Не могу понять почему не работает surface.BooleanUnion(locSurface) не выводит результат в единую поверхность.
Код - C# [Выбрать]
  1. [CommandMethod("RR", CommandFlags.UsePickSet)]
  2.         // Поиск максимальных/минимальных треугольников по координате Z
  3.         public static void RR()
  4.         {
  5.             AccessDoc AcToDraw = new AccessDoc();
  6.             Database db = AcToDraw.DBase;
  7.             Editor ae = AcToDraw.Ed;
  8.             List<Triangle> triangleList = TriangleList();
  9.  
  10.             using (Transaction tr = db.TransactionManager.StartTransaction())
  11.             {
  12.                 //Перебираем поверхности
  13.                 BlockTableRecord blocktableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  14.                 Face face = (Face)tr.GetObject(triangleList.First().IdFace, OpenMode.ForWrite);
  15.                 triangleList.Remove(triangleList.First());
  16.                 Autodesk.AutoCAD.DatabaseServices.Surface surface = new Autodesk.AutoCAD.DatabaseServices.Surface();
  17.                 surface = Autodesk.AutoCAD.DatabaseServices.Surface.CreateFrom(face);
  18.                 //blocktableRecord.AppendEntity(surface);
  19.                 //tr.AddNewlyCreatedDBObject(surface, true);
  20.                 foreach (Triangle triangle in triangleList)
  21.                 {
  22.                     face = (Face)tr.GetObject(triangle.IdFace, OpenMode.ForWrite);
  23.                     Autodesk.AutoCAD.DatabaseServices.Surface locSurface = new Autodesk.AutoCAD.DatabaseServices.Surface();
  24.                     locSurface = Autodesk.AutoCAD.DatabaseServices.Surface.CreateFrom(face);
  25.                     //blocktableRecord.AppendEntity(locSurface);
  26.                     //tr.AddNewlyCreatedDBObject(locSurface, true);
  27.                     surface.BooleanUnion(locSurface);
  28.                 }
  29.                 blocktableRecord.AppendEntity(surface);
  30.                 tr.AddNewlyCreatedDBObject(surface, true);
  31.                
  32.  
  33.  
  34.                 tr.Commit();
  35.             }
  36.         }
  37.  
Название: Re: Объединение Surface
Отправлено: Александр Ривилис от 28-02-2021, 16:39:13
Исключение какое-нибудь возникает?
Ну и как минимум вместо:
Код - C# [Выбрать]
  1. surface.BooleanUnion(locSurface);
должно быть:
Код - C# [Выбрать]
  1. surface = surface.BooleanUnion(locSurface);
Название: Re: Объединение Surface
Отправлено: Judas от 28-02-2021, 16:46:46
При
Код - C# [Выбрать]
  1. surface = surface.BooleanUnion(locSurface);
  2.  
Фатал Error
Код - C# [Выбрать]
  1. -----Current Stack:
  2.    � acadUnhandledExceptionFilter(_EXCEPTION_POINTERS* )
  3.  
  4.    � acadUnhandledExceptionFilter(_EXCEPTION_POINTERS* )
  5.  
  6.    � Autodesk.AutoCAD.Runtime.UnhandledExceptionFilter.Filter(_EXCEPTION_POINTERS* ep)
  7.  
  8.    � Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
  9.  
  10.    � EngineeringProtection.TriangleThalwegLine.RR() � G:\Csharp\Programm\005-EngineeringProtection\EngineeringProtection\EngineeringProtection\03-TriangleThalwegLine.cs:������ 476
  11.  
  12.    � Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
  13.  
  14.    � Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
  15.  
  16.    � Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()
  17.  


Название: Re: Объединение Surface
Отправлено: Judas от 28-02-2021, 16:49:43
Исключений нет при:
Код - C# [Выбрать]
  1.  surface.BooleanUnion(locSurface);
  2.  

Работает все норм без исключений, но без результата
Название: Re: Объединение Surface
Отправлено: Александр Ривилис от 28-02-2021, 16:51:29
А если так:
Код - C# [Выбрать]
  1. Surface surface1 = surface.BooleanUnion(locSurface);
Название: Re: Объединение Surface
Отправлено: Judas от 28-02-2021, 16:56:12
не работает
(https://i.postimg.cc/LJhNX8R1/image.jpg) (https://postimg.cc/LJhNX8R1)

в ручную через union все хорошо получается.
Название: Re: Объединение Surface
Отправлено: Александр Ривилис от 28-02-2021, 16:59:49
Judas,
Ну я так понимаю, что треугольники должны быть отсортированы так, чтобы объединялись те, у которых есть общие грани. Ведь объединить два треугольника, которые не имеют общих граней нельзя - поверхность не получится.
Название: Re: Объединение Surface
Отправлено: Judas от 28-02-2021, 17:06:51
Да. Верно. Это поверхность после триангуляции.
Специально тестил на данном примере. в ручную, через штатные инструменты автокада - все получается все выбираются и объединяются.
Как минимум у них есть 1 общая точка.

(https://i.postimg.cc/ZCQD6dwc/1.jpg) (https://postimg.cc/ZCQD6dwc)
Название: Re: Объединение Surface
Отправлено: Александр Ривилис от 28-02-2021, 17:18:35
Как минимум у них есть 1 общая точка.
Ты не понял. На вход surface.BooleanUnion нужно передавать Surface имеющую с surface общее ребро.
Но не исключаю, что API работает не так как следует. Так что или использовать командные методы или придумывать другой алгоритм, на который я давал ссылку раньше: https://www.keanw.com/2009/07/triangulating-an-autocad-sub-division-mesh-from-a-set-of-points-using-net.html
Название: Re: Объединение Surface
Отправлено: Judas от 28-02-2021, 17:31:13
По разбираюсь, но странновато почему - ручные работают, а в с# нет.
Название: Re: Объединение Surface
Отправлено: Александр Ривилис от 28-02-2021, 17:35:15
По разбираюсь, но странновато почему - ручные работают, а в с# нет.
Абсолютно ничего странного - команда значительно сложнее, чем просто метод BooleanUnion.
Название: Re: Объединение Surface
Отправлено: avc от 28-02-2021, 17:50:06
Могу подтвердить, что BooleanUnion c surface вполне нормально работает. По крайней мере на моих тестовых примерах, сразу после конвертации из сетей. И да, в реализации метода (именно в AutoCAD) есть ошибка - возвращает всегда null, а результат запихивается в this. Приходится клонировать поверхность перед вызовом BooleanUnion.
Название: Re: Объединение Surface
Отправлено: Judas от 07-03-2021, 15:58:12
avc
Цитировать
Могу подтвердить, что BooleanUnion c surface вполне нормально работает. По крайней мере на моих тестовых примерах, сразу после конвертации из сетей. И да, в реализации метода (именно в AutoCAD) есть ошибка - возвращает всегда null, а результат запихивается в this. Приходится клонировать поверхность перед вызовом BooleanUnion.
Можно консультацию?
А как вы объединяете сеть? т.е. 10000 face получается 10000 SubDMesh.
Потом их объединяете? Или сразу делаете SubDMesh на все выбранные Face?
Если делаете сразу 1 сеть на все поделитесь секретом успеха..
Название: Re: Объединение Surface
Отправлено: avc от 07-03-2021, 16:11:20
Никакого секрета. У меня простая программа конвертации СЕТЕЙ (PolyFaceMesh и SubDMesh) в солиды. https://sites.google.com/site/avcplugins/meshtosolid (https://sites.google.com/site/avcplugins/meshtosolid) 
Но не этих странных AcDbFace. Сети генерят дизайнеры в 3DSMax. А Face в реальной жизни не встречаются.
Название: Re: Объединение Surface
Отправлено: Judas от 07-03-2021, 16:28:29
Печаль..
Название: Re: Объединение Surface
Отправлено: Александр Ривилис от 07-03-2021, 16:30:54
Judas,
Предложенный мной алгоритм не подошел?
Название: Re: Объединение Surface
Отправлено: Judas от 07-03-2021, 16:35:09
Подошел.
Сети получаются, но их не возможно объединить, мне нужна одна огромная, что бы ее исследовать на предмет гидрологии.
Поэтому пока зайдем с другого конца, может по дольше, но там видно будет.

П.С. Кстати не объединял surface именно потому что не было общих ребер на случайно выбранных surface - пусть пока это будет запасной вариант.
Название: Re: Объединение Surface
Отправлено: Александр Ривилис от 07-03-2021, 16:38:36
Сети получаются но их не возможно объединить
Не понял. Ты говоришь об этом:
А как вы объединяете сеть? т.е. 10000 face получается 10000 SubDMesh.
Тогда это глупость. Так быть не должно. Из всех Face должна была получится одна SubDMesh. Там же кусок кода:
Код - C# [Выбрать]
  1.       if (createSubDMesh)
  2.  
  3.       {
  4.  
  5.         Point3dCollection vertarray = new Point3dCollection();
  6.  
  7.         Int32Collection facearray = new Int32Collection();
  8.  
  9.  
  10.  
  11.         for (i = 0; i < npts; i++)
  12.  
  13.           vertarray.Add(new Point3d(ptx[i], pty[i], ptz[i]));
  14.  
  15.  
  16.  
  17.         j = 0;
  18.  
  19.         for (i = 0; i < ntri; i++)
  20.  
  21.         {
  22.  
  23.           facearray.Add(3);
  24.  
  25.           facearray.Add(pt1[i]);
  26.  
  27.           facearray.Add(pt2[i]);
  28.  
  29.           facearray.Add(pt3[i]);
  30.  
  31.         }
  32.  
  33.  
  34.  
  35.         SubDMesh sdm = new SubDMesh();
  36.  
  37.         sdm.SetDatabaseDefaults();
  38.  
  39.         sdm.SetSubDMesh(vertarray, facearray, 0);
  40.  
  41.         btr.AppendEntity(sdm);
  42.  
  43.         tr.AddNewlyCreatedDBObject(sdm, true);
  44.  
  45.       }
  46.  
  47.  
  48.  
  49.       tr.Commit();
  50.  
  51.     }
  52.  
  53.  
Название: Re: Объединение Surface
Отправлено: trir от 08-03-2021, 02:39:45
Очередной изобретатель Civil'а...