Error when obtaining solids

Good morning.
I am having problems with my code when obtaining the solids of my element, I have already reviewed the code and tried several ways but I cannot find the error, I think I am getting confused with something else, please if someone could help me.
Thank you so much

I think my function is the one that is failing because apparently it is not accessing for “for s in opg:”

ERROR GET SOLID.dyn (13.1 KB)

import clr
import sys
import System
import time
from threading import Thread
from System.Collections.Generic import List

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

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import *

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

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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

clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import *

clr.AddReference("System.Drawing")
from System.Drawing import *

doc = DocumentManager.Instance.CurrentDBDocument

Entrada = UnwrapElement(IN[0])

Resultado = []

def EleSolido(Elementos):
    Solidos = []
    opg = Elementos.get_Geometry(Options())    
    for s in opg:
        if isinstance(s, Solid) and s.Volume > 0:
            try:
                sol = s.ToProtoType()
                Solidos.append(sol)
            except:
                return []
            break
        elif isinstance(s, GeometryInstance):
            geom = s.GetInstanceGeometry()
            for g in geom:
                if isinstance(g, Solid) and g.Volume > 0:
                    try:
                        sol = g.ToProtoType()
                        Solidos.append(sol)
                    except:
                        return []
                    break
    return Solidos[0]

class BarradeProgreso(Form):
    def __init__(self, Entrada):
        self.Text = "Ventana con Barra de Progreso"
        self.Width = 320
        self.Height = 100
        self.StartPosition = FormStartPosition.CenterScreen
        self.FormBorderStyle = FormBorderStyle.None
        self.BackColor = Color.FromArgb(200, 200, 200)
        self.MouseDown += self.on_mouse_down
        self.MouseMove += self.on_mouse_move

        self.TextoProceso = Label()
        self.TextoProceso.Text = "Procesando..."
        self.TextoProceso.Font = Font("Arial", 11, FontStyle.Bold)
        self.TextoProceso.AutoSize = True
        self.TextoProceso.Location = Point(10, 12)
        self.Controls.Add(self.TextoProceso)

        self.BarraProgreso = ProgressBar()
        self.BarraProgreso.Minimum = 0
        self.BarraProgreso.Maximum = len(Entrada) if Entrada else 1
        self.BarraProgreso.Value = 0
        self.BarraProgreso.Width = 300
        self.BarraProgreso.Location = Point(10, 35)
        self.Controls.Add(self.BarraProgreso)

        self.ProgresoText = Label()
        self.ProgresoText.Text = "0 / {}".format(len(Entrada))
        self.ProgresoText.Font = Font("Arial", 8)
        self.ProgresoText.AutoSize = True
        self.ProgresoText.Location = Point(10, 60)
        self.Controls.Add(self.ProgresoText)

        self.BotonAceptar = Button()
        self.BotonAceptar.Text = "ACEPTAR"
        self.BotonAceptar.Enabled = False
        self.BotonAceptar.Location = Point(80, 73)
        self.BotonAceptar.Click += self.aceptar_proceso
        self.Controls.Add(self.BotonAceptar)

        self.BotonCancelar = Button()
        self.BotonCancelar.Text = "CANCELAR"
        self.BotonCancelar.Enabled = True
        self.BotonCancelar.Location = Point(170, 73)
        self.BotonCancelar.Click += self.cancelar_proceso
        self.Controls.Add(self.BotonCancelar)

        self.cancelado = False

        def actualizar_progreso():
            global Resultado  
            for i, elemento in enumerate(Entrada):
                if self.cancelado:
                    return                
                try:
                    id_elemento = elemento.Id
                    solido = EleSolido(elemento) #  NOT GET SOLID OBJECT
                    
                    sublista_resultado = solido
                    Resultado.append(sublista_resultado)
                except Exception as ex:

                    Resultado.append([id_elemento, str(ex)])
                    
                self.BarraProgreso.Value = i + 1
                self.ProgresoText.Text = "{} / {}".format(i + 1, len(Entrada))
                Application.DoEvents()
                time.sleep(0.001)
            
            if not self.cancelado:
                self.TextoProceso.Text = "Proceso completado!"
                self.BotonAceptar.Enabled = True

        Thread(target=actualizar_progreso).start()

    def cancelar_proceso(self, sender, event):
        self.cancelado = True
        resultado = MessageBox.Show("El procesamiento de la información fue cancelado por el 'Usuario'.\nTodos los datos se perderán pero no afectarán al documento actual.", "Cancelar", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        if resultado == DialogResult.OK:
            self.Close()

    def aceptar_proceso(self, sender, event):
        self.Close()

    def on_mouse_down(self, sender, event):
        self.drag_start = event.Location

    def on_mouse_move(self, sender, event):
        if event.Button == MouseButtons.Left:
            self.Left += event.X - self.drag_start.X
            self.Top += event.Y - self.drag_start.Y


ventana_progreso = BarradeProgreso(Entrada)
ventana_progreso.ShowDialog()

OUT = Resultado

Hi,

here 2 examples

# Example 1 : return a list
def EleSolidoA(Elementos):
    Solidos = []
    global errors # a variable list in the global scope
    opg = Elementos.get_Geometry(Options())    
    if opg is not None:
        for s in opg:
            if isinstance(s, DB.Solid) and s.Volume > 0:
                try:
                    sol = s.ToProtoType()
                    Solidos.append(sol)
                except Exception as ex:
                    # catch the error
                    #print(ex) 
                    # or
                    errors.append(ex)
            elif isinstance(s, GeometryInstance):
                geom = s.GetInstanceGeometry()
                for g in geom:
                    if isinstance(g, DB.Solid) and g.Volume > 0:
                        try:
                            sol = g.ToProtoType()
                            Solidos.append(sol)
                        except Exception as ex:
                            # catch the error
                            #print(ex) 
                            # or
                            errors.append(ex)
    return Solidos
#
# Example 2: returns the solid 1ᵉʳ found or, failing that, the None object
def EleSolidoB(Elementos):
    global errors # a variable list in the global scope
    opg = Elementos.get_Geometry(Options())    
    if opg is not None:
        for s in opg:
            if isinstance(s, DB.Solid) and s.Volume > 0:
                try:
                    return s.ToProtoType()
                except Exception as ex:
                    # catch the error
                    #print(ex) 
                    # or
                    errors.append(ex)
            elif isinstance(s, GeometryInstance):
                geom = s.GetInstanceGeometry()
                for g in geom:
                    if isinstance(g, DB.Solid) and g.Volume > 0:
                        try:
                            return g.ToProtoType()
                        except Exception as ex:
                            # catch the error
                            #print(ex) 
                            # or
                            errors.append(ex)
    return None

errors = []

Thanks for the comment.
Question: Will you try the code and see if it works or what errors it returns?..

no, I just analyzed your code

I have tried the code examples and I still have the same problems and results.
Could you please take a look at the general code, maybe I am finding some conflict or library that I am not referencing correctly…??


what are the errors ?
OUT = errors

Here OUT = errors

try to replace
if isinstance(g, Solid) and g.Volume > 0:

by

if isinstance(g, DB.Solid) and g.Volume > 0:

1 Like

Wow… Thank you, I appreciate your response if the function worked.
Could you please tell me why in this case it is necessary to add the “DB” I mention it because in other codes the function does not require the “DB” and it works very well. Without your help I was about to look for a bridge to jump off of… thank you

1 Like

@AM3D.BIM.STUDIO Different libraries might have functions or classes with the same name. Using the full namespace avoids ambiguity and ensures that the correct function or class is being used.

1 Like