Добавление материалов из списка
Еще в далеком 2011 году мы обсуждали как импортировать материалы из файла Excel в Revit.
Входные данные хранились в файле Excel и содержали следующие параметры:
Наименование
- Код
- Название
- Сила
Графика
- Цвет в RGB
- Прозрачность
- Штриховка разреза
- Штриховка поверхности
Идентификация
- Класс
- Информация о продукте
- Пользовательские параметры
У пользователя была проблема, что он не мог добраться программно создать материал с заданным классом.
В итоге поступили следующим образом:
- Создали в интерфейсе Revit список предопределенных материалов с нужным классом, где название материала совпадало с названием класса
- При импорте искали материал с нужным названием и копировали его. Тем самым и создавали новый материал с нужным классом
Надстройка была реализована для Revit 2011 и Revit API уже изменилось с тех пор и поэтому надстройка немного изменилась.
Вот список методов, которые необходимо изменить для Revit API 2014.
- Использовать FilteredElementCollector для доступа к материалам и штриховкам и LINQ для создания словаря соответствия имени материала с самим объектом материалом.
- Цвет необходимо задавать в конструкторе класса Color.
- Установить штриховку поверхности материала и разреза с помощью ElementId.
Так же я немного почистил и оптимизировал код.
Помимо этого, я внес изменения в вывод итогового сообщения, добавив информацию о том, сколько материалов было фактически добавлено.
Первоначальная реализация обновления имела баг с обработкой штриховки. Так как файл Excel для некоторых позиций содержит значение N/A, то естественно, что штриховки с таким именем нет и поэтому выдавалась ошибка.
Я подправил код и добавил проверку на значение N/A:
- const string _not_available = "N/A";
- if( 0 < surPattern.Length
- && !surPattern.Equals( _not_available ) )
- {
- myMaterial.SurfacePatternId
- = fillPatterns[surPattern].Id;
- }
- if( 0 < cutPattern.Length
- && !cutPattern.Equals( _not_available ) )
- {
- myMaterial.CutPatternId
- = fillPatterns[cutPattern].Id;
- }
Однако все же осталась не решенная проблема: если количество добавленных материалов меньше, чем количество обработанных строк, то по какой-то причине не все материалы были добавлены. Пользователь же так и не узнает причину.
Так что имейте ввиду, что возможно вам придется доработать код, если потребуется.
Я все же решил внести небольшое изменение и добавил название материалов, которые были добавлены, вместо простого отображения количества.
В результате я могу получить вот такой отчет:
Конечно, пользователь все еще не знает в этом случае причину не добавления материала, но то что выводится список добавленных материалов – уже не плохо.
И, в завершение, полный код команды:
- [Transaction( TransactionMode.Manual )]
- public class Command : IExternalCommand
- {
- const string _not_available = "N/A";
- const string _input_file_name = "C:/RevitAPI/MaterialList.xlsx";
- static string PluralSuffix( int i )
- {
- return 1 == i ? "" : "s";
- }
- public Result Execute(
- ExternalCommandData commandData,
- ref string message,
- ElementSet elements )
- {
- UIApplication uiapp = commandData.Application;
- UIDocument uidoc = uiapp.ActiveUIDocument;
- Document doc = uidoc.Document;
- // Создаем слоарь с сопоставлением названия материлов, объекту материала
- Dictionary<string, Material> materials
- = new FilteredElementCollector( doc )
- .OfClass( typeof( Material ) )
- .Cast<Material>()
- .ToDictionary<Material, string>(
- e => e.Name );
- // То же и для штирховок.
- Dictionary<string, FillPatternElement> fillPatterns
- = new FilteredElementCollector( doc )
- .OfClass( typeof( FillPatternElement ) )
- .Cast<FillPatternElement>()
- .ToDictionary<FillPatternElement, string>(
- e => e.Name );
- try
- {
- Excel.Application excel
- = new Excel.Application();
- excel.Visible = false;
- Excel.Workbook workbook = excel.Workbooks.Open(
- _input_file_name, 0, true, 5, "", "", true,
- Excel.XlPlatform.xlWindows, "\t", false,
- false, 0, true, 1, 0 );
- Excel.Worksheet worksheet = (Excel.Worksheet)
- workbook.Worksheets.get_Item( 1 );
- Excel.Range range = worksheet.UsedRange;
- int nRows = 0;
- List<string> materials_added = new List<string>();
- int iRow = 5;
- using( Transaction tx = new Transaction( doc ) )
- {
- tx.Start( "Добавление материала" );
- while( null != range.Cells[iRow, 1].Value2 )
- {
- string matName = (string) range.Cells[iRow, 1].Value2;
- matName += " " + (string) range.Cells[iRow, 2].Value2;
- matName += " " + (string) range.Cells[iRow, 3].Value2;
- if( matName != null )
- {
- double red = (double) range.Cells[iRow, 4].Value2;
- double green = (double) range.Cells[iRow, 5].Value2;
- double blue = (double) range.Cells[iRow, 6].Value2;
- double transparency = (double) range.Cells[iRow, 8].Value2;
- string surPattern = (string) range.Cells[iRow, 9].Value2;
- string cutPattern = (string) range.Cells[iRow, 10].Value2;
- // Ищем материал для копирования
- string CSI = (string) range.Cells[iRow, 11].Value2;
- if( materials.ContainsKey( CSI ) )
- {
- Material materialCSI = materials[CSI];
- Material myMaterial
- = materialCSI.Duplicate( matName );
- Color matColor = new Color(
- Byte.Parse( red.ToString() ),
- Byte.Parse( green.ToString() ),
- Byte.Parse( blue.ToString() ) );
- myMaterial.Color = matColor;
- myMaterial.Transparency
- = (int) transparency;
- if( 0 < surPattern.Length
- && !surPattern.Equals( _not_available ) )
- {
- myMaterial.SurfacePatternId
- = fillPatterns[surPattern].Id;
- }
- if( 0 < cutPattern.Length
- && !cutPattern.Equals( _not_available ) )
- {
- myMaterial.CutPatternId
- = fillPatterns[cutPattern].Id;
- }
- materials_added.Add( matName );
- }
- }
- ++nRows;
- ++iRow;
- }
- tx.Commit();
- }
- workbook.Close( true, null, null );
- excel.Quit();
- int n = materials_added.Count;
- string msg = string.Format(
- "{0} строк обработано "
- + "{1} материалов добавлено:",
- nRows, n );
- TaskDialog dlg = new TaskDialog(
- "Добавление материалов" );
- dlg.MainInstruction = msg;
- dlg.MainContent = string.Join( ", ",
- materials_added ) + ".";
- dlg.Show();
- return Result.Succeeded;
- }
- catch( Exception ex )
- {
- message = "Revit AddMaterials Exception:\n"
- + ex.ToString();
- return Result.Failed;
- }
- }
- }
Код с проектом для Visual Studio доступен на GitHub.
Источник: http://thebuildingcoder.typepad.com/blog/2010/08/add-new-materials-from-list.html#2
http://thebuildingcoder.typepad.com/blog/2014/03/adding-new-materials-from-list-updated.html
http://thebuildingcoder.typepad.com/blog/2014/03/adding-new-materials-from-list-updated-again.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=678
Опубликовано 14.04.2014