Python. Перенос значений параметров между семействами

Автор Тема: Python. Перенос значений параметров между семействами  (Прочитано 18371 раз)

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

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Добрый вечер коллеги !
Есть код, вроде ничего особого но не могу понять где ошибка :
Код - Python [Выбрать]
  1. #связь с Revit и его параметрами API библиотек
  2. import clr
  3. clr.AddReference('RevitAPI')
  4. clr.AddReference('RevitAPIUI')
  5.  
  6. from Autodesk.Revit import *
  7. from Autodesk.Revit.UI import *
  8. from Autodesk.Revit.UI.Macros import *
  9. from Autodesk.Revit.UI.Selection import *
  10. from Autodesk.Revit.DB import *
  11. from System.Collections.Generic import *
  12. from System.Collections import *
  13. from System import *
  14. from math import *
  15.  
  16.  
  17. app = __revit__.Application
  18. doc = __revit__.ActiveUIDocument.Document
  19.  
  20. t = Transaction(doc, 'Print family parameters')
  21.  
  22. t.Start()
  23.  
  24. #начало кода
  25.  
  26. # Возвращает идентификатор элемента итератор к элементам, проходящих фильтры
  27. famtypeitr = collector.GetElementIdIterator()
  28. famtypeitr.Reset()
  29.  
  30. # фильтр всех экземпляров категории
  31. typeFilter= ElementCategoryFilter(BuiltInCategory.OST_Rebar)
  32.  
  33. # фильтр всех видимых экземпляров
  34. elems=FilteredElementCollector(doc).WherePasses( typeFilter ).ToElements()
  35.  
  36. # фильтр всех экземпляров класса
  37. symbolFilter= ElementClassFilter(type(FamilySymbol))
  38.  
  39. # 2фильтр всех экземпляров категории
  40. type2Filter=ElementCategoryFilter(BuiltInCategory.OST_DetailComponents)
  41.  
  42. # получаем возможность фильтровать по строкам (текст)
  43. provider=ParameterValueProvider(ElementId( BuiltInParameter.ALL_MODEL_TYPE_NAME))
  44.  
  45. # Основа для всех классов, которые сравнивают значения строк из Revit в значение фильтра поставляемого пользователем
  46. evaluator=FilterStringEquals()
  47.  
  48. # Фильтр который работает на строковых(текстовых) значениях во всем проекте Revit
  49. rule=FilterStringRule(provider, evaluator, "Деталь П1", true )
  50.  
  51. # Фильтр используется для сопоставления элементов от одного или нескольких правил фильтров параметров
  52. paramFilter=ElementParameterFilter(rule)
  53.  
  54. # Фильтр списка
  55. filterList=List<ElementFilter>()
  56. filterList.Add(symbolFilter)
  57. filterList.Add(type2Filter)
  58. filterList.Add(paramFilter)
  59.  
  60. # Фильтр, который содержит набор фильтров.
  61. Filter=LogicalAndFilter(filterList)
  62.  
  63. # фильтр всех видимых экземпляров
  64. details=FilteredElementCollector(doc).WherePasses( Filter ).ToElements()
  65.  
  66. # присвоение параметров от rebar к detail
  67. for rebar in elems:
  68.     p=Parameter
  69.     p=rebar.LookupParameter("A")
  70.     if (p == null):
  71.         continue
  72.     float(a=p.AsDouble())
  73.     p=rebar.LookupParameter("B")
  74.     if (p == null):
  75.         continue
  76.     float(b=p.AsDouble())
  77.     p=rebar.LookupParameter("C")
  78.     if (c == null):
  79.         continue
  80.     float(b=p.AsDouble())
  81.     for detail in details:
  82.         p2=Parameter
  83.         p2 = detail.LookupParameter("A")
  84.         p2.Set(a)
  85.         p2 = detail.LookupParameter("B")
  86.         p2.Set(b)
  87.         p2 = detail.LookupParameter("C")
  88.         p2.Set(c)
  89.        
  90. t.Commit()
  91.  
  92. __window__.Close()
   
   
   

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

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Честно говоря, запускать не пытался, в коде много мусора.
Но сразу в глаза бросается строчка
Код - Python [Выбрать]
  1. famtypeitr = collector.GetElementIdIterator()

collector тут еще не существует, дальше famtypeitr нигде не используется.
Дальше вот эта строка:
Код - Python [Выбрать]
  1. filterList=List<ElementFilter>()

В Python, насколько помню Generic-и нужно задавать вот так:
Код - Python [Выбрать]
  1. filterList=List[ElementFilter]()

Дальше
Код - Python [Выбрать]
  1. elems=FilteredElementCollector(doc).WherePasses( typeFilter ).ToElements()
таким фильтром вернутся не только экземпляры, но и типоразмеры. Вообще можно написать проще:
Код - Python [Выбрать]
  1. elems=FilteredElementCollector(doc).OfCategory( BuiltInCategory.OST_Rebar).WhereElementIsNotElementType().ToElements()

Ну и я не вполне уверен в собранном в LogicalAndFilter фильтре, честно говоря

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Есть код, вроде ничего особого но не могу понять где ошибка :
А в чем собственно ошибка проявляется?
Написать кучу кода, не сказав что в итоге хочется получить и промолчать что за ошибка (или что не получается) - это выглядит как
Цитировать
Ребят, я тут что то написал, сам не знаю что, но вы посмотрите, правильно ли я все написал, а то я не пойму, получается ли у меня то что я хотел или нет

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Александр Игнатович Спасибо, буду вечером смотреть (мучить) дальше код с учетом ваших поправок.
А в чем собственно ошибка проявляется?
Написать кучу кода, не сказав что в итоге хочется получить и промолчать что за ошибка (или что не получается) - это выглядит как
ошибка - код не работает.
что хочу получить в названии темы.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
код не работает
как не работает? в каком месте? не работает в плане функциональности или выдает ошибку? Если да, то в момент компиляции или при выполнении и на какой строчке? Если нет, то самый простой вариант - отладка по шагам и смотреть значения переменных после каждого шага.

что хочу получить в названии темы.
Все же предлагаю четко сформулировать вашу идею и получить в зависимости от этого предложения по решению задачи. В коде как минимум идет перенос значений между экземплярами семейств, а не семействами. Плюс логика странная.
Вы в цикле перебираете элементы типа "Арматура", затем в этом цикле у вас еще один цикл (якобы для копирования параметров). Так вот если Арматрур несколько (а их наверняка ни одна), то второй цикл у вас будет выполнятся столько раз, сколько элементов арматуры. Поэтому что в итоге запишется в Деталь П1 - совершенно непредсказуемо и непонятно.
Кстати, условие
Код - Python [Выбрать]
  1. p=Parameter
  2.     p=rebar.LookupParameter("A")
либо всегда истина либо всегда ложь. Соответственно либо второй цикл не выполнится никогда, либо результат того, что запишется в Деталь П1 непредсказуем.

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Что хочу получить детально:
Есть допусти много экземпляров арматуры (Rebar), у арматуры есть три параметра (A,B,C) и они для всех экземпляров разные. Хочу получить такие же параметры для другого семейства (detail), точнее не сами параметры (они уже есть в семействе), а значения этих семейств полученные от Rebar  по фильтру строки "Деталь П1".

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
они для всех экземпляров разные. Хочу получить такие же параметры для другого семейства (detail)
Ключевое слово - разные. Какое в итоге значение хотите видеть в detail?

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Получается мне список нужно ввести:
 ["Деталь П1","Деталь П2","Деталь П3","Деталь П4" и тд], мне нужно контролировать для каких типов "Rebar"
и в зависимости от параметров A,B,C "Rebar" переносить их в эти же  ["Деталь П1","Деталь П2","Деталь П3","Деталь П4" и тд] только уже для "Detail" . Но при этом например"Деталь П1" в "Rebar" может иметь несколько экземпляров с различными A,B,C.

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
p=Parameter
    p=rebar.LookupParameter("A")
Python ругается на такой синтаксис
Немного подремонтировав код получил :

Код - Python [Выбрать]
  1. #связь с Revit и его параметрами API библиотек
  2. import clr
  3. clr.AddReference('RevitAPI')
  4. clr.AddReference('RevitAPIUI')
  5.  
  6. from Autodesk.Revit import *
  7. from Autodesk.Revit.UI import *
  8. from Autodesk.Revit.UI.Macros import *
  9. from Autodesk.Revit.UI.Selection import *
  10. from Autodesk.Revit.DB import *
  11. from System.Collections.Generic import *
  12. from System.Collections import *
  13. from System import *
  14. from math import *
  15.  
  16.  
  17. app = __revit__.Application
  18. doc = __revit__.ActiveUIDocument.Document
  19.  
  20. t = Transaction(doc, 'Print family parameters')
  21.  
  22. t.Start()
  23.  
  24. #начало кода
  25.  
  26. # Возвращает идентификатор элемента итератор к элементам, проходящих фильтры
  27. collector = FilteredElementCollector(doc)
  28. collector.OfCategory(BuiltInCategory.OST_GenericModel)
  29. collector.OfClass(FamilySymbol)
  30. famtypeitr = collector.GetElementIdIterator()
  31. famtypeitr.Reset()
  32.  
  33. # фильтр всех экземпляров категории
  34. typeFilter= ElementCategoryFilter(BuiltInCategory.OST_Rebar)
  35.  
  36. # фильтр всех видимых экземпляров
  37. elems=FilteredElementCollector(doc).WherePasses( typeFilter ).ToElements()
  38.  
  39. # фильтр всех экземпляров класса
  40. symbolFilter= ElementClassFilter(FamilySymbol)
  41.  
  42. # 2фильтр всех экземпляров категории
  43. type2Filter=ElementCategoryFilter(BuiltInCategory.OST_DetailComponents)
  44.  
  45. # получаем возможность фильтровать по строкам (текст)
  46. provider=ParameterValueProvider(ElementId( BuiltInParameter.ALL_MODEL_TYPE_NAME))
  47.  
  48. # Основа для всех классов, которые сравнивают значения строк из Revit в значение фильтра поставляемого пользователем
  49. evaluator=FilterStringEquals()
  50.  
  51. # Фильтр который работает на строковых(текстовых) значениях во всем проекте Revit
  52. rule=FilterStringRule(provider, evaluator, "Деталь П1", True)
  53.  
  54. # Фильтр используется для сопоставления элементов от одного или нескольких правил фильтров параметров
  55. paramFilter=ElementParameterFilter(rule)
  56.  
  57. # Фильтр списка
  58. filterList=List[ElementFilter]()
  59. filterList.Add(symbolFilter)
  60. filterList.Add(type2Filter)
  61. filterList.Add(paramFilter)
  62.  
  63. # Фильтр, который содержит набор фильтров.
  64. Filter=LogicalAndFilter(filterList)
  65.  
  66. # фильтр всех видимых экземпляров
  67. details=FilteredElementCollector(doc).WherePasses( Filter ).ToElements()
  68.  
  69. # присвоение параметров от rebar к detail
  70. for rebar in elems:
  71.     p=Parameter
  72.     p=rebar.LookupParameter("A")
  73.     if (p == None):
  74.         continue
  75.     float(a=p.AsDouble())
  76.     p=rebar.LookupParameter("B")
  77.     if (p == None):
  78.         continue
  79.     float(b=p.AsDouble())
  80.     p=rebar.LookupParameter("C")
  81.     if (p == None):
  82.         continue
  83.     float(c==p.AsDouble())
  84.     for detail in details:
  85.         p2=Parameter
  86.         p2 = detail.LookupParameter("A")
  87.         p2.Set(a)
  88.         p2 = detail.LookupParameter("B")
  89.         p2.Set(b)
  90.         p2 = detail.LookupParameter("C")
  91.         p2.Set(c)
  92.        
  93. t.Commit()
  94.  
  95. __window__.Close()
   
В итоге Revit ругается got an unexpected keyword argument 'a', как я понимаю аргумент для float() не правильный .......
   

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

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
А зачем вообще вызывать float(a=...), почему не просто a=... ? Насколько я понимаю, у функции float в Python другое предназначение https://ironpython-test.readthedocs.org/en/latest/library/functions.html#float

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Получается мне список нужно ввести:
 ["Деталь П1","Деталь П2","Деталь П3","Деталь П4" и тд], мне нужно контролировать для каких типов "Rebar"
А логически как связаны Детали ПХ и Арматуры?
Вообще да, нужно четко определиться с сопоставлением деталей арматурам. Сколько типоразмеров Деталей П?
Вообще у арматуры значения A, B, C часто меняются или это статические значения? Сколько вариантов значений A, B, C существует? Это нужно все для более оптимального алгоритма.

Off-Topic: показать
Кстати, с комментариями в коде у вас явный перебор:)

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Вот еще что подумал. Получается у вас будет список примерно такой:
Если параметр A=1, B=2, C=3, то надо записать эти значения в Деталь П1, Если A=2, B=3, C=4, то в Деталь П2 и т.п. Количество комбинаций A, B, C теоретически бесконечно. В конкретном проекте оно конечно будет ограничено.

Но. Если у вас будет такой список, то я вообще не вижу смысла в коде обращаться к арматурам. Проходите по всем деталям. Смотрите, если это Деталь П1, то заполняете значения параметров A=1, B=2, C=3, если Деталь П2, то A=2, B=3, C=4 и т.д. Здесь нам вообще арматуры не важны.

Опять но... но если этих вариантов комбинаций значений много, то задача трудно решаема (как то нужно составить список). А если еще они и меняются, то задача вообще в таком виде не решаема.
Может быть все таки детали и арматуры как то связаны в модели и можно с помощью API определить какая деталь к какой арматуре привязана и взять параметры для детали из привязанной арматуры?

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
А зачем вообще вызывать float(a=...), почему не просто a=... ? Насколько я понимаю, у функции float в Python другое предназначение
мне нужно просто дробное значение, не целое, точнее оно может быть не целым
А логически как связаны Детали ПХ и Арматуры?
они связанны через общий параметр A, B,C (а вообще их 6 или 7).
Мне главное что бы можно было передать значения параметров! а не сами параметры. В данном коде просто передается значение параметров от Rebar к Detail по строке "Деталь П1". Далее хочу усложнить до полноценного сортировщика , который будет сортировать все детали в Rebar по A,B,C. (допустим 30 различных деталей где A,B,C различные). И по этой сортировке будет создавать сам Detail ( а точнее 30 экземпляров с различными A,B,C) я точно знаю что эта задача решаема но полуавтоматическим методом. Приходится переписывать значения A,B,C в ручную из Rebar в Detail.
И задача еще усложняется тем что набор параметров A,B,C для всех деталей не одинаковый , где то может быть только A,B , а где то A,B,C,D.
Off-Topic: показать
а комментарии я пишу себе что бы понимать куда и что )

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Мне главное что бы можно было передать значения параметров! а не сами параметры.
Это понятно, только это этого не легче:)

они связанны через общий параметр A, B,C
а физически связаны? через параметр они получается пока еще не связаны, так как задача состоит в том, чтобы как раз таки их связать параметрами.
В данном коде просто передается значение параметров от Rebar к Detail по строке "Деталь П1"
Так то оно так, только вы не знаете от какой именно Rebar значения параметров копируются в деталь.
Задача еще усложняется тем что набор параметров A,B,C для всех деталей не одинаковый , где то может быть только A,B , а где то A,B,C,D.
Задача вообще выглядит странной. Пример модели бы хоть скинули или на скриншотах показали. А то на абстрактных воображениях тяжело воспринимать.

В целом я останусь при своем мнении. Если физически арматура и деталь никак не связаны, то единственных выход делать список "Набор параметров" - "Название детали". И в этом случае вам Rebar вообще не надо трогать.

Оффлайн mikoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 55
  • Карма: 0
Это понятно, только это этого не легче:)
и я понимаю что от этого не легче :)
а физически связаны?
нет,ни как вообще.
Так то оно так, только вы не знаете от какой именно Rebar значения параметров копируются в деталь.
как не знаю !? могу ввести строковый параметр для элементов с нужными мне параметрами ....в теории :/
Задача вообще выглядит странной.
реализовываю ведомость деталей (ведомость гибочных элементов) ну и далее по наклонной
В целом я останусь при своем мнении. Если физически арматура и деталь никак не связаны, то единственных выход делать список "Набор параметров" - "Название детали". И в этом случае вам Rebar вообще не надо трогать.
не соглашусь так как уже получилось для одного элемента :), вот код рабочий:

Код - Python [Выбрать]
  1. #связь с Revit и его параметрами API библиотек
  2. import clr
  3. clr.AddReference('RevitAPI')
  4. clr.AddReference('RevitAPIUI')
  5.  
  6. from Autodesk.Revit import *
  7. from Autodesk.Revit.UI import *
  8. from Autodesk.Revit.UI.Macros import *
  9. from Autodesk.Revit.UI.Selection import *
  10. from Autodesk.Revit.DB import *
  11. from System.Collections.Generic import *
  12. from System.Collections import *
  13. from System import *
  14. from math import *
  15.  
  16.  
  17. app = __revit__.Application
  18. doc = __revit__.ActiveUIDocument.Document
  19.  
  20. t = Transaction(doc, 'Print family parameters')
  21.  
  22. t.Start()
  23.  
  24. #начало кода
  25.  
  26. # Возвращает идентификатор элемента итератор к элементам, проходящих фильтры
  27. collector = FilteredElementCollector(doc)
  28. collector.OfCategory(BuiltInCategory.OST_GenericModel)
  29. collector.OfClass(FamilySymbol)
  30. famtypeitr = collector.GetElementIdIterator()
  31. famtypeitr.Reset()
  32.  
  33. # фильтр всех экземпляров категории
  34. typeFilter= ElementCategoryFilter(BuiltInCategory.OST_Rebar)
  35.  
  36. # фильтр всех видимых экземпляров
  37. elems=FilteredElementCollector(doc).WherePasses( typeFilter ).ToElements()
  38.  
  39. # фильтр всех экземпляров класса
  40. symbolFilter= ElementClassFilter(FamilySymbol)
  41.  
  42. # 2фильтр всех экземпляров категории
  43. type2Filter=ElementCategoryFilter(BuiltInCategory.OST_DetailComponents)
  44.  
  45. # получаем возможность фильтровать по строкам (текст)
  46. provider=ParameterValueProvider(ElementId( BuiltInParameter.ALL_MODEL_TYPE_NAME))
  47.  
  48. # Основа для всех классов, которые сравнивают значения строк из Revit в значение фильтра поставляемого пользователем
  49. evaluator=FilterStringEquals()
  50.  
  51. # Фильтр который работает на строковых(текстовых) значениях во всем проекте Revit
  52. rule=FilterStringRule(provider, evaluator, "Деталь П1", True)
  53.  
  54. # Фильтр используется для сопоставления элементов от одного или нескольких правил фильтров параметров
  55. paramFilter=ElementParameterFilter(rule)
  56.  
  57. # Фильтр списка
  58. filterList=List[ElementFilter]()
  59. filterList.Add(symbolFilter)
  60. filterList.Add(type2Filter)
  61. filterList.Add(paramFilter)
  62.  
  63. # Фильтр, который содержит набор фильтров.
  64. Filter=LogicalAndFilter(filterList)
  65.  
  66. # фильтр всех видимых экземпляров
  67. details=FilteredElementCollector(doc).WherePasses( Filter ).ToElements()
  68.  
  69. # присвоение параметров от rebar к detail
  70.  
  71. for rebar in elems:
  72.     p=Parameter
  73.     p=rebar.LookupParameter("A")
  74.     if (p == None):
  75.         continue
  76.     a=p.AsDouble()
  77.     p=rebar.LookupParameter("B")
  78.     if (p == None):
  79.         continue
  80.     b=p.AsDouble()
  81.     p=rebar.LookupParameter("C")
  82.     if (p == None):
  83.         continue
  84.     c=p.AsDouble()
  85.     for detail in details:
  86.         p2=Parameter
  87.         p2 = detail.LookupParameter("A")
  88.         p2.Set(a)
  89.         p2 = detail.LookupParameter("B")
  90.         p2.Set(b)
  91.         p2 = detail.LookupParameter("C")
  92.         p2.Set(c)
  93. t.Commit()
  94.  
  95. __window__.Close()
   
почему-то не понимает float(). Следующая версия кода ,создавать экземпляры с разными A,B,C, для начала с двумя(тремя) хотя бы.