Get intersected solid from Pipe Fitting and Floor and display solid result in Background Dynamo

Hello
I’d like to know whether a pipe connection or a pipe intersects with a floor.
In the case of a pipe, when I use the Element.Geometry block, it returns a solid.
However, in the case of a pipe connection, it returns an empty list.
So I used some Python code to make sure I got the solid in both cases.
ComputerIntersect.py (5.1 KB)

This works and I can then obtain the solid resulting from the intersection.

However, I still have two problems:
The first is that when I select a pipe and a floor using the Geometry.Intersect block, it displays the solid resulting from the intersection in the 3D view. How can I display the result of my intersection solid obtained from my Python code in Dynamo’s 3D view?
The other problem is that when I return the Solid.Volume from my Python code and from the Dynamo blocks, I don’t get the same result. Why? A problem with the units?

Hello @Sona_Architecture

You have to understand the difference between Revit objects and Desgnscript/Dynamo Objects.

Using Dynamo nodes you work with Dynamo elements, you can see the geometry in the Dynamo 3D view.

In python you can work with Dynamo elements or with Revit elements.

You have created a
Autodesk.DesignScript.Geometry.Solid with the dynamo core nodes, but you have created a Autodesk.Revit.DB.Solid with your python code.

You will never ever see Revit.DB elements in the Dynamo 3d view.

Converting Dynamo and Revit elements to each other is not possible for Solids!

For your understanding, everything you can find here is related to Revit elements only: https://www.revitapidocs.com/

Here a comparison how you work with revit solids and dynamo soilds in python:

Dynamo solid:
solidA.Intersect(solidB)

Revit solid:
BooleanOperationsUtils.ExecuteBooleanOperation(solidA, solidB, BooleanOperationsType.Intersect)

If you want to work with revit elements but you want to see them in dynamo background you have to use a workaround. One way would be to extract faces from the revit solid and convert them to dynamo surfaces, these can be seen in den 3D view. Another workaround is to export the solid to a SAT file and import it back with dynamo nodes. Another workaround is creating an importinstance from the solid, explode it and use the resulting FreeForm object in dynamo.

If you want to use dynamo methods in python you need to import

from Autodesk.DesignScript.Geometry import *

As you are aware of how to work with Revit.DB elements, here is an example code that works with dynamo elements.

import clr

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

def solids_intersect(solid1, solid2):
    try:
        intersection = Solid.Intersect(solid1, solid2)
        if intersection:
            return True
    except:
        pass
    return False

input_solid = IN[0]
list_of_solids = IN[1]

intersecting_solids = []

for solid in list_of_solids:
    if solids_intersect(input_solid, solid):
        intersecting_solids.append(solid)

OUT = intersecting_solids

With the node to code feature you can convert pretty much all dynamo core nodes to designscript code, so working with dynamo elements in python is easier than working with revit elements.

Hi @gerhard.p
Thank you for your very clear answer ! :grinning:

I fully understand the difference that now exists between Dynamo solids and Revit solids.
I’ve tested the Solid.Intersect(solidA, solidB) method on Dynamo solids and it works well.

Now, in the case of a pipe connection, I have to use Revit’s method to find out which solid intersects between my two Revit solids obtained from my def get_target_solids because Element.Geometry returns me an empty solids (normal because it’s a GeometryInstance).

So I found this method to transform Revit Geometry to Dynamo geometry :
It works!

Thanks a lot!

1 Like

You are right, my mistake, it´s just one direction that doesn´t work for solids, you can´t convert from dynamo solid to revit solid. But that’s not your intent.

Sample file with error:

[
  [
    Autodesk.Revit.DB.Solid,
    Solid,
    Solid,
    An internal error has occurred.
   at Autodesk.Revit.DB.TessellatedShapeBuilder.Build()
   at Revit.GeometryConversion.ProtoToRevitMesh.ToRevitType(Solid solid, TessellatedShapeBuilderTarget target, TessellatedShapeBuilderFallback fallback, ElementId MaterialId, Boolean performHostUnitConversion)
  ]
]
import clr

# Add Revit API reference
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
# Add Dynamo references for geometry conversion
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk
# Add RevitNodes reference for ToProtoType, ToRevitType conversion methods
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

# Add Dynamo services reference for transactions
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Import List from System.Collections.Generic to handle lists of elements
from System.Collections.Generic import List

# Get the current Revit document
doc = DocumentManager.Instance.CurrentDBDocument

# Function to create a Revit solid (a simple box for this example)
def create_revit_solid(width, height, depth):
    # Start a transaction to create a Revit solid
    TransactionManager.Instance.EnsureInTransaction(doc)
    
    # Create a list to hold the boundary curves
    curves = List[DB.Curve]()
    
    # Define the four corners of the base
    pt1 = DB.XYZ(0, 0, 0)
    pt2 = DB.XYZ(width, 0, 0)
    pt3 = DB.XYZ(width, height, 0)
    pt4 = DB.XYZ(0, height, 0)
    
    # Create the rectangle's boundary lines using fully qualified namespace
    line1 = DB.Line.CreateBound(pt1, pt2)
    line2 = DB.Line.CreateBound(pt2, pt3)
    line3 = DB.Line.CreateBound(pt3, pt4)
    line4 = DB.Line.CreateBound(pt4, pt1)
    
    # Add the lines to the curve list
    curves.Add(line1)
    curves.Add(line2)
    curves.Add(line3)
    curves.Add(line4)
    # Create a curve loop from the curves
    curve_loop = CurveLoop()
    for curve in curves:
        curve_loop.Append(curve)

    # Use the CurveLoop to create a solid by extrusion
    extrusion = GeometryCreationUtilities.CreateExtrusionGeometry([curve_loop], XYZ.BasisZ, depth)

    # Commit the transaction
    TransactionManager.Instance.TransactionTaskDone()
    
    return extrusion  # This is your solid
    
# Function to create a Dynamo solid (a simple extruded cylinder)
def create_dynamo_solid(radius=5, depth=10):
    # Create a circle with Z = 0
    center_point = Point.ByCoordinates(0, 0, 0)
    circle = Circle.ByCenterPointRadius(center_point, radius)
    
    # Create a surface from the circle by extrusion
    solid = circle.ExtrudeAsSolid(depth)

    # Clean up intermediate geometry if necessary
    circle.Dispose()
    return solid

# Define dimensions for the box
width, height, depth = 10, 10, 10

# Create Revit and Dynamo solids
revit_solid = create_revit_solid(width, height, depth)
dynamo_solid = create_dynamo_solid()

# Convert the Revit solid to a Dynamo solid
dynamo_solid_from_revit = revit_solid.ToProtoType()

# Convert the Dynamo solid to a Revit solid
try:
    revit_solid_from_dynamo = dynamo_solid.ToRevitType(True)
except Exception as e:
    revit_solid_from_dynamo = str(e)
# Output the solids
OUT = revit_solid, dynamo_solid, dynamo_solid_from_revit, revit_solid_from_dynamo

Thank you @gerhard.p for this additional information