using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.UI.Selection;
[Transaction(TransactionMode.Manual)]
public class swaat : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication rvtUiApp = commandData.Application;
Application rvtApp = rvtUiApp.Application;
UIDocument rvtUiDoc = rvtUiApp.ActiveUIDocument;
Document rvtDoc = rvtUiDoc.Document;
{
var element = rvtUiDoc.Selection.GetElementIds();
var lst_ = new List<string>();
foreach (var elem in rvtUiDoc.Selection.GetElementIds())
foreach (var bic in Enum.GetValues(typeof(BuiltInCategory)))
{
if (rvtDoc.GetElement(elem).Category.Id.IntegerValue == (int)bic)
{
lst_.Add(rvtDoc.GetElement(elem).Category.Name.ToString());
lst_.Add(bic.ToString());
lst_.Add(rvtDoc.GetElement(elem).LookupParameter("Комментарии").AsString());
}
};
TaskDialog.Show("Bic", string.Join(" ;", lst_));
}
return Result.Succeeded;
}
}
Делая вариант с переводом в String даже не обратил внимание, что диаметры фитингов возвращаются как “65,000”, а в Исходном списке у меня числа в формате “65” (после String.ToNumber). Неужели из-за этого нод List.ContainsItem считает, что эти 2 числа (будучи ЧИСЛАМИ) не идентичны? Бред же…
@txt, сначала думал, что вы мне предлагаете практически то же, что у меня. Но потом заметил Питон-код. Протестировал. Оказалось, что float(i) переводит в число более правильно, чем String.ToNumber. Хотя оба являются числами. После float(i) уже можно сравнивать в List.ContainsItem как надо! Большое спасибо за опыт!
Мда.. Недолго радовался… Теперь ситуация ещё загадочней. Трубы Ду65 обрабатываются как надо, а Ду15 – нет. При том, что теперь числа выглядят правильно во всех отношениях о_О. Ладно, проще забить на это. Тут явно глюк внутри Dynamo (версия 1.2.1). Строками хоть задача решена.
В скрипте (ссылка прилагается) фильтрую врезки труб по указанным диаметрам.
В нод List.ContainsItem приходят числа на оба входа (даже проверял суммированием). Но нод выдает неправильный результат (в моем случае false вместо true). Тут же (ниже, в отдельной группе) делаю тестирование нода – подаю на входы 2 списка чисел – нод работает правильно.
Ром,
я ранее как-то пытался сделать нодами что-то подобное , но безуспешно. В принципе ваше решение, на мой взгляд, выглядит логичным) Однако по факту нод List.Replace… просто создает новые списки (вход list нода ) количеством равным числу index и в каждом из них производит замену на весь лист item . Возможно и есть способ изменить его поведение на то что ожидается…
Решение Конрода Собона (выбираются все элементы проекта по нескольким категориям): # Copyright(c) 2017, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net
import clr
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
# Import RevitAPI
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
import System
from System import Array
from System.Collections.Generic import *
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
try:
>>>>errorReport = None
>>>>cat_list = [BuiltInCategory.OST_Rooms, BuiltInCategory.OST_Walls, BuiltInCategory.OST_Windows, BuiltInCategory.OST_Doors]
>>>>typed_list = List[BuiltInCategory](cat_list)
>>>>filter = ElementMulticategoryFilter(typed_list)
>>>>output = FilteredElementCollector(doc).WherePasses(filter).ToElements()
except:
# if error occurs anywhere in the process catch it
>>>>import traceback
>>>>errorReport = traceback.format_exc()
# Assign your output to the OUT variable
if None == errorReport:
>>>>OUT = output
else:
>>>>OUT = errorReport
чтобы выбрать те же элементы только на активном виде , меняем только одну строку: output = FilteredElementCollector(doc,doc.ActiveView.Id).WherePasses(filter).ToElements()
“Калька” с си-шарпа…
Пишу своими, а не словами из учебника.
Си – язык требующий четкого определения переменных. Инт, Дабл, Стринг и т.п.
Питон – язык без “формализации” данных и может запросто проводить действия без предопределения переменных.
В данном случае List [ElementId](elemIds)
Означает, что в функцию подается список коллекция List в котором находятся объекты типа [ElementId] , а название списска elemIds
В Питоне достаточно написать uidoc.Selection.SetElementIds(elemIds)
Вывод: оказывается в ревите есть комманды, которые “едят” не родные списки, а объекты из .Net – коллецкии.
Для создания таковых и используется List [ElementId].
Спасибо за хороший вопрос. Пришлось посидеть, почитать.
Добрый день, объясните, пожалуйста, синтаксис и логику строчки 22 (скрипт из коробки с ревитом “Выбрать все маркируемые…”). Пытаюсь понять, как питоном выбирать объекты ревита и вообще пользоваться методами. Может, где то можно почитать про это дело? Revit API 2016 Guide открыл и испугался. Куда там глядеть?
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitAPIUI")
import Autodesk
from Autodesk.Revit.UI import *
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitNodes")
import Revit
# clr.ImportExtensions(Revit.Elements)
from System.Collections.Generic import *
elems = UnwrapElement(IN[0])
elemIds = []
for elem in elems:
elemIds.append(elem.Id)
uidoc = DocumentManager.Instance.CurrentUIDocument
uidoc.Selection.SetElementIds(List[ElementId](elemIds))
# Just for fun - give it to the output!
OUT = elemIds
Здравствуйте, не могу сообразить как сгруппировать список по сходным значениям с помощью List.GroupByKey. Надо чтобы получился список вида: { { ff,ff }, {aa,aa,aa}, { ff,ff } }