SOLID.ByUnion to PYTHON

Good morning.
I am trying to replicate in PYTHON the “SOLID.ByUnion” NODE where I can join all the solids inside the lists and return the united solid, thus maintaining the original number of indexes in the list.
Could someone please help me.

You just need to iterate over the sublists if I am understanding correctly.

Not at my PC but try this:

#after standard imports
listOfListsOfSolids = IN[0]
unionedSolids = [Solid.ByUnion(listOfSolids) for listOfSolids in listOfListsOfSolids]
OUT = unionedSolids

They are applying your recommendation but it returns an error, why?

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

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

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

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

def get_line_of_framing(framing, opt):
    if isinstance(framing.Location, DB.LocationCurve):
        return framing.Location.Curve.ToProtoType()
    
    geo_set = framing.get_Geometry(opt)
    for geo in geo_set:
        if isinstance(geo, DB.Line):
            return geo.ToProtoType()
    return None

opt = Options()
opt.DetailLevel = ViewDetailLevel.Coarse
opt.IncludeNonVisibleObjects = True

# Obtener todas las vigas en la categoría de "OST_StructuralFraming"
Vigas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralFraming).WhereElementIsNotElementType().ToElements()

# Primer filtrado: solo las vigas que tienen un eje válido
VigasConEjes = []
for viga in Vigas:
    eje = get_line_of_framing(viga, opt)
    if eje is not None:
        VigasConEjes.append(viga)       

# Segundo filtrado: de las vigas con eje, solo aquellas que pueden albergar refuerzos (Rebars)
VigasRebar = []
for e in VigasConEjes:
    # Verificar si la viga es un host válido para barras de refuerzo
    if DBS.RebarHostData.IsValidHost(e):
        VigasRebar.append(e)   
        
# Obtener sólidos de cada viga
SolidosPorViga = []
for e in VigasRebar:
    geoSet = e.get_Geometry(opt)
    solids = []
    if geoSet:
        for g in geoSet:
            if isinstance(g, DB.GeometryInstance):
                # Extraer sólidos de una instancia de geometría
                for gi in g.GetInstanceGeometry():
                    if isinstance(gi, DB.Solid) and gi.Volume > 0:
                        solids.append(gi.ToProtoType())
            elif isinstance(g, DB.Solid) and g.Volume > 0:
                # Agregar sólidos directamente
                solids.append(g.ToProtoType())    
    if solids:
        SolidosPorViga.append(solids)  # Agregar la lista de sólidos a la lista general
        
        
#Solidos Unidos
#***************ERRORRRRRRRRRRRRRRRRRR****************************************
SolidosUnidos = [Solid.ByUnion(listOfSolids) for listOfSolids in SolidosPorViga]

# Obtener Ejes de cada viga      
EjesVigas = []
for viga in VigasRebar:
    eje = get_line_of_framing(viga, opt)
    EjesVigas.append(eje)
    
OUT = VigasRebar, EjesVigas, SolidosUnidos

You’re importing both the Revit Solid class and the Dynamo Solid class, so not just the standard boilerplate.

This means that you need to call out which ‘Solid’ you’re using, Dynamo’s or Revit’s. Calling out the namespace as a prefix (typically Revit.DB. or Geometry) will ensure you always use the right namespace. However…

You also have an alias of DS for the Dynamo Geometry class, which is a common way of ensuring no namespace collision issues while ensuring you always get Dynamo’s geometry library. So you need to use that as your prefix.

So instead of typing only Solid to call the Dynamo Solid class you would use DS.Solid instead.

Thank you very much for your time, I still need a lot of practice to be able to identify the errors well… thank you

1 Like