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

ADN Club => Revit API => Тема начата: enot от 07-11-2018, 22:42:22

Название: Solid помещения
Отправлено: enot от 07-11-2018, 22:42:22
Получаю солид помещения
Код - C# [Выбрать]
  1. SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc);
  2. SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(room);
  3. Solid roomSolid = results.GetGeometry();

Солид выдает ошибку :
Curve join produced more than one WIRE in PolyCurve

В чем может быть причина (вероятно, идет наложение/пересечение линий)?  Так как и метод room.GetBoundarySegments(options) c последующим получением линий и формированием из них CurveLoop дает ошибку =>The profile CurveLoops are not valid. Some possible reasons: the loop is not continuous; the loop contains a null curve; the loops is marked as closed but is in fact open, or vice versa. ;
----------------------------------------
Конечной целью является получение периметральных линий помещения на плане, именно для всех помещений проекта
Если рассматривать только активный вид то логика примерно такая:

Код - C# [Выбрать]
  1. Options options = app.Create.NewGeometryOptions();
  2. options.IncludeNonVisibleObjects = true;
  3. options.View = doc.ActiveView;
  4. var geom_elem = room.get_Geometry(options);
далее через  сравниваем doc.GetElement(e.GraphicsStyleId).Category с  OST_IOSRoomPerimeterLines
-------------------------------------------------



Название: Re: Solid помещения
Отправлено: Александр Игнатович от 07-11-2018, 23:42:19
На модель бы посмотреть, конечно.

Предполагаемые причины описаны в SDK по методу SpatialElementGeometryCalculator.CanCalculateGeometry:
Цитировать
Return Value
It will return false if the room/space is not enclosed in 2d or has no location, or the height is too small.
Название: Re: Solid помещения
Отправлено: enot от 08-11-2018, 00:07:18
Файл с проблемным помещением:

https://cloud.mail.ru/public/4sZfffhD (https://cloud.mail.ru/publicc/4sZ6/AXwXGRnpE)

Линии curves дают ошибку в месте
CurveLoop loop_curve = CurveLoop.Create(curves);
Далее планирую выдавливание геометрии из CurveLoop
Название: Re: Solid помещения
Отправлено: Александр Игнатович от 08-11-2018, 01:36:38
Так, ну смотрите, вот код (на Revit Python Shell), думаю, не проблема будет перевести при необходимости, который Вам нужен
Код - Python [Выбрать]
  1. room = selection[0] #нужно выбрать помещение
  2.  
  3. calculator = SpatialElementGeometryCalculator(doc)
  4. results = calculator.CalculateSpatialElementGeometry(room)
  5.  
  6. solid = results.GetGeometry()
  7.  
  8. plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, room.get_BoundingBox(None).Min-XYZ.BasisZ)
  9.  
  10. extrAnalyzer = ExtrusionAnalyzer.Create(solid, plane, -1*XYZ.BasisZ)
  11.  
  12. face = extrAnalyzer.GetExtrusionBase()
  13.  
  14. print face.GetEdgesAsCurveLoops()# тут работаем как раз с CurveLoop-ом

НО. Оно не заработает, пока слегка не поправить модель. Я пробовал по-разному получать Solid, через get_Geometry, из свойства ClosedShell, даже пытался создавать FreeForm в семействе на основе этой геометрии и заново получать геометрию, нет, ExtrusionAnalyzer.Create вываливается с ошибкой. Пёс с ним, выбираем непосредственно из геометрии (не важно, get_Geometry или ClosedShell) solid, из него берем поверхность с нормалью -1*XYZ.BasisZ, окей, дальше берем границы - CurveLoop и тут внезапно оказывается, что он незамкнут, IsOpen() выдает true.

Как поправить файл:

(https://i.postimg.cc/vcgnKR0Y/fix-file.png) (https://postimg.cc/vcgnKR0Y)

Как понять, что нужно править именно в этом месте - не знаю, смотреть стены, ограничивающие помещения, но тут есть более очевидные кандидаты, на одной из стен висит предупреждение, у другой стоит запрет на соединение

Но №2: а какая задача? зачем
Далее планирую выдавливание геометрии из CurveLoop

У Вас вроде и так уже есть готовый Solid
Название: Re: Solid помещения
Отправлено: enot от 08-11-2018, 07:25:34
Александр, по первому вопросу:
Если получаем линии через GetBoundarySegments линии по периметру помещения => переводим их в линии модели, чтобы посмотреть
Далее , есть линия, которая находится как раз в месте  начало и конец которой находится на первом и втором ,приложенных вами, скринах (начало и конец получается в точках с синими кружочками). Получается линия малой длины.
Иногда при черчении линии (например делаем профиль выдавливания в семействе) ревит выдает ошибку : "Элемент на экране выглядит маленьким" => возможно, в этом кроется причина? (интересно, какой предел длины, при которой такая ошибка возникает)
Тогда мы попадаем под ,описанное в первом посте, исключение
the loop contains a null curve; ( в этом случае вопрос будет в введении проверки на исключение таких null curve (в моем понимании линия малой длины ?) из curveloop (но при исключении таких линий curveloop может оказаться незамкнутым)

По второму вопросу : Полученный периметральный curveloop я масштабирую и затем выдавливаю, получаю новый солид
Название: Re: Solid помещения
Отправлено: enot от 08-11-2018, 11:15:33
IsOpen() выдает true
curveloop ( от Face-ов солида помещения) у которых IsOpen = False
(https://i.postimg.cc/q6zKyr35/Is-Open-False.png) (https://postimg.cc/q6zKyr35)

curveloop у которых IsOpen = True
(https://i.postimg.cc/75VLHcCG/Is-Open-True.png) (https://postimg.cc/75VLHcCG)
Название: Re: Solid помещения
Отправлено: Александр Игнатович от 08-11-2018, 11:22:03
Насчет линий малой длины - нельзя создать ModelCurve/DetailCurve для линий короче Application.ShortCurveTolerance.

Вообще, конечно, плохо то, что Revit не выдает по этому помещению никаких предупреждений, получает Solid, даже по нему можно создать в семействе FreeForm
Название: Re: Solid помещения
Отправлено: enot от 08-11-2018, 11:28:40
значит дело не в линиях малой длины, так как
Curve.Length> Application.ShortCurveTolerance  пропустил все линии, входящих в CurveLoop у которого  IsOpen = True
Название: Re: Solid помещения
Отправлено: Александр Игнатович от 08-11-2018, 11:45:21
А причину со следствием не перепутали?) solid помещения уже необычен тем, что у некоторых его поверхностей ребра не образуют замкнутых контуров, т.е. какая-то проблем идет из глубин модели, как её строили. Кстати, она изначально из Revit, или результат экспорта из другого формата?
Название: Re: Solid помещения
Отправлено: enot от 08-11-2018, 11:53:50
изначально из Revit
Модель из Ревит

у некоторых его поверхностей ребра не образуют замкнутых контуров
Тут не понял. Как можно построить поверхность Face из незамкнутых линий
Название: Re: Solid помещения
Отправлено: Александр Пекшев aka Modis от 08-11-2018, 11:57:47
Попробуйте метод GetRoomBoundaryAsCurveLoopArray (http://www.revitapidocs.com/2018.1/b460e4ed-62c0-5611-16ba-a1bd9a85625a.htm)
Название: Re: Solid помещения
Отправлено: enot от 08-11-2018, 12:24:56
Попробуйте метод GetRoomBoundaryAsCurveLoopArray
using Autodesk.Revit.DB.IFC.ExporterIFCUtils;

ExporterIFCUtils просит библиотеку (RevitApI и RevitUI уже подгружены)
Название: Re: Solid помещения
Отправлено: Александр Пекшев aka Modis от 08-11-2018, 12:27:01
Попробуйте метод GetRoomBoundaryAsCurveLoopArray
using Autodesk.Revit.DB.IFC.ExporterIFCUtils;

ExporterIFCUtils просит библиотеку (RevitApI и RevitUI уже подгружены)
Подключите "C:\Program Files\Autodesk\Revit 2018\RevitAPIIFC.dll"
Название: Re: Solid помещения
Отправлено: enot от 08-11-2018, 12:32:10
Подключите "C:\Program Files\Autodesk\Revit 2018\RevitAPIIFC.dll"
Получилось. Спасибо
Метод хорош, но грабли с CurveLoop те же

Пробуя получить Offset для CurveLoop
Код - C# [Выбрать]
  1. CurveLoop offset_curve = CurveLoop.CreateViaOffset(sourceLoop, offset,  sourceLoop.GetPlane().Normal)
используя (скорее следовало бы там продолжить этот вопрос...)
http://adn-cis.org/forum/index.php?topic=8848.0 (http://adn-cis.org/forum/index.php?topic=8848.0)

Получаем (некоторые линии смещаются не наружу  , а внутрь ) ошибку Curve loop couldn't be properly trimmed.

(https://i.postimg.cc/Q9Hp9MMv/WRONG-Curve-Offset.png) (https://postimg.cc/Q9Hp9MMv)

В чем может быть причина...