Hello all,
I am working with python shell in dynamo trying to add a connector element to a family's planar face. Please see the code below:
# Load the Python Standard and DesignScript Libraries
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import math
import System
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
#import Autodesk.Revit.UI.Selection
from Autodesk.Revit.DB.Electrical import ElectricalSystemType
from Autodesk.Revit.DB.Structure import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion);
doc = DocumentManager.Instance.CurrentDBDocument;
familyElement = UnwrapElement(IN[0]);
TransactionManager.Instance.TransactionTaskDone();
familyDoc = doc.EditFamily(familyElement.Family);
Id = familyElement.Id;
ref = Reference(familyElement);
TransactionManager.Instance.EnsureInTransaction(doc);
geometryOptions = Options();
geometryOptions.ComputeReferences = True;
geometryOptions.IncludeNonVisibleObjects = False;
# Get the geometry of the family element
geometryElement = familyElement.Geometry[geometryOptions];
planarFace=None;
faces = [];
for geometryObject in geometryElement:
if isinstance(geometryObject, Solid):
solid = geometryObject
for face in solid.Faces:
faces.append(face)
if isinstance(face, PlanarFace):
planarFace = face;
break;
TransactionManager.Instance.TransactionTaskDone();
TransactionManager.Instance.EnsureInTransaction(doc);
# Create the electrical connector
connector = ConnectorElement.CreateElectricalConnector(familyDoc, ElectricalSystemType.PowerBalanced, planarFace.Reference);
# Commit the transaction
TransactionManager.Instance.TransactionTaskDone();
OUT = faces;
I get the error, The reference is not a planar face. Parameter name: planarFace.
If I do OUT = planarFace, then it is indeed an Autodesk.Revit.DB.PlanarFace element. So I am not sure what I am doing wrong. By the way, IN[0] is a family symbol in my project.
Any help would be greatly appreciated. Thank you!
Solved! Go to Solution.
Solved by Christoph_Marthaler_AWZH. Go to Solution.
Hello
I don't think you can use the reference from a face that you get from the project document. You have to use the face of a geometry from an extrusion or the instance of a nested family inside the family document.
You must also create the transaction with the family document if you want to place the connector in the family document.
By the way, no transaction is required to read out the geometry. A transaction is only required when you make changes to a document.
Thank you Christoph for your response. Any pointers on how to get the face of a geometry from an extrusion? do I have to make a new extrusion or can I use an existing one if it is available?
Thank you!
Thank you Christoph for your response. Any pointers on how to get the face of a geometry from an extrusion? do I have to make a new extrusion or can I use an existing one if it is available?
Thank you!
you can use a FilteredElementCollector to get all Extrusions or any other ElementType from a Document
collector = FilteredElementCollector(familyDocument).OfClass(type(Extrusion))
Guids:
Christoph, thank you for your responses.
This is exactly what I ended up using yesterday.
For anyone that has encountered the same issue,
after you get extrusions from the family document using FilteredElementCollector.
You can obtain the Geometry of each extrusion, and iterate over the geometry to find the faces and check if the face is a planar face.
Something like this:
IList<Element> extrusions = extrusioncollector.ToElements();
PlanarFace? planarface = null;
foreach (Extrusion e in extrusions) { GeometryElement geom = e.get_Geometry(options); foreach (GeometryObject geomObj in geom) { if (geomObj is Solid solid) { foreach (Face face in solid.Faces) { if (face is PlanarFace) { planarface = face as PlanarFace; goto LoopEnd; } } } } }
Then you can use planarface.Reference in your CreateElectricalConnector method as your third argument.
Hope this helps, thank you!
Can't find what you're looking for? Ask the community or share your knowledge.