Structural Framing Centerline

Structural Framing Centerline

Anonymous
Not applicable
4,475 Views
14 Replies
Message 1 of 15

Structural Framing Centerline

Anonymous
Not applicable

I've been trying to find an accurate way of getting the beam location line. I know I can use the internal LocationCurve that is provided from a Structural Framing element. But this does not take into account any post-processing such as Z offset or Y offset, whether uniform or independent. Is there an accurate way of getting the "centerline" of the post-processed structural framing location?

 

 

0 Likes
Accepted solutions (1)
4,476 Views
14 Replies
Replies (14)
Message 2 of 15

augusto.goncalves
Alumni
Alumni
Aren't you looking for the Analytical Model?
Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network
0 Likes
Message 3 of 15

Anonymous
Not applicable

The analytical model lines do not always reflect where the actual beam geometry is located. I'm looking for a way to access the Top Face centerline of beam geometry through the API. I know I can use location line, but that also does not reflect changes to Y/Z justification or Z/Y offset, etc.

0 Likes
Message 4 of 15

jeremytammik
Autodesk
Autodesk

Dear Max,

 

You sent me an email pointing to this thread and asking, "I’ve been racking my brain about how to accurately get the centerline of the top face of beam geometry or any structural framing geometry. If you can maybe give me some pointers I would greatly appreciate it."

 

I can answer that. To be more precise, I already did so, on January 28, 2010, discussing Spot Elevation Creation on Top of Beam:

 

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

 

I hope this helps.

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 5 of 15

Anonymous
Not applicable
Thank you so much Jeremy. I'll take a look at the provided information, somehow I wasn't able to find that blog post before.
0 Likes
Message 6 of 15

Anonymous
Not applicable

I've tried to get this method to work, and it does find the "top" face, but fails on steeper beams.

 

Here is the face I'm looking for:

Top Face.PNG

 

On beams steeper than ~28 degrees, this is the face it gives me:

Top Face2.PNG

0 Likes
Message 7 of 15

Anonymous
Not applicable

Here is a snippet of my code, I've only been coding in C# and the Revit API for a short while. So my code probably looks awful.

 

                    Reference pickedRef = null;
                    Selection sel = uiApp.ActiveUIDocument.Selection;

                    // Pick a beam
                    BeamPickFilter selFilter = new BeamPickFilter();
                    pickedRef = sel.PickObject(ObjectType.Element, selFilter,
                      "Please select a WF or C-Channel beam");

                    Element elem = doc.GetElement(pickedRef);
                    FamilyInstance instance = elem as FamilyInstance;
                    Options m_options = doc.Application.Create.NewGeometryOptions();

                    Face TopFace = null;

                    GeometryElement instanceGeo = instance.get_Geometry(m_options);
                    GeometryElement slaveGeo = instance.GetOriginalGeometry(m_options);
                    GeometryElement transformGeo = slaveGeo.GetTransformed(instance.GetTransform());

                    // show geometry that was transformed
                    IEnumerator<GeometryObject> Objects2 = transformGeo.GetEnumerator();
                    while (Objects2.MoveNext())
                    {
                        GeometryObject obj = Objects2.Current;

                        if (obj is Solid)
                        {
                            Solid solid = obj as Solid;
                            double z = double.MinValue;
                            foreach (Face f in solid.Faces)
                            {
                                BoundingBoxUV b = f.GetBoundingBox();
                                UV p = b.Min;
                                UV q = b.Max;
                                UV midparam = p + 0.5 * (q - p);
                                XYZ midpoint = f.Evaluate(midparam);
                                XYZ normal = f.ComputeNormal(midparam);

                                if (Util.PointsUpwards(normal))
                                {
                                    if (midpoint.Z > z)
                                    {
                                        z = midpoint.Z;
                                        TopFace = f;
                                    }
                                }
                            }
                        }
                    }

 

 

I'm thinking that I need to find a new way to analyze the geometry, but I'm not sure where to go from here. 

0 Likes
Message 8 of 15

Revitalizer
Advisor
Advisor

Hi,

 

you could compare also

 

  • the number of vertices of the faces (front face: 12, top face: 4)
  • the location curve's direction with faces' normals and negative normals (to exclude front faces)
  • the area of the faces (fron face is smaller than top face)

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





Message 9 of 15

Anonymous
Not applicable
Thank you for the ideas, I'll go ahead and give them a try.
0 Likes
Message 10 of 15

jeremytammik
Autodesk
Autodesk

Can you share your final solution, please in case anyone else runs into the same need?

 

Thank you!



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 11 of 15

Anonymous
Not applicable

Its not really a pretty solution (it works in most cases), what I did is get the origin point of the beam geometry, then generated a line from that:

 

                // Get origin point of transformed beam geometry
                XYZ origin = instance.GetTransform().Origin;

                // Offset the origin point vertically by 50 units
                XYZ originOffsetZ = new XYZ(origin.X, origin.Y, (origin.Z + 50));

                // Create a line between the origin and origin offset point
                Line originIntersect = Line.CreateBound(origin, originOffsetZ);

 

 

// Determine if top most face by checking if the line created between 
// origin point and offset origin point intersects with the face
IntersectionResultArray results; SetComparisonResult result = f.Intersect(originIntersect, out results); if (result == SetComparisonResult.Overlap) { TopFace = f; }

Where this will fail is if your beam start or end extension (or Start / End Join Cutback) is so great that the origin point is no longer within the beam geometry. Also this method will fail if you rotate the beam cross section. So it's not foolproof.

 

The likelyhood of this kind of modification to the geometry is pretty low, and I have not come across an instance where it has failed in practice.

 

Here is an example where it won't work (the analytical line is shown to demonstrate what the original beam geometry was before modifying the Start Join Cutback value)

 

Beam Origin.PNG

 

There's most likely a much better way of doing this, that will find the face I'm looking for in every case. But I have not been able to figure it out.

 

I was maybe thinking of analyzing the "original" beam geometry and somehow getting a unique id for the top face, and then from that id being able to use it to work with the transformed geometry face.

 

I'm hesitant of saying this is really a "solution". I would love to find a way of being able to get the face I need every time, no matter how the geometry has been manipulated.

Message 12 of 15

jeremytammik
Autodesk
Autodesk

There are indeed easier and more foolproof solutions.

 

You can just grab all the faces' normal vectors and choose the face whose normal face is 'most vertical', i.e., has the smallest angle between it and the Z axis.

 

If you are not interested in the end faces of the beam and wish the end face to be ignored even if the beam is very steep, then you can add a check for the surface area of the face, .e.g. to eliminate the two end faces, which will presumably have the smallest area. You can also easily eliminate the end faces by rejecting any face whose normal vector is parallel to the beam location line.

 

I hope this is clear and provides you with enough to achieve a really satisfactory solution for all cases.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 13 of 15

Anonymous
Not applicable

The end faces will not always have the smallest area when the beam is short.

 

Also, 

 

"You can also easily eliminate the end faces by rejecting any face whose normal vector is parallel to the beam location line."

 

The beam location line doesn't move when you do post processing on the beam, the beam location line stays in basically the same place as the analytical line that is shown here.

 

Beam Example.PNG

 

 

Location line curve start and end points:

Location Curve Start End.PNG

 

Analytical line curve start and end points:

Analytical Curve.PNG

0 Likes
Message 14 of 15

Anonymous
Not applicable
Accepted solution

On further thinking, the only time the end face areas would be greater is when the beam will be extremely short. Something that is unlikely to ever occur.

 

I've revised the code as follows:

// Areas of all Top(ish) faces
IList<double> fAreas = new List<double>();

// Array to hold faces
FaceArray topishFaces = new FaceArray();

// This was taken from the CmdNewSpotElevation example
// that is provided by Jeremy Tammik (The Building Coder)
BoundingBoxUV b = f.GetBoundingBox();
UV p = b.Min;
UV q = b.Max;
UV midparam = p + 0.5 * (q - p);
XYZ midpoint = f.Evaluate(midparam);
XYZ normal = f.ComputeNormal(midparam);

if (Util.PointsUpwards(normal))
{
    fAreas.Add(f.Area);
    topishFaces.Append(f);
}

// Analyze top(ish) face areas
foreach (Face face in topishFaces)
{
    if((fAreas.Max() - face.Area) <= areaDiff)
    {
        TopFace = face;
    }
}

Thank you so much for all your help and suggestions Jeremy!

0 Likes
Message 15 of 15

jeremytammik
Autodesk
Autodesk

Very cool.

 

My pleasure entirely.

 

I like your nomenclature, e.g., 'Top(ish)'.

 

🙂

 

Thank you for your appreciation.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes