Intersect door magnet with corresponding door, how?

Hello,

i have the topic allready solved in dynamo. and it runs amazing, BUT in Python i come to my limits:

  • i can collect my items (also linked)
  • i can get my values
  • i can get locations

but

  • i can`t create sphere
  • i can`t intersect elements
  • i can`t get the result

this my code so far

#🌈 links
linked_docs = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_RvtLinks).WhereElementIsNotElementType().ToElements()
lnkInstance = [i for i in linked_docs if i.Name.Contains("FM_AR")]
doclnk = lnkInstance[0].GetLinkDocument()

# 🛒 collect doors from linked file
doors = FilteredElementCollector(doclnk).OfCategory(BuiltInCategory.OST_Doors).WhereElementIsNotElementType().ToElements()

# 🔶 get Doornumbers
doorNumbers = [i.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() for i in doors]

# ❓ Evaluate None Error
lis = []

for i in doorNumbers:
    if i == None:
        lis.append("---")
    else:
        lis.append(i)

# 1️⃣ Collector
collector = FilteredElementCollector(doc)\
    .OfCategory(BuiltInCategory.OST_ElectricalFixtures)\
    .WhereElementIsNotElementType()\
    .ToElements()

# 🧲 holding magnets
magnets = [i for i in collector if doc.GetElement(i.GetTypeId()).Family.Name.Contains("Haltemagnet")]

# 1️⃣ origin of magnets
locationPoints = [i.Location.Point for i in magnets]

# 2️⃣ point at magnet
points = []

for i in locationPoints:
    revit_xyz = XYZ(i.X,i.Y,i.Z)
    revit_point = Point.Create(revit_xyz)
    points.append(revit_point)

# 🔵 spheres for clash
spheres = []

for i in points:
    radius = 1
    dummy = GeometryCreationUtilities.CreateSphere(doc, i, radius, SolidOptions())
    spheres.append(dummy)

print("\n{}".format(len(magnets)))
print("\n{}".format(doclnk))
print("\n{}".format(len(doors)))

i tried also with directShape, but there is no sphere at least i got no error

t = Transaction(doc,"Sphere")
t.Start()

spheres = []

for i in points:
    radius = 1
    geo = GeometryCreationUtilities.CreateSphere(doc, i, radius, SolidOptions())
    # Create DirectShape element
    geo = DirectShape.CreateElement(doc, ElementId.InvalidElementId)
    geo.ApplicationId = "Dummy"
    geo.ApplicationDataId = "ToClash"
    geo.SetShape([geo])
    spheres.append(geo)

t.Commit()

GeometryCreationUtilities has no CreateSphere() method. You have to use CreateRevolvedGeometry() ApiDocs.co but you can’t get away with only the radius, you have to provide the axis of rotation and the profile that is a half circle.

Do you really need an actual sphere geometry? Using a simple BoundingBox would be much faster :bulb:

1 Like

@thumDer ,

i will try direct shape methode … so chatGPT is playing with me :wink:

the issue is i need just a simple clashtest. a Sphere is the best geometrical form to test “whats near by!”

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



def CreateCenterbasedSphere(center, radius):

    frame = Frame(center,
            XYZ.BasisX,
            XYZ.BasisY,
            XYZ.BasisZ)
    
    profileloops = List[CurveLoop]() 
    profileloop  = CurveLoop()
    
    cemiEllipse = Ellipse.CreateCurve(center, radius, radius,
                                        XYZ.BasisX,
                                        XYZ.BasisZ,
                                        -math.pi / 2.0, math.pi / 2.0)
    
    profileloop.Append(cemiEllipse);
    profileloop.Append(Line.CreateBound(
    XYZ(center.X, center.Y, center.Z + radius),
    XYZ(center.X, center.Y, center.Z - radius)))
    profileloops.Add(profileloop);
    
    return GeometryCreationUtilities.CreateRevolvedGeometry(frame, profileloops, -math.pi, math.pi)
    

# Create Sphere
pt = XYZ(1,1,1)
r  = 1
sphere = CreateCenterbasedSphere(pt, r)

print(sphere)

# Transaction
t = Transaction(doc, 'test')
t.Start()

# Create DS Shape


ds = DirectShape.CreateElement(doc, ElementId(BuiltInCategory.OST_GenericModel))
ds.SetShape([sphere])

t.Commit()

ChatGPT likes to hallucinate a lot of non-existing Revit API classes and methods, you always have to double check, if those are valid, using apidocs.co. Instead of the Ellipse class you should use the Arc class.
You are right about that the Sphere represent a constant distance range from a point, but using an actual solid geometry for intersection check in an ElementIntersectsSolidFilter is much slower than using a boundingbox in a BoundingBoxIntersectsFilter.
Also, for the former ElementIntersectsSolidFilter you don’t even need the actual DirectShape element, you can already use the Solid you are setting as the DirectShapes geometry by itself.

3 Likes