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

ADN Club => Revit API => Тема начата: Alexander от 18-11-2013, 09:36:25

Название: Параметры в спецификации
Отправлено: Alexander от 18-11-2013, 09:36:25
Доброго времени суток!

Возможно ли при создании спецификации самому задать параметры в столбцах?
Например, чтобы уровень был в отдельном столбце. 

Спасибо!
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 18-11-2013, 09:55:17
Александр, добрый день.

С помощью API вы сможете сделать не более чем пользователь может делать в интерфейсе.

Для ответа на ваш вопрос, нужно уточнить пару моментов:
1) Вы создаете спецификацию с помощью API с нуля или редактируете существующую?
2) Я правильно понимаю, что вы хотите добавить новое поле спецификации из произвольного параметра, при этом параметр вы хотите создать так же программно?
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs15.postimg.org%2Fexwxcu5dj%2Fimage.jpg&hash=45b6be79da8fa93321fa6e9241fef27e) (http://postimg.org/image/exwxcu5dj/)
Название: Re: Параметры в спецификации
Отправлено: Alexander от 18-11-2013, 10:39:54
Виктор,
я создаю спецификацию с нуля.
Да, параметр я хочу создать программно.

Насколько я понимаю, семейство вместо параметра вставить не получится. Например, какую-нибудь дверь засунуть не в саму таблицу, а в её шапку.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 18-11-2013, 13:14:08
Александр,

Программно добавить новое поле в спецификацию можно с помощью метода ScheduleDefinition.AddField().

Чтобы добавить параметр, нужно воспользоваться одним из перегруженных методов и передать еще и идентификатор параметра, который вы хотите вывести.

Например, следующий код добавит в спецификацию поле Семейство и типоразмер в спецификацию.
definition.AddField(ScheduleFieldType.Instance, new ElementId(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM));
Если же вы хотите добавить в спецификацию значение собственного параметра, то вам нужно найти идентификатор вашего параметра. Чуть позже найду способ как его найти.

А создавать программно сам параметр вы уже научились?
Кстати не совсем ясно зачем вам создавать параметр при создании спецификцаии. Значение этого параметра ведь будет пустым.
Название: Re: Параметры в спецификации
Отправлено: Alexander от 18-11-2013, 15:50:22
Виктор,

У меня есть несколько уровней, на каждом уровне объекты. Если я строю таблицу и использую AddField(schedulableField.instance), то он выдаёт определённый набор параметров. Я хочу чтобы каждый уровень был в шапке(например 1, 2, 3 и т.д. этаж).
Поэтому думал создать параметр в качестве уровня.

А параметр , насколько понимаю, создаётся с помощью sharedparameter.

Для наглядности таблица их excel(4, 0 это уровни):
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs17.postimg.org%2Fpv51tbkq3%2Fexcel.jpg&hash=e82af926befaf018bfd5e25346c291ed) (http://postimg.org/image/pv51tbkq3/)
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 18-11-2013, 16:22:24
Чтож, с шаблоном стало более понятно.
Если 0.0 и 4.0 - это шапка, соответствующая уровню, то что означают цифры 26,4 и 70,8?

В теории такую спецификацию создать можно. Но для этого нужно будет создать столько дополнительных параметров, сколько у вас есть уровней. Эти параметры будут видны у каждого объекта. Судя по всему значение большей части этих параметров будет пустым.

Хотелось бы получить более детальное описание желаемой спецификации. Какое будет значение у общих параметров?
Название: Re: Параметры в спецификации
Отправлено: Alexander от 18-11-2013, 16:42:26
Эти цифры - это площадь стен. Каждая строка в таблице это какая-то стена.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 18-11-2013, 17:13:24
То есть вам нужно создать спецификацию площади каждой стены на каждом из уровней.

Подобную спецификацию создать программно можно.
Алгоритм следующий:

Самое трудное в этом алгоритме - это рассчитать площадь стен на каждом из уровней.
Второй момент - определение идентификатора параметра, который нужен при создании поля спецификации.
Его можно получить так. Выбираем первую попавшуюся стену в проекте. Находим параметр, содержащий значение площади поверхности стены на определенном уровне. Берем свойство Id этого параметра.
Код - C# [Выбрать]
  1.             FilteredElementCollector filteredElementCollector =
  2.                 new FilteredElementCollector(doc);
  3.  
  4.             var firstWall = filteredElementCollector.OfClass(typeof (Wall)).FirstElement() as Wall;
  5.  
  6.             if (firstWall == null)
  7.             {
  8.                 message = "В проекте нет стен";
  9.                 return Result.Failed;              
  10.             }
  11.  
  12.             var level0Param = firstWall.get_Parameter("Уровень 0.0");
  13.  
  14.             var level0ParamId = level0Param.Id;

Но для начала я бы рекомендовал создать сначала параметры и рассчитать площдь стен. Имея эти данные спецификацию можно попробовать и вручную создать.
Название: Re: Параметры в спецификации
Отправлено: Alexander от 18-11-2013, 17:25:14
Спасибо за ответ.

Мне нужно в разных столбцах выполнять подсчёт площадей стен расположенных на разных этажах, но имеющих один типоразмер. Первый столбец для 1 этажа, 2 для 2 и т.д. , а последний столбец - итого по всем этажам.
В Ревите можно сформировать подсчёт площадей по строкам, но не по столбцам.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 18-11-2013, 17:37:38
То есть в вашем случае стена будет находиться только на одном уровне? Если так, то площадь посчитать проще. В любом случае если вы хотите по столбцам, то нужно создавать доп. параметры и сделать по приведенному алгоритму.
Название: Re: Параметры в спецификации
Отправлено: Alexander от 19-11-2013, 09:13:07
Нет, несколько стен на разных уровнях.
Спасибо за предоставленное решение.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 19-11-2013, 09:42:37
В дополнение хочу добавить. Так как для каждой стены будет множество параметров с площадью стен на каждом уровне, которые по сути нужны только для спецификации и пользователю не обязательно их видеть в свойствах стены, то программно можно создать скрытые параметры. Пользователь их не будет видеть окне свойств объекта, но для спецификации эти параметры можно будет использовать.

Ну и если уж совсем идти до конца и решить задачу полностью, то нужно еще отслеживать изменение размера стены и при изменении перезаписывать значение параметров, содержащих площадь поверхности стены.
Название: Re: Параметры в спецификации
Отправлено: Alexander от 09-12-2013, 15:13:37
Добрый день.

Виктор, в продолжении темы хотел поинтересоваться расчётом площади.
Пытаюсь сделать подобным образом:
Код - C# [Выбрать]
  1. FilteredElementCollector filteredElementCollectorWall = new FilteredElementCollector(document);
  2. var wall = filteredElementCollectorWall.OfClass(typeof(Wall)).FirstElement() as Wall;
  3. Parameter widthParam = wall.get_Parameter("Ширина1");
  4. double widthValue = widthParam.AsDouble();
  5. Parameter heightParam = wall.get_Parameter("Длина1");
  6. double heightValue = heightParam.AsDouble();
  7. double areaValue = widthValue * heightValue;
  8. wall.get_Parameter("Площадь_стены").Set(areaValue);
                   

Площадь не считает, может где-то ошибка?
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 09-12-2013, 15:36:47
Александр,
для начала нужно посмотреть значения переменных widthValue и heightValue после того как вы получили их значения из параметров. Поставьте  точку остановки на 7 линии (7 по коду в вашем посте) и в дебагере посмотрите чему равны значения.

Параметры Ширина1 и Длина1 точно имеют тип Double? Проверьте чему равно свойство widthParam.StorageType и heightParam.StorageType

И естественно нужно убедиться что стена, возвращаемая с помощью метода
Код - C# [Выбрать]
  1. var wall = filteredElementCollectorWall.OfClass(typeof(Wall)).FirstElement() as Wall;
содержит не нулевые значение параметров Ширина1 и Длина1
Название: Re: Параметры в спецификации
Отправлено: Alexander от 09-12-2013, 16:12:55
Виктор,
спасибо за быстрый ответ.

Проверил все действия, также пробовал менять double на int (и в коде и параметры проекта).
Всё равно не считает.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 09-12-2013, 16:21:41
Давайте тогда определимся что значит "не считает". Посчитать площадь прямоугльника - это простая арифметическая операция умножения и ошибиться тут сложно. Если переменные не равны 0, то значение площади в любом случае посчитается.

Все же скажите мне чему равны переменные widthValue, heightValue и areaValue?

Или площадь же считается, но не происходит сохранение площади в параметр Площадь_стены?
Название: Re: Параметры в спецификации
Отправлено: Alexander от 09-12-2013, 16:32:11
widthValue и  heightValue равны 5 и 6. В дебагере также отображается. areaValue - просто пустое поле(в дебагере 0)
Ширина1, Длина1 и Площадь_стены это общие параметры созданные вручную в revit
Название: Re: Параметры в спецификации
Отправлено: Alexander от 09-12-2013, 16:40:40
Виктор,
areaValue считает в дебагере, но не записывает в Revit
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 09-12-2013, 16:44:48
Уже интереснее. Т.е. выходит что операции умножения не просходит.
Я как то сталкивался с таким, что дебагер показывает неверное значение. Скорее всего это глюк дебагера.

У меня есть подозрение что ошибка в записи результата в параметр (8 строка).
После выполнения вашего когда, чему равен параметр Площадь_стены в интерфейсе?

Попробуйте исправить код вот так:
Код - C# [Выбрать]
  1.             bool res = wall.get_Parameter("Площадь_стены").Set(areaValue);
  2.  
  3.             TaskDialog.Show("Тест", string.Format("Ширина: {0}\r\nДлина: {1}\r\nПлощадь: {2}\r\nРезультат: {3}",
  4.                 widthValue,
  5.                 heightValue,
  6.                 areaValue,
  7.                 res));
  8.  

Выполните и скажите что поулчилось.
Название: Re: Параметры в спецификации
Отправлено: Alexander от 09-12-2013, 16:59:36
Дебагер считает, ваш код также возвращает правильное значение.
Не записывает значение в параметр Площадь_стены
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 09-12-2013, 17:18:17
Как я и думал. Подвох именно в записи параметра.
Проверьте тип параметра Площадь_стены. В интерфейсе вы в этот параметр можете записать значение?

Ради эксперимента попробуйте заменить .Set(areaValue); на .Set(areaValue.ToString()); и на .SetValueString(areaValue.ToString());

Транзакция как открывается: автоматически или вручную?

Название: Re: Параметры в спецификации
Отправлено: Alexander от 09-12-2013, 17:23:13
В интерфейсе значения записываются, формулы считаются.
Приведение к строке также не помогло.

Транзакция вручную.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 09-12-2013, 17:30:05
В таком случае хочется видеть весь код внешней команды, где вы записываете площадь в параметр.
Название: Re: Параметры в спецификации
Отправлено: Alexander от 10-12-2013, 10:32:50
Помимо площади там создаётся таблица, но создание полей для неё я закомментил.
 
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 10-12-2013, 11:13:06
Попробовал выполнить. Вот такой код у меня сработал
Код - C# [Выбрать]
  1.             double heightValue = heightParam.AsDouble();
  2.             double areaValue = widthValue * heightValue;
  3.             var res = wall.get_Parameter("Площадь_стены2").Set(areaValue);

Результат равен true.
Тип параметров Длина2 и Ширина2 - Длина.
Тип параметра Площадь_стены2 - Площадь.

Заметил правда вот что. Если Длина2 = 6 и Ширина2 = 5, то площадь будет равна 0.
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs29.postimg.org%2Fiptv9utir%2Fimage.jpg&hash=d6a303128a0da1d9efd606e002d7b680) (http://postimg.org/image/iptv9utir/)
Все дело в том, что по умолчанию длина и ширина устанавливается в миллиметрах, а площадь - в квадратных метрах. Т.е. площадь просто очень маленькая.

Попробуйте код, что я привел выше. Чему равна переменная res? Чему равно значение параметра Площадь_стуны в интерфейсе после этого?

На всякий случай - какую версию Revit используете?

Название: Re: Параметры в спецификации
Отправлено: Alexander от 10-12-2013, 13:03:17
res выдаёт false,а revit 2014.
А компилятор считает площадь правильно, но переводит значения в дюймы.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 10-12-2013, 13:25:51
Попробуйте на вот этом проекте.
Я также в 2014 Ревите пробовал.
Название: Re: Параметры в спецификации
Отправлено: Alexander от 10-12-2013, 13:42:13
В вашем проекте считает
res - false
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 10-12-2013, 13:51:04
В этом случае становится ситуация становится еще более непонятной.

Попробуйте еще тогда с моей надстройкой.

Название: Re: Параметры в спецификации
Отправлено: Alexander от 10-12-2013, 14:14:36
Ваш так же считает правильно, но res по-прежнему false.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 10-12-2013, 14:28:34
Прямо мистика какая то.

Последнее что еще могу предложить, выполните простую команду, в которой не производится больше никаких действий, кроме как обновление параметра:
Код - C# [Выбрать]
  1.         public Result Execute(
  2.           ExternalCommandData commandData,
  3.           ref string message,
  4.           ElementSet elements)
  5.         {
  6.             UIApplication uiapp = commandData.Application;
  7.             UIDocument uidoc = uiapp.ActiveUIDocument;
  8.             Application app = uiapp.Application;
  9.             Document doc = uidoc.Document;
  10.  
  11.             FilteredElementCollector filteredElementCollectorWall = new FilteredElementCollector(doc);
  12.             var wall = filteredElementCollectorWall.OfClass(typeof(Wall)).FirstElement() as Wall;
  13.             Parameter widthParam = wall.get_Parameter("Ширина2");
  14.             double widthValue = widthParam.AsDouble();
  15.             Parameter heightParam = wall.get_Parameter("Длина2");
  16.             double heightValue = heightParam.AsDouble();
  17.             double areaValue = widthValue * heightValue;
  18.             using (Transaction t = new Transaction(doc, "Обновление параметра"))
  19.             {
  20.                 t.Start();
  21.                 var res = wall.get_Parameter("Площадь_стены2").Set(areaValue);
  22.                 t.Commit();
  23.  
  24.                 TaskDialog.Show("Запись значения в параметр", res.ToString());
  25.             }
  26.            
  27.  
  28.             return Result.Succeeded;
  29.         }

Также после выполнения команды вышлите мне файл журнала.
Он находится в папке C:\Users\<username>\AppData\Local\Autodesk\Revit\<Ваша версия ревит>\Journals. Мне нужен текстовый файл вида journal.XXXX.txt, где XXXX самый последний порядковый номер.

Есть ли у вас возможность проверить выполнение команды на другой версии Revit или еще лучше на другом компьютере?
Название: Re: Параметры в спецификации
Отправлено: Alexander от 10-12-2013, 15:08:23
Код возвратил true.
Также я вставил TaskDialog в свой проект и он тоже возвратил true. Но в параметр ответ не записывает(в моём проекте).
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 10-12-2013, 15:21:55
Код возвратил true.
Параметр при этом изменился в интерфейсе? Если в вашем не изменился, то изменился ли в моем простеньком проекте?
Название: Re: Параметры в спецификации
Отправлено: Alexander от 10-12-2013, 15:28:52
В моём нет,пустое поле.
В вашем да. 0 или больше, если увеличить ширину и длину.

В моём проекте несколько стен,у каждой Ширина2 = 5, Длина2= 6.

Так же , если я открываю другие проекты(примеры Ревит), и присваиваю такие же параметры для стен, то и там параметр не меняется в интерфейсе.
Название: Re: Параметры в спецификации
Отправлено: Виктор Чекалин от 10-12-2013, 15:38:55
В моём проекте несколько стен,у каждой Ширина2 = 5, Длина2= 6.

Так же , если я открываю другие проекты(примеры Ревит), и присваиваю такие же параметры для стен, то и там параметр не меняется в интерфейсе.

Так ведь код то меняет значение площади только для одной, первой попавшейся стены, а не у всех стен. А вы в интерфейсе выбираете скорее всего другую стену, не ту у которой меняли параметр.

Чтобы изменить параметр у всех стен вам нужен вот такой код:
Код - C# [Выбрать]
  1.  
  2.             FilteredElementCollector filteredElementCollectorWall = new FilteredElementCollector(doc);
  3.             var walls = filteredElementCollectorWall.OfClass(typeof(Wall));
  4.             using (Transaction t = new Transaction(doc, "Обновление параметра"))
  5.             {
  6.                 t.Start();
  7.  
  8.                 foreach (Wall wall in walls)
  9.                 {
  10.                     Parameter widthParam = wall.get_Parameter("Ширина2");
  11.                     double widthValue = widthParam.AsDouble();
  12.                     Parameter heightParam = wall.get_Parameter("Длина2");
  13.                     double heightValue = heightParam.AsDouble();
  14.                     double areaValue = widthValue * heightValue;
  15.                    
  16.                     var res = wall.get_Parameter("Площадь_стены2").Set(areaValue);
  17.                    
  18.                     Debug.Print("Стена: {0}; Результат: {1}", wall.Id, res);
  19.                 }
  20.  
  21.                 t.Commit();
  22.             }
Название: Re: Параметры в спецификации
Отправлено: Alexander от 10-12-2013, 15:47:33
Да, в таком случае всё работает.
Спасибо!