Задание параметров ...
 
Поделиться:
Уведомления
Очистить все

[Решено] Задание параметров элементов в Python

16 Сообщения
3 Пользователи
3 Лайки
865 Просмотры
0
Автор темы

Добрый день!

Разрабатываю скрипт на Dynamo для автоматического изменения высоты пространств. Так как обычными нодами нельзя изменить данный параметр (only read), то пытаюсь реализовать запись через Python.

На вход подаю два списка:

IN[0] - список пространств

IN[1] - список высот, на которые нужно заменить

Длины списков одинаковые.

Сам код получился такой:

import clr
clr.AddReference("RevitNodes")
import Revit
space = IN[0]
hight = IN[1]
Revit.Transaction.Transaction.Start(space)
for i in space:
k=UnwrapElement(i).LookupParameter("Смещение сверху").Set(hight[2])
Revit.Transaction.Transaction.End(space)
OUT = space

Не получается подать на перезапись высоты списком. Если на "Set(hight[2])" подать одиночное значение, то все хорошо, если просто оставить "Set(hight)" или "Set(hight[i])" питон ругается

 

Space

 

7 Ответов
2

@tai 

Pyton ругается потому что вы в значение пытаетесь сразу весь список подать. 
Если у вас одинакового размера списки и по очереди нужно каждому элементу значение присвоить, то нужно в цикле перебирать не элементы, а индексы.

Попробуйте вот так:

import clr
clr.AddReference("RevitNodes")
import Revit
space = IN[0]
hight = IN[1]
Revit.Transaction.Transaction.Start(space)
for i in range(len(space)):
    k=UnwrapElement(space[i]).LookupParameter("Смещение сверху").Set(hight[i])
Revit.Transaction.Transaction.End(space)
OUT = space

 

BIM-менеджер
Соавтор шаблонов ADSK КЖ/КМ 2021
Инженер-проектировщик КР, КЖ
Телеграм
Правила форума и некоторые нюансы по работе с текстовым редактором

1
Автор темы

Да, все заработало как надо, спасибо за помощь!

Вадим Муратов Вадим Муратов 13.04.2023 08:04

@tai эту же задачу можно решить и без обращения к индексам с помощью метода zip. Если списки равной длины, то это идеальный способ

for s, h in zip(space, height):

  k=UnwrapElement(s).LookupParameter("Смещение сверху").Set(h)

Кстати да, забываю постоянно про zip. Хорошее решение ?

0
Автор темы

И этот метод тоже работает, за hEight отдельное спасибо )

А кто-нибудь может подсказать, существуют курсы посвященные чисто Python в Dynamo, ну или DesignScript+Python?

0
Автор темы

Ребят, я с этим питоном все не могу успокоится... )))

Делаю уже другой скрипт, но таже проблема, и наверно схожее должно быть решение, поэтому продолжаю в этой теме.
Делаю скрипт, в котором надо реализовать перемещение элементов (труб и воздуховодов) по оси X и У. Как и в первой задаче есть список элементов, список ΔX и ΔY.

На просторах интернета нашел следующий код:

import clr

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

#Входные данные для этого узла будут сохранены в виде списка в переменной IN.
doc = DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application

dataEnteringNode = IN
elementId = IN[0].Id

TransactionManager.Instance.EnsureInTransaction(doc)
ElementTransformUtils.MoveElement(doc,ElementId(elementId),XYZ(IN[1],IN[2],0))
TransactionManager.Instance.TransactionTaskDone()

OUT = 0

Проверил, он работает, все классно, но опять только с одним элементом, я пытался через цикл for по аналогии с прошлой задачей заставить его работать со списками, ничего не вышло. Кто-нибудь может его допилить?

сайт исходника кода https://russianblogs.com/article/38012006102/

Вадим Муратов Вадим Муратов 15.04.2023 07:53

@tai свой код показать не хотите, да?)

0
Автор темы

Да было б чтоб показывать )

Было много вариантов, но самый первый это просто добавить цикл for и в его тело поместить перемещение (Move) с транзакциями, что-то вроде такого:

import clr

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

#Входные данные для этого узла будут сохранены в виде списка в переменной IN.
doc =  DocumentManager.Instance.CurrentDBDocument
app =  DocumentManager.Instance.CurrentUIApplication.Application

dataEnteringNode = IN
elementId = IN[0].Id
x = IN[1]
y = IN[2]

for i in range(len(x)):
    TransactionManager.Instance.EnsureInTransaction(doc)
    ElementTransformUtils.MoveElement(doc,ElementId(elementId),XYZ(x[i],y[i],0))
    TransactionManager.Instance.TransactionTaskDone()

# Присвоите свой вывод переменной OUT.
OUT = 0

 

Длины списков одинаковые поэтому длину можно рассчитывать с любого входящего списка

В этом коде Питон ругается на строку "elementId = IN[0].Id" - AttributeError: 'list' object has no attribute 'Id'

@tai Вы пытаетесь взять id у списка. В ошибке написано, что объект список не имеет такого атрибута.

0
Автор темы

Тоже над этим думал, но если этот код использовать как есть, подать один элемент и на X, Y по одному числу, то все работаеткак надо, даже с Id

Вадим Муратов Вадим Муратов 16.04.2023 09:22

@tai и что?) один элемент — это один элемент, список — это список, совершенно другой объект. покажите, что подаёте в Питон-скрипт, что там за структура списка

Скорее всего у вас там список из трёх подсписков. Когда вы подаёте подсписок IN[0] и берёте у него свойство Id, то Ревит берёт, естественно, айди у списка. Но список не имеет такого свойства.

если у вас там три равных списка, то можно делать такой цикл

TransactionManager.Instance.EnsureInTransaction(doc)

for el, x, y in zip(IN[0], IN[1], IN[2]):

    ElementTransformUtils.MoveElement(doc, el.Id, XYZ(x,y,0))

TransactionManager.Instance.TransactionTaskDone()

Правда, меня тут смущает, что координата Z равно нулю, он ведь вам элементы «опустит» на ноль файла. Вы там что перемещаете?

0
Автор темы

Данный код перемещает элементы на указанное смещение относительно своего текущего положения.

Насчет списков, то пробовал подавать и три отдельных списка и один список, в котором три подсписка, ни первое, ни второе не получилось.

Задача, которую я решаю, это смещение выделенных воздуховодов и труб так, чтобы между ними было равное расстояние, например 100 мм. Постоянная ситуация, когда по коридору идут куча воздуховдов, труб, какие-то в изоляции, какие-то нет, хочется это все выровнять, но руками это долго. Ниже записал видео как должен работать данный скрипт. 

Пока не знаю как преобразовать код, чтоб они обрабатывал элементы списком, поэтому пока разбиваю весь список по одному элементу.

 

image

 

Это сообщение было изменено 1 год назад от TAI

@tai посмотрите какой-нибудь базовый курс по питону. Ваш путь в корне не верный. 
Вы разбиваете список, пишете 9 элементов (при этом теряете 1 элемент исходного списка, так как индексация начинается с 0), а если будет не 9 элементов, а 90? Тогда что будете делать?
Разберитесь с циклами, это совсем не сложно и это база, если хотите писать или использовать скрипты в Dynamo.

На том же степике есть бесплатные курсы по основам программирования

Вадим Муратов Вадим Муратов 16.04.2023 15:09

@askravcova, это база!

@muratovbim так о том и речь, что не зная таких базовых вещей пытаться что-то сделать в коде - бесполезная трата времени.

Ответ