ElevationMarker.CreateElevation - что за параметр индекс?

Автор Тема: ElevationMarker.CreateElevation - что за параметр индекс?  (Прочитано 4360 раз)

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

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет. Изучаю информацию по поводу создания фасадов. Для создания фасадов нужно использовать метод ElevationMarker.CreateElevation(Document document, ElementId viewPlanId, int index), который принимает три параметра. С первыми двумя параметрами все понятно, но вот 3 параметр вызывает у меня конфуз. Я просто не понимаю как он работает.
В справке написано:
Цитировать
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.
В базе знаний написано:
Цитировать
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.
Но как его задавать я так и не понял. Может кто пояснить?

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Немножко потестировал, если создать только 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

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Александр Игнатович, я, в принципе, тоже так подумал. Но уже столкнулся с рядом вопросов:
1. Если попробовать не на стандартном шаблоне, а на проекте без шаблона, то этих самых квадратиков нет. И создать можно только фасад с индексом 0. Для всех последующих индексов выдается ошибка. От чего это может зависеть и как проверить? Думаю, это может быть связано с типоразмером фасада, а точнее с семейством, которое используется для "стрелочки". Тут в Ревите все так запутано...
2. Если я хочу создать фасад под углом - как тогда задавать индексы? Поворачивать марку фасада?

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Повернуть можно после создания 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 пока не знаю, посмотрю - отпишусь

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Нда, довольно сложно.

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

Там указывается "Марка отметки", это уже будет пользовательское семейство, собственно определяющее, как будет выглядеть Elevation Marker, категория семейства  - Марки отметок. Это семейство может иметь одно или несколько вложенных семейств той же категории, собственно, это количество и определяет сколько фасадов может иметь Elevation Marker. Порядок, похоже, определяется по id

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Да, всё получилось, создал собственный Elevation Marker:



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

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

Загружаем семейство в проект, настраиваем системное семейство "Марка фасада", типоразмер системного семейства Фасад при необходимости, ну и дальше уже наслаждаемся собственным Elevation Marker-ом

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Так, вроде все в голове сложилось более менее.
Сами марки фасадов в моём конкретном случае мне не важны, так как мне нужно будет для одной марки создавать один фасад. В будущем, когда начну делать развертки стен, уже пригодится эта информация. Хотя, и не факт - можно просто поставить 4 марки в одну точку. Только это не круто  :D

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

Касаемо поворота марки тоже важно - перед поворотом обязательно нужно вызвать doc.Regenerate(), иначе не поворачивается. Александр Игнатович, вы это учили в своём примере. Просто уточняю для тех, кто наткнется потом на эту тему

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
создались все 4, итого:
0 - запад
1 - юг
2 - восток
3 - север

Сейчас только заметил эту часть ответа и это - плохо! Плохо так как становится неясно какой индекс куда показывает. Как я писал выше - при моих тестах индекс 0 показывает на север

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Вообще говоря, я бы при необходимости работы с ElevationMarker загружал бы в проект своё семейство, настраивал бы марку и свой ViewFamilyType для фасадов, только в этом случае можно с полной уверенностью сказать, что, например, "0 указывает на север", а "1 - на восток".

А зачем для развертки стен фасады? можно жеж разрезами обойтись. Кстати, планирую в скорости выложить свою реализацию развертки стен на github.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
А зачем для развертки стен фасады? можно жеж разрезами обойтись. Кстати, планирую в скорости выложить свою реализацию развертки стен на github
Это пока только планы на будущее =)
Сейчас у меня совсем другая задача и нужны именно фасады. Буду методом научного тыка делать =) Если что интересное замечу - отпишусь в этой теме

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
На текущий момент - ничего хорошего я добиться не смог. Первая большая проблема с которой я столкнулся - невозможность повернуть маркер на 180 градусов. Ревит просто не позволяет этого сделать. Точнее - позволяет, но не поворачивает. Причем, если поставить маркер рядом со стенами, то и вручную его не повернуть (вообще никак). Но если маркер унести далеко от стен - то повернуть можно. Т.е. фасад "цепляется" к стенам или что-то типа того... Эххх... Буду биться дальше

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
В итоге: что это за индекс я в общем понял и марку я повернул. В моём случае изначально марка смотрит "вверх" (на север или ось 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. На премию "идеальный код" не претендует, зато работает как надо

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

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

Александр Игнатович, спасибо за участие

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Ещё вариант, кстати, есть. После создания вида
Код - C# [Выбрать]
  1. var viewSection = elevationMaker.CreateElevation(document, planViewId, idx)

Проверить viewSection.ViewDirection. Можно работать во временной транзакции, aka temporary transaction trick, либо просто удалять viewSection, если он по каким-то причинам не подходит. В этом случае document.Regenerate() можно не вызывать.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Александр Игнатович, думаю, не нужно. Методом тыка я нашел то, что, как мне кажется, самое оно:
1. Для задания глубины вида использовать методы GetDepthCueing и, соответственно, SetDepthCueing. Там правда задается в процентах. Хотя можно тупо просто задать значение параметра ))

2. Для задания положения фасада (той самой синей полоски) нужно использовать ViewCropRegionShapeManager, получаемый методом GetCropRegionShapeManager.

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

В интернете находил какие-то темы, где использовали свойство CropBox, но потыкавшись с ним ни к чему полезному не пришёл

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Так то вопрос об ориентации вида был, с размерами и подрезкой понятное дело.

Кстати, задать глубину вида проще всего через параметер Смещение дальнего предела секущего диапазона (BuiltInParameter.VIEWER_BOUND_OFFSET_FAR)