Beam/Column Faces Error

Beam/Column Faces Error

Anonymous
Not applicable
513 Views
4 Replies
Message 1 of 5

Beam/Column Faces Error

Anonymous
Not applicable

Hi All,

 

I'm trying to retrieve geometry data from an array of elements (walls, floors, columns and beams). When I use my algorithm with the walls and floors, there is no problem to get the Solid of the element.

 

 

Options opt = new Options(); 
opt.ComputeReferences = true;

foreach (Element e in listaElementos) { GeometryElement geoElement = e.get_Geometry(opt); foreach (GeometryObject obj in geoElement) { Solid geomSolid = obj as Solid; foreach (Face geomFace in geomSolid.Faces) { XYZ centroide = geomFace.Evaluate(new UV(0.5, 0.5)); // Se hace el chequeo para identificar el que está más arriba if (centroide.Z > ptoMasAlto) { puntoMasAlto = centroide; ptoMasAlto = centroide.Z; ide = e.Id; } // Se chequea cuál está más a la izquierda XYZ nuevoCentroide = new XYZ(centroide.X, centroide.Y, 0); XYZ comparacion = rle.PointOntoPlane(planoVista, nuevoCentroide); // Se compara la direccion de los vectores para obtener el que está más a la izquierda. XYZ vectorComp = (comparacion - izqPlano); double anguloComp = doc.ActiveView.RightDirection.AngleTo(vectorComp); if (Math.Abs(anguloComp - 0) > 0.1) { izqPlano = comparacion; puntoMasIzq = centroide; } } } }

But if I see what element is stored in my "listaElementos" list for beams and for columns there is a "FamilyInstance" element. Using the above code I get "null" when I ask for its solid and from then, it crashes.

 

Any tip of advice on how to get the faces for my columns and beams will be very appreciated.

 

Regards!

 

 

0 Likes
514 Views
4 Replies
Replies (4)
Message 2 of 5

BardiaJahan
Advocate
Advocate

When you perform get_Geometry() on a family instance, it includes a GeometryInstance object instead of solid. You must retrieve that and then use GetInstanceGeometry() to get the underlying geometry. And as you notice, you can use a recursive approach - not included here - which also works for nested families.

 

Options opt = new Options();
            opt.ComputeReferences = true;

            foreach (Element e in listaElementos)
            {

                GeometryElement geoElement = e.get_Geometry(opt);
                foreach (GeometryObject obj in geoElement)
                {
                    Solid geomSolid = obj as Solid;
                    foreach (Face geomFace in geomSolid.Faces)
                    {
                        XYZ centroide = geomFace.Evaluate(new UV(0.5, 0.5));

                        // Se hace el chequeo para identificar el que está más arriba
                        if (centroide.Z > ptoMasAlto)
                        {
                            puntoMasAlto = centroide;
                            ptoMasAlto = centroide.Z;
                            ide = e.Id;
                        }

                        // Se chequea cuál está más a la izquierda
                        XYZ nuevoCentroide = new XYZ(centroide.X, centroide.Y, 0);
                        XYZ comparacion = rle.PointOntoPlane(planoVista, nuevoCentroide);

                        // Se compara la direccion de los vectores para obtener el que está más a la izquierda.
                        XYZ vectorComp = (comparacion - izqPlano);

                        double anguloComp = doc.ActiveView.RightDirection.AngleTo(vectorComp);
                        if (Math.Abs(anguloComp - 0) > 0.1)
                        {
                            izqPlano = comparacion;
                            puntoMasIzq = centroide;
                        }
                    }

                    GeometryInstance geomInst = obj as GeometryInstance;
                    if (null != geomInst)
                    {
                        GeometryElement geoElementInst = geomInst.GetInstanceGeometry();
                        foreach (GeometryObject obj2 in geoElementInst)
                        {
                            .....
                        }
                    }

                }
            }

 

0 Likes
Message 3 of 5

Anonymous
Not applicable

Hi @BardiaJahan, thanks for your comments.

 

Finnally I made a Bypass like folowing:

 

 

foreach (Element e in listaElementos)
                {
                    GeometryElement geoElement = e.get_Geometry(opt);
                    foreach (GeometryObject obj in geoElement)
                    {
                        // Se chequea si es un Geometry Instance (Bean Column)
                        GeometryInstance geomInst = obj as GeometryInstance;

                        // Caso: Beams y Columns
                        if (null == geomInst)
                        {
                            Solid geomSolid = obj as Solid;
                            foreach (Face geomFace in geomSolid.Faces)
                            {
                                XYZ centroide = geomFace.Evaluate(new UV(0.5, 0.5));

                                // Se hace el chequeo para identificar el que está más arriba
                                if (centroide.Z > ptoMasAlto)
                                {
                                    puntoMasAlto = centroide;
                                    ptoMasAlto = centroide.Z;
                                    ide = e.Id;
                                }

                                // Se chequea cuál está más a la izquierda
                                XYZ nuevoCentroide = new XYZ(centroide.X, centroide.Y, 0);
                                XYZ comparacion = rle.PointOntoPlane(planoVista, nuevoCentroide);

                                // Se compara la direccion de los vectores para obtener el que está más a la izquierda.
                                XYZ vectorComp = (comparacion - izqPlano);

                                double anguloComp = doc.ActiveView.RightDirection.AngleTo(vectorComp);
                                if (Math.Abs(anguloComp - 0) > 0.1)
                                {
                                    izqPlano = comparacion;
                                    puntoMasIzq = centroide;
                                }
                            }
                            break;
                        }
                    } 
                }

I'll be attent to your comments.

 

Regads!

 

0 Likes
Message 4 of 5

BardiaJahan
Advocate
Advocate

Now, does it work for walls and floors that has no GeometryInstance?

0 Likes
Message 5 of 5

JimJia
Alumni
Alumni

You can try this method to get solids from base GeometryObject, hope it's helpful:

        /// <summary>
        /// Gets all solid objects from geometry object.
        /// </summary>
        /// <param name="gObj">Geometry object from where to get solids. </param>
        /// <returns>The solids of the geometry object. </returns>
        static public List<Solid> GetSolids(GeometryObject gObj)
        {
            List<Solid> solids = new List<Solid>();
            if (gObj is Solid) // already solid
            {
                Solid solid = gObj as Solid;
                // we don't want empty solid(face and volume is empty) here. 
                if (solid.Faces.Size > 0 && Math.Abs(solid.Volume) > 0) // some solid may have not any face?!
                    solids.Add(gObj as Solid);
            }
            else if (gObj is GeometryInstance) // find solids from GeometryInstance
            {
                IEnumerator<GeometryObject> gIter2 = (gObj as GeometryInstance).GetInstanceGeometry().GetEnumerator();
                gIter2.Reset();
                while (gIter2.MoveNext())
                {
                    solids.AddRange(GetSolids(gIter2.Current));
                }
            }
            else if (gObj is GeometryElement) // find solids from GeometryElement, this will not happen at all?
            {
                IEnumerator<GeometryObject> gIter2 = (gObj as GeometryElement).GetEnumerator();
                gIter2.Reset();
                while (gIter2.MoveNext())
                {
                    solids.AddRange(GetSolids(gIter2.Current));
                }
            }
            return solids;
        }

Jim Jia
Autodesk Forge Evangelist
https://forge.autodesk.com
Developer Technical Services
Autodesk Developer Network
Email: Jim.Jia@autodesk.com
0 Likes