Retrieving points of top face of a beam

Retrieving points of top face of a beam

Anonymous
Not applicable
3,685 Views
11 Replies
Message 1 of 12

Retrieving points of top face of a beam

Anonymous
Not applicable

Hi there,

 

I want to define the top surface plane of a structural beam.

 

So I need to retrieve at least 3 points from the top face of a structural beam. However, with the following code, I am stuck.  

 

FilteredElementCollector collector = new FilteredElementCollector(Global.doc()).WhereElementIsNotElementType().OfCategory(BuiltInCategory.OST_StructuralFraming); // select all structural framing(beams)
List<Element>  beamList = collector.ToList(); // select all structural beams as a List
for (int i = 0; i < allBeamList.Count; i++)
{
                    beamGeo = beamList[i].get_Geometry(geomOptions);
                    foreach (GeometryObject geomObj in beamGeo)
                    {
                        geomSolid = geomObj as Solid;
                        try
                        {
                            foreach (Face geomFace in geomSolid.Faces)
                            {
                                face = geomFace;
                                edges = face.GetEdgesAsCurveLoops();
                                break;
                            }
                        }
                        catch{}
                    }
}

From the edges following info is got but I couldn't make sense of any of them. Any help is much appreciated!

- [Autodesk.Revit.DB.Line] {Autodesk.Revit.DB.Line} Autodesk.Revit.DB.Line
+ Direction {(0.883461516, -0.468503734, 0.000000000)} Autodesk.Revit.DB.XYZ
+ Origin {(41.600096955, 43.315422219, 0.984251969)} Autodesk.Revit.DB.XYZ

0 Likes
Accepted solutions (1)
3,686 Views
11 Replies
Replies (11)
Message 2 of 12

jeremytammik
Autodesk
Autodesk
0 Likes
Message 3 of 12

Anonymous
Not applicable

Jeremy thanks for replying. I think the face approach might be the long way to get where I want...

 

I actually just need the coordinates on top of the beam's four corners. Would there be another method to retrieve these as points(X,Y,Z)?

 

2019-12-24_11-15-11.png

0 Likes
Message 4 of 12

Moustafa_K
Collaborator
Collaborator
Accepted solution

1st you need to only select the faces that points towards +Z (to get the inclined and the horizantal top faces)

```

if (face.ComputeNormal(new UV(.5,.5)).Z > 0)

```

by then you will be able to get the only top Faces.

then after loop through the faces --> edges (like in your example)

```

edges = face.GetEdgesAsCurveLoops();
foreach (var edge in edges)
{
XYZ topBeamPoint = edge .AsCurve().GetEndPoint(0); //this is the start point of an edge
}

now you can collect all the top beam points and do you math.

hope that helps.

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes
Message 5 of 12

zrodgersTSSSU
Advocate
Advocate

@Anonymous Did you have the corrected code for this? I am tryin to do something similar and it would be a great starting point.

0 Likes
Message 6 of 12

jeremy_tammik
Alumni
Alumni

The proper way to retrieve the top face of the beam is to retrieve the beam solid, query it for its faces and pick the one whose normal vector points upwards. From that face, you can retrieve the corner vertices or any other point you want.

 

Another approach that will probably achieve what is asked for here is to retrieve all the beam solid's vertices and pick the three with the largest Z coordinate.

 

Both of these approaches are illustrated by The Building Coder in numerous different examples, e.g.:

 

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 7 of 12

zrodgersTSSSU
Advocate
Advocate

@jeremy_tammik Thanks for the response. I was trying to get a starting point but ended up writing it out anyways. 

 

This was how i got the top and bottom, had to do some funky stuff to get the faces I wanted depending on beam angle. but it worked out.

foreach (GeometryObject o in instGeoElem)
                                        {
                                            Solid solid = o as Solid;
                                            if (solid != null)
                                            {
                                                foreach (Face geoFace in solid.Faces)
                                                {
                                                    //filters top size faces//
                                                    double faceTZ = geoFace.ComputeNormal(new UV(0.5, 0.5)).Z;

                                                    //gets top faces
                                                    if (faceTZ > 0.0)
                                                    {
                                                        if (faceTZ >= maxZ)
                                                        {
                                                            maxZ = faceTZ;
                                                            maxFaces.Add(geoFace);
                                                            //get largerst top face
                                                            foreach(Face f in maxFaces)
                                                            {
                                                                if (f.Area > topLargestArea)
                                                                {
                                                                    topLargestArea = f.Area;
                                                                    largestTopFace = f;
                                                                    topNormal = f.ComputeNormal(new UV(0.5, 0.5));
                                                                }

                                                            }
                                                            
                                                        }

                                                    }
                                                    else
                                                    {
                                                        double faceBZ = geoFace.ComputeNormal(new UV(0.5, 0.5)).Z;

                                                        //filters bottom size faces
                                                        if (faceBZ < 0.0)
                                                        {
                                                            if(faceBZ <= minZ)
                                                            {
                                                                minZ = faceBZ;
                                                                minFaces.Add(geoFace);
                                                                foreach(Face f in minFaces)
                                                                {
                                                                    //get largerst top face
                                                                    if (f.Area > bottomLargestArea)
                                                                    {
                                                                        bottomLargestArea = f.Area;
                                                                        largestBottomFace = f;
                                                                        bottomNormal = f.ComputeNormal(new UV(0.5, 0.5));
                                                                    }

                                                                }
                                                            }
                                                            
                                                        }
                                                    }
                                                }
                                            }
                                        }

 

0 Likes
Message 8 of 12

Houba3314
Enthusiast
Enthusiast

Hello i want to place an object (Generic model) on the face of a beam ! can u guide me how to do that . its my first time doing this.

0 Likes
Message 9 of 12

jeremy_tammik
Alumni
Alumni

I suggest starting by studying this description of my early exploration into a very similar task in 2010:

  

https://thebuildingcoder.typepad.com/blog/2010/01/spot-elevation-creation-on-top-of-beam.html

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 10 of 12

RPTHOMAS108
Mentor
Mentor

The symbol position is laid out as in the family template it is then transformed to the instance position via the instance transform. That process can also be reversed via inverse of instance transform. 

0 Likes
Message 11 of 12

Houba3314
Enthusiast
Enthusiast

hello again, i am able to find the faces of the beam and get intersection beween a beam and a duct now i want to place and element at that intersection . when i use doc.create.newfamilyinstance i cant use it wiht reference as a parameter because beam is not a host object  i tried it other overload and it did create it but not on the same level (height) i dont know the technical word im sorry i mostly do web dev so this is new to me .

0 Likes
Message 12 of 12

Houba3314
Enthusiast
Enthusiast

Sorry i didnt understand you can you provide a code or something

0 Likes