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

ADN Club => Revit API => Тема начата: Александр Пекшев aka Modis от 23-05-2018, 12:14:17

Название: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 23-05-2018, 12:14:17
Всем привет. Изучаю информацию по поводу создания фасадов. Для создания фасадов нужно использовать метод ElevationMarker.CreateElevation(Document document, ElementId viewPlanId, int index), который принимает три параметра. С первыми двумя параметрами все понятно, но вот 3 параметр вызывает у меня конфуз. Я просто не понимаю как он работает.
В справке (http://www.revitapidocs.com/2017/ef15bad0-1f09-2a61-b74b-f4967137a47b.htm) написано:
Цитировать
The index on the ElevationMarker where the new elevation ViewSection will be placed. The index on the ElevationMarker must be valid and unused. View direction is determined by the index.
В базе знаний (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/Revit-API/files/GUID-776D3BC5-26A3-4D3C-A30C-9E9FD6552147-htm.html) написано:
Цитировать
The last parameter is the index on the ElevationMarker where the new elevation view will be placed. The index on the ElevationMarker must be valid and unused. The view's direction is determined by the index.
Но как его задавать я так и не понял. Может кто пояснить?
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Игнатович от 23-05-2018, 12:51:55
Немножко потестировал, если создать только ElevationMarker, тогда в интерфейсе появляется квадратик, с возможностью включить-выключить  виды с 4 сторон, при включении появляются соответствующие виды Elevation x - a, Elevation x - b и т.д.

Попробовал вот так на Iron Python:
Код - Python [Выбрать]
  1. tx = Transaction(doc, "ss")
  2. tx.Start()
  3.  
  4. em = ElevationMarker.CreateElevationMarker(doc, ElementId(69337), XYZ.Zero, 50)
  5.  
  6. for i in range(0, em.MaximumViewCount):
  7.         em.CreateElevation(doc, ElementId(13073), i)
  8.  
  9. tx.Commit()

создались все 4, итого:
0 - запад
1 - юг
2 - восток
3 - север

Это все на стандартном шаблоне. Вообще в API есть свойство MaximumViewCount, т.е., видимо, предполагается возможность не квадратных ElevationMarker
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 23-05-2018, 12:56:46
Александр Игнатович, я, в принципе, тоже так подумал. Но уже столкнулся с рядом вопросов:
1. Если попробовать не на стандартном шаблоне, а на проекте без шаблона, то этих самых квадратиков нет. И создать можно только фасад с индексом 0. Для всех последующих индексов выдается ошибка. От чего это может зависеть и как проверить? Думаю, это может быть связано с типоразмером фасада, а точнее с семейством, которое используется для "стрелочки". Тут в Ревите все так запутано...
2. Если я хочу создать фасад под углом - как тогда задавать индексы? Поворачивать марку фасада?
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Игнатович от 23-05-2018, 13:07:00
Повернуть можно после создания Elevation-ов, иначе игнорирует. На пустом проекте:

Код - Python [Выбрать]
  1. import math
  2.  
  3. tx = Transaction(doc, "ss")
  4. tx.Start()
  5.  
  6. em = ElevationMarker.CreateElevationMarker(doc, ElementId(1384), XYZ.Zero, 50)
  7.  
  8. for i in range(0, em.MaximumViewCount):
  9.         em.CreateElevation(doc, ElementId(1608), i)
  10.        
  11. doc.Regenerate()
  12.  
  13. ElementTransformUtils.RotateElement(doc, em.Id, Line.CreateUnbound(XYZ.Zero, XYZ.BasisZ), math.pi / 4.0)
  14.  
  15. tx.Commit()

Как настраивать ElevationMarker пока не знаю, посмотрю - отпишусь
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Игнатович от 23-05-2018, 13:24:16
Нда, довольно сложно.

Марки фасадов в проекте настраиваются тут: вкладка "Управление", Дополнительные параметры \ марки фасадов.

Там указывается "Марка отметки", это уже будет пользовательское семейство, собственно определяющее, как будет выглядеть Elevation Marker, категория семейства  - Марки отметок. Это семейство может иметь одно или несколько вложенных семейств той же категории, собственно, это количество и определяет сколько фасадов может иметь Elevation Marker. Порядок, похоже, определяется по id
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Игнатович от 23-05-2018, 13:39:42
Да, всё получилось, создал собственный Elevation Marker:

(https://s31.postimg.cc/pwiam3dif/image.png) (https://postimg.cc/image/pwiam3dif/)

Сначала создаем марку указателя, черный треугольник, выставляем значение "Указатель" параметра семейства "Использование марок отметок"

Потом создаем основное семейство, значение параметра "Использование марок отметок" оставляем как есть, загружаем семейство марки указателя и создаем N экземпляров

Загружаем семейство в проект, настраиваем системное семейство "Марка фасада", типоразмер системного семейства Фасад при необходимости, ну и дальше уже наслаждаемся собственным Elevation Marker-ом
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 23-05-2018, 14:22:06
Так, вроде все в голове сложилось более менее.
Сами марки фасадов в моём конкретном случае мне не важны, так как мне нужно будет для одной марки создавать один фасад. В будущем, когда начну делать развертки стен, уже пригодится эта информация. Хотя, и не факт - можно просто поставить 4 марки в одну точку. Только это не круто  :D

Получается, индекс мне нужно всегда задавать равным 0. Как я понимаю (чисто эмпирически) направление вида для индекса всегда показывает "вверх". Остается только высчитать на сколько повернуть марку фасада.

Касаемо поворота марки тоже важно - перед поворотом обязательно нужно вызвать doc.Regenerate(), иначе не поворачивается. Александр Игнатович, вы это учили в своём примере. Просто уточняю для тех, кто наткнется потом на эту тему
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 23-05-2018, 14:24:27
создались все 4, итого:
0 - запад
1 - юг
2 - восток
3 - север

Сейчас только заметил эту часть ответа и это - плохо! Плохо так как становится неясно какой индекс куда показывает. Как я писал выше - при моих тестах индекс 0 показывает на север
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Игнатович от 23-05-2018, 14:31:43
Вообще говоря, я бы при необходимости работы с ElevationMarker загружал бы в проект своё семейство, настраивал бы марку и свой ViewFamilyType для фасадов, только в этом случае можно с полной уверенностью сказать, что, например, "0 указывает на север", а "1 - на восток".

А зачем для развертки стен фасады? можно жеж разрезами обойтись. Кстати, планирую в скорости выложить свою реализацию развертки стен на github.
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 23-05-2018, 14:34:17
А зачем для развертки стен фасады? можно жеж разрезами обойтись. Кстати, планирую в скорости выложить свою реализацию развертки стен на github
Это пока только планы на будущее =)
Сейчас у меня совсем другая задача и нужны именно фасады. Буду методом научного тыка делать =) Если что интересное замечу - отпишусь в этой теме
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 25-05-2018, 11:05:21
На текущий момент - ничего хорошего я добиться не смог. Первая большая проблема с которой я столкнулся - невозможность повернуть маркер на 180 градусов. Ревит просто не позволяет этого сделать. Точнее - позволяет, но не поворачивает. Причем, если поставить маркер рядом со стенами, то и вручную его не повернуть (вообще никак). Но если маркер унести далеко от стен - то повернуть можно. Т.е. фасад "цепляется" к стенам или что-то типа того... Эххх... Буду биться дальше
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 26-05-2018, 10:03:40
В итоге: что это за индекс я в общем понял и марку я повернул. В моём случае изначально марка смотрит "вверх" (на север или ось Y), а повернуть мне нужно было чтобы она смотрела на стену с внешней стороны. Сделал так (с учётом проблемы поворота на 180 градусов):
Код - C# [Выбрать]
  1. var angle = wallOrientation.AngleTo(XYZ.BasisY);
  2.                     if (Math.Abs(wallOrientation.DotProduct(XYZ.BasisY) - 1) < 0.0001)
  3.                     {
  4.                         // lifehack =))
  5.                         ElementTransformUtils.RotateElement(doc, marker.Id, Line.CreateUnbound(markerPosition, XYZ.BasisZ), Math.PI / 2);
  6.                         ElementTransformUtils.RotateElement(doc, marker.Id, Line.CreateUnbound(markerPosition, XYZ.BasisZ), Math.PI / 2);
  7.                     }
  8.                     else if (Math.Abs(wallOrientation.DotProduct(XYZ.BasisY) - 1) > 0.0001)
  9.                     {
  10.                         if (wallOrientation.Y > 0.0)
  11.                         {
  12.                             if (wallOrientation.X > 0.0)
  13.                             {
  14.                                 ElementTransformUtils.RotateElement(doc, marker.Id, Line.CreateUnbound(markerPosition, XYZ.BasisZ),  -angle);
  15.                                 ElementTransformUtils.RotateElement(doc, marker.Id, Line.CreateUnbound(markerPosition, XYZ.BasisZ), Math.PI / 2);
  16.                                 ElementTransformUtils.RotateElement(doc, marker.Id, Line.CreateUnbound(markerPosition, XYZ.BasisZ), Math.PI / 2);
  17.                             }
  18.                             else ElementTransformUtils.RotateElement(doc, marker.Id, Line.CreateUnbound(markerPosition, XYZ.BasisZ),  Math.PI + angle);
  19.                         }
  20.                         else
  21.                         {
  22.                             if (wallOrientation.X > 0.0)
  23.                                 ElementTransformUtils.RotateElement(doc, marker.Id, Line.CreateUnbound(markerPosition, XYZ.BasisZ), Math.PI - angle);
  24.                             else ElementTransformUtils.RotateElement(doc, marker.Id, Line.CreateUnbound(markerPosition, XYZ.BasisZ), angle);
  25.                         }
  26.                     }
Думаю, не нужно объяснять что такое wallOrientation. На премию "идеальный код" не претендует, зато работает как надо

Единственна проблема остается в том, что изначально никак не узнаешь в какую сторону по умолчанию "смотрит" марка фасада. Т.е. универсально не сделать - только под конкретную марку.

Дальше буду ломать голову с заданием границ вида для фасада (с учётом поворота). Но это уже тема другого вопроса.

Александр Игнатович, спасибо за участие
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Игнатович от 28-05-2018, 10:38:31
Ещё вариант, кстати, есть. После создания вида
Код - C# [Выбрать]
  1. var viewSection = elevationMaker.CreateElevation(document, planViewId, idx)

Проверить viewSection.ViewDirection. Можно работать во временной транзакции, aka temporary transaction trick, либо просто удалять viewSection, если он по каким-то причинам не подходит. В этом случае document.Regenerate() можно не вызывать.
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 28-05-2018, 10:51:45
Александр Игнатович, думаю, не нужно. Методом тыка я нашел то, что, как мне кажется, самое оно:
1. Для задания глубины вида использовать методы GetDepthCueing (http://www.revitapidocs.com/2017/e60cb801-5a19-1fd7-6a44-0751cf87f162.htm) и, соответственно, SetDepthCueing (http://www.revitapidocs.com/2017/1fce2f87-4d7d-e060-06c0-220c9d385763.htm). Там правда задается в процентах. Хотя можно тупо просто задать значение параметра ))
(https://s33.postimg.cc/ymah4ppuj/image.png) (https://postimg.cc/image/ymah4ppuj/)
2. Для задания положения фасада (той самой синей полоски) нужно использовать ViewCropRegionShapeManager (http://www.revitapidocs.com/2017/2610cb66-5dae-9fc8-4e83-7dfe88085abb.htm), получаемый методом GetCropRegionShapeManager (http://www.revitapidocs.com/2017/e2f53728-9b72-227a-f585-9dccf6d79d9f.htm).

Я это еще все не пробовал (сегодня вот как раз начал), но судя по названиям и описанию - это то, что нужно. Правда методы из п.1 доступны только с 2017 Ревита.

В интернете находил какие-то темы, где использовали свойство CropBox, но потыкавшись с ним ни к чему полезному не пришёл
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Игнатович от 28-05-2018, 10:56:50
Так то вопрос об ориентации вида был, с размерами и подрезкой понятное дело.

Кстати, задать глубину вида проще всего через параметер Смещение дальнего предела секущего диапазона (BuiltInParameter.VIEWER_BOUND_OFFSET_FAR)
Название: Re: ElevationMarker.CreateElevation - что за параметр индекс?
Отправлено: Александр Пекшев aka Modis от 28-05-2018, 10:59:23
Так то вопрос об ориентации вида был
Ааааа! Я не сразу понял)) Голова забита другими проблемами ))
Да, хорошая идея. Если будет необходимость, то её и попробую. Можно все и в одной транзакции делать и похоже даже регенерация не нужна