Set Parameter by two zipped values, how?

Hello,

so my code works well!

but the final part does not work

i want sum baseConstrain(Host) and Offset(Opening) and set a parameter… ChatGPT is not working like real people!

… or is there even a easier way ? just grab apsult hight and

import clr
import sys 

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *

clr.AddReference('System')
from System.Collections.Generic import List

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

def Sum (x,y):
	return x + y

#collector
collector = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel)
all_elements = collector.WhereElementIsNotElementType().ToElements()

Openings = [i for i in all_elements if "Allg_WD_rechteckig" in i.Symbol.FamilyName] #Openings

Hosts = [i.Host.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsDouble() for i in Openings] #Host - Base Constrain from openings

Offsets = [i.LookupParameter("UK über Ebene").AsDouble() for i in Openings] # Parameter for round Openings is not working "Achse über Ebene"

Apsoluts = [i for i in zip(Sum(Hosts,Offsets))]

for i in Openings:
	for j in i.Parameters:
		p = i.LookupParameter("EbenenHöhe über 00")
		tx = Transaction(doc, "Apsoluthöhe eintragen")
		tx.Start()
		p.Set(Apsoluts)
		tx.Commit()

OUT = "Done"

KR

Andreas

Hello,
I think it’s not possible to create the parameter through the API to Mr. Jacob’s answer here

You can do it under dynamo though.

cordially
christian.stan

@christian.stan ,

can be a workaround easier like here ?

just taking the locationPoints get Z Value and set the shared Parameter insteat of calculating!

because i have assets, rectengular and circle openings… is it possible this way ?

grafik

the task is just get → Set

KR

Andreas

You are summing before you zip, which I don’t think is your intent in this line:
Apsoluts = [i for i in zip(Sum(Hosts,Offsets))]

Try this instead:
Apsoluts = [Sum(i) for i in zip(Hosts,Offsets)]

1 Like

@jacob.small ,

i am already on the train.

  • get locationPoint.Z
  • set the Parameter

I think thats better than any location, but i am struggeling with units and negativ values…

KR

Andreas

your ‘Apsoluts’ is a list here
cordially
christian.stan

1 Like

Hello, there are 2 arguments to its function

cordially
christian.stan

3 Likes

Hello @Draxl_Andreas,

I´d recommend to print the results after every step to investigate whats going on.

I´d recommend, keep it simple, don´t overuse list comprehensions (use them for heavy tasks to speed them up only) and ziping, etc. This helps in making the code readable and understandable. And don´t create such a small function that is only called a single time and is much more complicated then just making a “+”.

If I understood correct this should satisfy you needs, have a look at my comments:
Edit: looking at it again, i think you don´t need the offset parameter, just "level_elevation + elevation_from_level "?! I commented it out.

import clr

# RevitAPI
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import FilteredElementCollector, BuiltInCategory, BuiltInParameter

# RevitAPIUI
clr.AddReference('RevitAPIUI')

# System
clr.AddReference('System')
from System.Collections.Generic import List

# RevitNodes
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

# RevitServices
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from Autodesk.Revit.UI import TaskDialog

doc = DocumentManager.Instance.CurrentDBDocument

try:
	# Collecting all generic model elements
	collector = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel)
	all_elements = collector.WhereElementIsNotElementType().ToElements()
	
	# Filtering for specific family name
	openings = [elem for elem in all_elements if "Allg_WD_rechteckig" in elem.Symbol.FamilyName]
	
	for opening in openings:
		elevation_from_level_para = opening.get_Parameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM)
		#offset_para = opening.LookupParameter("UK über Ebene")
		target_para = opening.LookupParameter("EbenenHöhe über 00")
	    
		# Get values only if parameter exist or .AsDouble() will throw an error
		if elevation_from_level_para and target_para:
			elevation_from_level = elevation_from_level_para.AsDouble()
			#offset = offset_para.AsDouble()
			target = target_para.AsDouble

			# Getting the elevation of the level associated with the opening
			level = doc.GetElement(opening.LevelId)
			level_elevation = level.Elevation
			total_elevation = level_elevation + elevation_from_level # + offset
	
			# Update the target parameter only if it does not already have the right value
			if target != total_elevation:
				TransactionManager.Instance.EnsureInTransaction(doc)
				target_para.Set(total_elevation)  
				TransactionManager.Instance.TransactionTaskDone()
				
# Catch any error and display it with a taskdialog
except Exception as e:
	TaskDialog.Show("Error", str(e))

This is by the way the perfect use case for a dynamic model updater, I have things like that running in the background to auto calculate those parameters. Triggered by family placement or geometry change. PyRevit script looks like that:

# -*- coding: utf-8 -*-

from System import Guid
from Autodesk.Revit.DB import (
    IUpdater, UpdaterId, ElementId, UpdaterRegistry, Element, 
    ElementCategoryFilter, BuiltInCategory, ChangePriority, FamilyInstance, 
)
from Autodesk.Revit.UI import TaskDialog, TaskDialogCommonButtons, TaskDialogResult

class SimpleUpdater(IUpdater):
    def __init__(self, doc):
        self._doc = doc

    def Execute(self, data):
        element_ids = list(data.GetAddedElementIds()) + list(data.GetModifiedElementIds())
        for id in element_ids:
            element = self._doc.GetElement(id)
            
            # If element is of specific family type, update parameters
            if self.is_specific_family_instance(element):
                self.handle_wandoeffnung(element)
            else:
                self.handle_doors(element)

    @staticmethod
    def is_specific_family_instance(element):
        from Autodesk.Revit.DB import FamilyInstance,BuiltInParameter
        return (isinstance(element, FamilyInstance) and 
                hasattr(element, 'Symbol') and element.Symbol is not None and 
                element.Symbol.Family.Name == "Wandöffnung rechteckig" and 
                element.Name == "WD")

    def handle_wandoeffnung(self, element):
        from Autodesk.Revit.DB import FamilyInstance,BuiltInParameter
        elevation_from_level = element.get_Parameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM).AsDouble()
        height = element.LookupParameter("Höhe Aussparung").AsDouble()
        top_edge_level = element.LookupParameter("Top Edge Elevation ")
        
        level = self._doc.GetElement(element.LevelId)
        level_elevation = level.Elevation
        elevation = level_elevation + elevation_from_level + height
        
        if top_edge_level and top_edge_level.AsDouble() != elevation:
            top_edge_level.Set(elevation)

    def handle_doors(self, element):
        from Autodesk.Revit.DB import FamilyInstance,BuiltInParameter
        top_edge_para = element.LookupParameter("Top Edge Elevation")
        head_height_para = element.get_Parameter(BuiltInParameter.INSTANCE_HEAD_HEIGHT_PARAM)
        
        if not top_edge_para or not head_height_para:
            return

        level = self._doc.GetElement(element.LevelId)

        if not level_elevation_para:
            return

        height = head_height_para.AsDouble()
        level_elevation = level.Elevation
        elevation = level_elevation + height
        
        if elevation != top_edge_para.AsDouble():
            top_edge_para.Set(elevation)


    def GetUpdaterId(self):
        # Return the unique identifier for this updater
        return self.updater_id

    def GetUpdaterName(self):
        return 'SimpleUpdaterName'

    def GetAdditionalInformation(self):
        return 'A simple updater for testing purposes'

    def GetChangePriority(self):
        return ChangePriority.Annotations

    def Initialize(self):
        # This is where you can add trigger conditions for the updater
        pass

    def Uninitialize(self):
        pass

# Get the current document and application
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application

# Create an instance of the updater
updater = SimpleUpdater(doc)

# Create a unique Guid for the updater
guid_string = "145a0f8c-0ada-4526-a36c-85a079463414"
guid = Guid(guid_string)

# Create an UpdaterId using the AddInId of the current application and the unique Guid
updater_id = UpdaterId(app.ActiveAddInId, guid)
updater.updater_id = updater_id

# If the updater is already registered, ask the user if they want to unregister it
if UpdaterRegistry.IsUpdaterRegistered(updater_id, doc):
    dialog_result = TaskDialog.Show("Updater Options", 
                                    "The updater is already registered. Do you want to unregister it?", 
                                    TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No)

    # Depending on the user's choice, unregister the updater
    if dialog_result == TaskDialogResult.Yes:
        # User chose to unregister the updater
        UpdaterRegistry.UnregisterUpdater(updater_id, doc)
        TaskDialog.Show('Success', 'Updater has been unregistered!')

else:
    UpdaterRegistry.RegisterUpdater(updater, doc, True)
    
    # Create a filter for wall elements
    door_filter = ElementCategoryFilter(BuiltInCategory.OST_Doors)
    family_instance_filter = ElementCategoryFilter(BuiltInCategory.OST_GenericModel)
    
    # Assign the trigger to the updater for element updates
    UpdaterRegistry.AddTrigger(updater_id, door_filter, Element.GetChangeTypeElementAddition())
    UpdaterRegistry.AddTrigger(updater_id, door_filter, Element.GetChangeTypeGeometry())
    UpdaterRegistry.AddTrigger(updater_id, family_instance_filter, Element.GetChangeTypeElementAddition())
    UpdaterRegistry.AddTrigger(updater_id, family_instance_filter, Element.GetChangeTypeGeometry())
    
    TaskDialog.Show('Success', 'Updater has been registered and trigger has been set!')
2 Likes