Получение всех объектов вокруг Room

Автор Тема: Получение всех объектов вокруг Room  (Прочитано 8731 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN Club
  • ***
  • Сообщений: 214
  • Карма: 5
  • Sergey
  • Skype: sergey.s.shevtsov
Здравствуйте!
Столкнулся с интересной задачей, нужно получить все элементы окружающие Room.
Для стен написал так:
Код - C# [Выбрать]
  1. Room room = doc.GetElement(id) as Room;
  2. foreach (IList<Autodesk.Revit.DB.BoundarySegment> bsList in room.GetBoundarySegments(new SpatialElementBoundaryOptions())) {
  3. foreach (Autodesk.Revit.DB.BoundarySegment segments in bsList) {
  4.      Wall wall = segments.Element as Wall;
  5.      Curve curve = (LocationCurve)wall.Location as LocationCurve.Curve;
  6.      TaskDialog.Show("Bsegments", e.Name + " " + curve.Length * SCALE + "\n");
  7.      }
  8. }
  9.  
Далее пытался в стене найти окна или двери, но вся проблема в том, что одна стена может учавствовать в построении нескольких комнат, и если я нахожу в стене окно, то не факт что оно будет в выбранной комнате.
А также длины стен комнаты не являются корректными (потому что получен id всей стены, а не конкретно сегмента).
Есть ли возможность выбрать все элементы вокруг комнаты и получить корректные длины сегментов стены?

Спасибо


Оффлайн Антон Останин

  • ADN OPEN
  • ***
  • Сообщений: 107
  • Карма: 6
Re: Получение всех объектов вокруг Room
« Ответ #1 : 12-12-2016, 18:05:29 »
Здравствуйте!
Попробуйте так:
Код - C# [Выбрать]
  1.                     SpatialElementGeometryCalculator calc = new SpatialElementGeometryCalculator(doc, new SpatialElementBoundaryOptions());
  2.                     SpatialElementGeometryResults results = calc.CalculateSpatialElementGeometry(room);
  3.                     var roomSolid = results.GetGeometry();
  4.                     foreach (Face face in roomSolid.Faces)
  5.                     {
  6.                         IList<SpatialElementBoundarySubface> subfaceList = results.GetBoundaryFaceInfo(face);
  7.                         foreach (SpatialElementBoundarySubface subface in subfaceList)                                              //Перебор всех прилегающих поверхностей к помещению
  8.                         {
  9.                            var area =  subface.GetSubface().Area;          //Площадь соприкосновения
  10.                         }
  11.                      }
  12.  

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

  • ADN Club
  • ***
  • Сообщений: 214
  • Карма: 5
  • Sergey
  • Skype: sergey.s.shevtsov
Re: Получение всех объектов вокруг Room
« Ответ #2 : 13-12-2016, 09:46:15 »
Спасибо, этот код подойдет для получения длины сегментов стены, но правда не всегда отрабатывает если нет соприкосновения со стеной.

Оффлайн Антон Останин

  • ADN OPEN
  • ***
  • Сообщений: 107
  • Карма: 6
Re: Получение всех объектов вокруг Room
« Ответ #3 : 13-12-2016, 09:52:31 »
Так это логично, если нет пересечения. :)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Получение всех объектов вокруг Room
« Ответ #4 : 24-12-2016, 23:26:14 »
Далее пытался в стене найти окна или двери, но вся проблема в том, что одна стена может учавствовать в построении нескольких комнат, и если я нахожу в стене окно, то не факт что оно будет в выбранной комнате.
Сергей, окна, двери и любые другие элементы, находящиеся на стене, фактически не являются границами стен. Антон подсказал веерный метод для обнаружения границ помещения.
Ты верно отметил, что окно или дверь, находящееся на стене, может быть и за пределами конкретной комнаты. Самый простой способ понять, принадлежит ли окно/дверь  конкретному помещению - проверить свойства FamilyInstance.FromRoom и FamilyInstance.ToRoom

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

  • ADN Club
  • ***
  • Сообщений: 214
  • Карма: 5
  • Sergey
  • Skype: sergey.s.shevtsov
Re: Получение всех объектов вокруг Room
« Ответ #5 : 18-04-2017, 13:27:33 »
Виктор, спасибо, за подсказку, с окнами и дверьми все получилось, обычным перебором и проверку свойства Room.
А как быть с потолком и полом, просто через соприкосновение с поверхностью я не могу определить тип объекта?

Отмечено как Решение shss 19-04-2017, 09:30:02

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Получение всех объектов вокруг Room
« Ответ #6 : 19-04-2017, 07:52:26 »
А как быть с потолком и полом, просто через соприкосновение с поверхностью я не могу определить тип объекта?
Разве? Я у себя применял подобное.
Вот метод для получения нижних границ помещения:
Код - C# [Выбрать]
  1.         IEnumerable<Element> GetRoomBottomBoundaElements(Document document,
  2.                 SpatialElementGeometryResults results,
  3.             Solid roomSolid)
  4.         {
  5.             foreach (Face face in roomSolid.Faces)
  6.             {
  7.                 var roomBoundaryFaceInfo =
  8.                     results.GetBoundaryFaceInfo(face);
  9.  
  10.                 Debug.Print("roomBoundaryFaceInfo: {0}", roomBoundaryFaceInfo.Count);
  11.  
  12.                 foreach (var info in roomBoundaryFaceInfo)
  13.                 {
  14.                     var type = info.SubfaceType;
  15.                     var linkedElementId = info.SpatialBoundaryElement;
  16.                     Element el = null;
  17.                     if (linkedElementId != null)
  18.                     {
  19.                         if (linkedElementId.HostElementId != ElementId.InvalidElementId)
  20.                         {
  21.                             el = document.GetElement(linkedElementId.HostElementId);
  22.                         }
  23.                     }
  24.                     if (el != null)
  25.                     {
  26.                         Debug.Print("{2} - [{0}] - {1}", el.Id.IntegerValue, el.Category.Name, type);
  27.                         if (info.SubfaceType == SubfaceType.Bottom)
  28.                         {
  29.                             yield return el;
  30.                         }
  31.                     }
  32.                     else
  33.                         Debug.Print("{0} - Not an element", type);
  34.                 }
  35.             }
  36.         }

Затем определить чем является элемент - не проблема. ПО категории например

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

  • ADN Club
  • ***
  • Сообщений: 214
  • Карма: 5
  • Sergey
  • Skype: sergey.s.shevtsov
Re: Получение всех объектов вокруг Room
« Ответ #7 : 19-04-2017, 09:31:30 »
Спасибо, этот вариант мне нравится больше, чем который я реализовал, используя нижние и верхние границы стен комнаты :)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: Получение всех объектов вокруг Room
« Ответ #8 : 19-04-2017, 09:40:36 »
shss, Пожалуйста. Только есть один момент, о котором нужно помнить. Чтобы данный метод работал, нужно, чтобы в настройках было задано вычисление Площади и Объема помещения. Если будет только площадь, то не корректно будет работать.

Оффлайн Антон Останин

  • ADN OPEN
  • ***
  • Сообщений: 107
  • Карма: 6
Re: Получение всех объектов вокруг Room
« Ответ #9 : 19-04-2017, 16:03:39 »
Либо можно самому включать это свойство и потом возвращать в исходное состояние.
Код - C# [Выбрать]
  1.        private void SetVolumesCompute(Document doc)
  2.         {
  3.             var settings = AreaVolumeSettings.GetAreaVolumeSettings(doc);
  4.             bool calcVolumes = settings.ComputeVolumes;                                     //состояние свойства
  5.             using (Transaction tr = new Transaction(doc, "Включение объемов"))
  6.             {
  7.                 tr.Start();
  8.                 settings.ComputeVolumes = true;  //включаем вычисление объемов
  9.                 tr.Commit();
  10.             }
  11.         }
  12.  

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

  • ADN Club
  • ***
  • Сообщений: 214
  • Карма: 5
  • Sergey
  • Skype: sergey.s.shevtsov
Re: Получение всех объектов вокруг Room
« Ответ #10 : 25-04-2017, 10:44:55 »
А как быть в случае если потолком является пол следующего этажа?
Мне кажется, что нет соприкосновения поверхностей, между Solid комнаты и Floor следующего этажа, потому что когда получаю
Код - C# [Выбрать]
  1. var type = info.SubfaceType;
Типа "Top" не появлется вообще.

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

  • ADN Club
  • ***
  • Сообщений: 214
  • Карма: 5
  • Sergey
  • Skype: sergey.s.shevtsov
Re: Получение всех объектов вокруг Room
« Ответ #11 : 25-04-2017, 11:12:24 »
Разобрался, необходимо выставить Upper Limit для Room, чтобы получить соприкосновение с Floor верхнего этажа.

Оффлайн Agens

  • ADN OPEN
  • ***
  • Сообщений: 223
  • Карма: 0
Re: Получение всех объектов вокруг Room
« Ответ #12 : 31-01-2020, 09:29:42 »
Раз разобрались, могли бы скинуть код... Я понимаю, что прошло 3 года, и вы прошли долгий путь, новичкам как :)
Вообще в API странная реализация BoundarySegment...
----
Стены, пол, кровлю возвратить получилось, но с окнами пока беда FamilyInstance.FromRoom возвращает null...

Виктор, спасибо, за подсказку, с окнами и дверьми все получилось, обычным перебором и проверку свойства Room.

Может кто подскажет направление?
----
BoundarySegment даст окно, которое может выходить за пределы помещения... (ерунду написал, окно не может принадлежать двум помещениям)... или нет? опять же вернутся все окна стены, которая принадлежит нескольким помещениям...
Просто считал теплопотери в Sancom, там такое возможно (окно делится стеной)...
----

« Последнее редактирование: 01-02-2020, 15:32:45 от Agens »
VS2019, VBA 7.1, VB.NET, C#, ACAD2019, Revit 2020

Оффлайн Agens

  • ADN OPEN
  • ***
  • Сообщений: 223
  • Карма: 0
Re: Получение всех объектов вокруг Room
« Ответ #13 : 01-02-2020, 17:30:17 »
Оказалось все проще:
Код - C# [Выбрать]
  1. Room room = window.get_Room(phase);
VS2019, VBA 7.1, VB.NET, C#, ACAD2019, Revit 2020

Оффлайн Agens

  • ADN OPEN
  • ***
  • Сообщений: 223
  • Карма: 0
Re: Получение всех объектов вокруг Room
« Ответ #14 : 01-02-2020, 19:56:23 »
Странно, дверь не обрабатывает!?
Код - C# [Выбрать]
  1. Room room = door.get_Room(phase);
возвращает nulll...
« Последнее редактирование: 01-02-2020, 21:28:28 от Agens »
VS2019, VBA 7.1, VB.NET, C#, ACAD2019, Revit 2020