I am trying to set the material-parameter of a freeform object inside a famdoc to “ByCategory” programmatically, using Python API code inside a Dynamo script.
I am using this code:
# Enable Python support and load DesignScript library
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference("System")
from System.Collections.Generic import *
#get the current document & application
doc = DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application
class FamilyOption(IFamilyLoadOptions):
def OnFamilyFound(self,familyInUse,overwriteParameterValues):
overwriteParameterValues = True
return True
def OnSharedFamilyFound(self, sharedFamily, familyInUse, FamilySource, overwriteParameterValues):
overwriteParameterValues = True
return True
#inputs
element = UnwrapElement(IN[0])
parameter = "Material"
#outputs
outlist = []
#get family from element
family = element.Symbol.Family
with doc.EditFamily(family) as famdoc:
#go inside family
#fitered element collector for filtering geometry inside famdoc
collector = Autodesk.Revit.DB.FilteredElementCollector(famdoc);
objects = collector.OfClass(Autodesk.Revit.DB.GenericForm).ToElements()
#get first object from list
object = objects[0]
#get all parameters from object
obj_params = object.GetOrderedParameters()
for p in obj_params:
outlist.Add(p.Definition.Name)
for p in obj_params:
if p.Definition.Name == parameter:
p.Set(Autodesk.Revit.DB.ElementId(-1))
#for p in obj_params:
#if p.Definition.Name == parameter:
#parameterValue = p.AsValueString()
famdoc.LoadFamily(doc,FamilyOption())
del(famdoc)
OUT = object
Somehow, when I open the. dyn and run, the first time always fails.
Error message: "The document is currently modifiable. Close the transaction before calling EditFamily "
But wait… when I recreate the python node (copy/paste) and run again, then no error comes!
You can also check out this short vid I made as a short demo (sorry for bad quality). https://www.youtube.com/watch?v=jxRaRXn9Xpk
In the first run i demonstrate the situation described above. In the second run I copy/paste the node before running, but then still, the first time fails, and after copy pasting again it works.
Question:
Does anyone understand the logic behind this behaviour? Can it be solved to work cleanly?
–
Second question (less important but still curious):
I am somehow able to succesfully set the parameter inside famdoc without using a transaction (as can be seen in the code). How is this possible?
PS. Might you want to test for yourself: here’s a download link to the files