Location для семейства после вставки

Главная Форумы Задать вопрос Location для семейства после вставки

Просмотр 3 сообщений - с 1 по 3 (из 3 всего)
  • Автор
    Сообщения
  • #10400 Score: 0
    Aminka13
    Участник

    Есть семейство – типовая модель, размещение – по рабочей плоскости. Хотела приложить к теме, но что-то не разобралась, как.

    Хочу написать скрипт, который бы позволял прикреплять экземпляры этого семейства на опорную плоскость. Поскольку нельзя поменять плоскость у уже имеющегося семейства, иду путем копирования параметров экземпляра, создания нового семейства и удаления исходного. Написала некий скрипт, который хорошо работает с семействами, изначально созданными по грани. Но для семейства на основе типовой модели с размещением по рабочей плоскости скрипт чудит – новые семейства оказываются с host по опорной плоскости, но location point выдает упорно (0,0,0). Если после того, как скрипт завершен, использовать “нарисованные” скриптом семейства в качестве основы для новых – location нормально ловится. Почему так происходит? где ошибка?

    Текст скрипта:

    import clr, System
    clr.AddReference(“RevitNodes”)
    import Revit
    clr.ImportExtensions(Revit.Elements)
    clr.ImportExtensions(Revit.GeometryConversion)

    clr.AddReference(‘RevitAPI’)
    from Autodesk.Revit.DB import *

    clr.AddReference(“RevitServices”)
    from RevitServices.Persistence import DocumentManager
    from RevitServices.Transactions import TransactionManager
    doc = DocumentManager.Instance.CurrentDBDocument

    clr.AddReference(‘ProtoGeometry’)
    from Autodesk.DesignScript.Geometry import *

    #Введенные в этом узле данные сохраняется в виде списка в переменных IN.
    dataEnteringNode = IN

    Rplane = IN[0]
    ElList = IN[1]

    newFamList = []
    ParList = []
    ParList2D = []

    doc = DocumentManager.Instance.CurrentDBDocument
    view = doc.ActiveView

    TransactionManager.Instance.EnsureInTransaction(doc)

    Z = UnwrapElement(Rplane).GetPlane().Origin[2]#Получили плоскость и ее исходную точку-список, и из нее Z координату
    for el in ElList :
    if UnwrapElement(el).CanFlipWorkPlane :

    #сначала рисуем новый экземпляр семейства
    FamTyp = UnwrapElement(el).Symbol#Получаем семейство
    dir = Vector.ByCoordinates(1,0,0)#Получаем вектор
    famPt = UnwrapElement(el).Location.Point#Получаем точку вставки исходного семейства как .DB.locationpoint и берем ее свойство point
    pt = Point.ByCoordinates(304.8*famPt[0],304.8*famPt[1],304.8*Z)#Получаем новую точку вставки на высоте опорной плоскости в мм
    sttyp = UnwrapElement(el).StructuralType
    newFam = doc.Create.NewFamilyInstance(UnwrapElement(Rplane).GetReference(), pt.ToXyz(), dir.ToRevitType(), FamTyp)#Нарисовали новое семейство

    <span style=”text-decoration: underline;”> #ПРОВЕРЯЕМ, ЧТО У СЕМЕЙСТВА В ЛОКЕЙШЕНЕ – И ВИДИМ, ЧТО ТАМ НУЛИ-это видно на узле element.getlocation, zzz-просто проверочная переменная      </span>
    <span style=”text-decoration: underline;”> #       zzz=UnwrapElement(newFam).Location.Point</span>

    #потом копируем все параметры в новый список с параметрами
    ParSet = UnwrapElement(el).Parameters #Получили список параметров как объектов db-objects
    for ps in ParSet:
    pn = ps.Definition.Name #Получаем имя параметра
    if isinstance(ps.AsValueString(), str) :  #выясняем, есть ли значиение AsValueString в виде стринг (не нон-тайп)
    pval = ps.AsValueString()
    else:
    pval = “”
    ParList.append(pn +” : ” + pval)#Получаем список имен и значений параметров аналогичный ноду element.parameters
    ParList2D.append([pn,pval])#Получаем список имен и значений параметров в виде списка с вложенным списком

    #теперь передаем параметры из исходного экземпляра в новое
    NewParSet = UnwrapElement(newFam).Parameters #Получили список параметров как объектов db-objects
    for ps in NewParSet :
    pn = ps.Definition.Name #Получаем имя параметра нового семейства
    if not ps.IsReadOnly : #проверяем, не является ли он параметром только для чтения
    for par in ParList2D:
    if par[0] == pn :
    pval = par[1]
    newFam.LookupParameter(pn).Set(pval);

    newFamList.append(newFam)

    #удалим старое семейство
    for el in ElList :
    if UnwrapElement(el).CanFlipWorkPlane :
    doc.Delete(UnwrapElement(el).Id)

    TransactionManager.Instance.TransactionTaskDone()

    OUT=newFamList

     

     

     

     

     

    #10412 Score: 0
    Aminka13
    Участник

    Где все ?)  Я так понимаю, надо как-то имитировать “закрытие” динамо-сеанса. Но не понимаю, почему и как. Случайно натыкалась на похожие темы, но найти их не могу опять. Люди-человеки, помогите пожалуйста. Почему динамо, отрисовав семейства, не “видит” их геометрию вставки корректно, пока не выйдешь из сеанса динамо?

    #10413 Score: 0
    Aminka13
    Участник

    Сама спросила – сама ответила :))) не прошло и нескольких дней мытарств по форумам. Может еще кому пригодится:

    помог doc.Regenerate внутри менеджера транзакции.  Оказалось, менеджер транзакций и прямая транзакция работают по-разному. Погуглила – вот тут написано немного о том, чем отличаются два пути транзакции: https://danimosite.wordpress.com/2017/05/11/intro-to-transactions/  А вот почему менеджер транзакции не  регенерирует автоматически  и требует ручной регенерации в моем случае, так и не поняла. Есть статьи Таммика за 2010 год, где есть предположение, что частая автоматическая регенерация перегрузит компьютер и утяжелить программу вроде бы. Но! – менеджер транзакции отрисовывает элемент в пространстве документа, а вот точку вставки не обновляет.  Это как? Значит у ревита есть разные регенерации для документа?  С моим дурным знанием английского полазила по АПИ, но не нашла принудительной регенерации для элемента, только для документа. При этом doc.Regenerate в мануале по АПИ сообщает что” Use this method to force update to the document after a group of changes. Note that when a transaction is committed there is an automatic call to regenerate the document.”  То есть как бы вызов TransactionManager.Instance.TransactionTaskDone()   должен заодно вызывать и doc.Regenerate в любом случае. Однако, видимо, не вызывает? то есть t.Commit() не идентично TransactionManager.Instance.TransactionTaskDone() в части регенерации? Может кто подскажет, почему так? Что там, внутри менеджера?  Я могу только предположить, что “собака зарыта” в том, что в менеджере вызывают субтранзакции, а для них, исходя из https://thebuildingcoder.typepad.com/blog/2017/06/ai-news-and-sub-transaction-regen.html#3   нужна принудительная регенерация.  Кто-то знает истину?)))))

Просмотр 3 сообщений - с 1 по 3 (из 3 всего)
  • Для ответа в этой теме необходимо авторизоваться.