Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FamilyInstance Symbol vs Instance - Column behavior

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
lvirone
277 Views, 2 Replies

FamilyInstance Symbol vs Instance - Column behavior

lvirone
Enthusiast
Enthusiast

Hello,

 

Introduction

First let me introduce what I understand on the geometry of a FamilyInstance. A FamilyInstance have GeometryInstance which can give you two kind of Geometry:

  1. Symbol : The geometry of the FamilyInstance in the Family coordinates, so you need to apply the Transform of the Family to get the Geomety you see in Model.
  2. Instance : The Geometry you see in Model in the correct position, but it doesn't compute reference so I banned it.

 

Some links which can be useful :

https://www.revitapidocs.com/2016/d3567707-4f77-5ed8-16f4-6d57411cf41b.htm

https://forums.autodesk.com/t5/revit-api-forum/getinstancegeometry-vs-getsymbolgeometry/td-p/1081688...

https://thebuildingcoder.typepad.com/blog/2010/02/retrieving-column-and-stair-geometry.html

 

The problem with columns

In all kind of objects I tested, what I explained with Symbol geometry which needs to be Transformed is True, BUT for columns it's like the Transform is already made in the Symbol geometry!

 

I must precise that I tested with custom columns in my own template, but I tested too with the same result in Revit base template "Systems-Default_Metric.rte" using Revit base Family "UC-Universal Column-Column".

 

What works for me (for now)

I created a method which identify if it's a column to decide if the Transform must be applied or not, but it doesn't look robust.

 

        
        /// <summary>
        /// Get the geometry of an element
        /// </summary>
public static List<Solid> GetGeometry(this Element elem, Options geomOptions)
        {
            //var doc = elem.Document;
            var solidList = new List<Solid>();

            if (geomOptions != null)
            {
                var geoElem = elem.get_Geometry(geomOptions);

                if (geoElem != null)
                {
                    foreach (var geomObj in geoElem)
                    {
                        if (geomObj is Solid obj) solidList.Add(obj);

                        //handle_geometry_instances - START
                        if (geomObj is GeometryInstance geoInst)
                        {
                            //InstanceGeometry return the TRUE geometry BUT it doesn't compute Reference so don't use it !!!!!
                            var geoE = geoInst.GetSymbolGeometry();

                            if (elem.TransformThisObjectGeometryToGetTheTrueGeometry()) geoE = geoInst.GetSymbolGeometry(((FamilyInstance)elem).GetTotalTransform());

                            foreach (var gObj2 in geoE)
                            {
                                var geoSolid2 = gObj2 as Solid;
                                if (geoSolid2 != null) solidList.Add(geoSolid2);
                            }
                        }
                        //handle_geometry_instances - END
                    }
                }
            }

            return solidList;
        }

        
        /// <summary>
        /// Use This method to determine if an Element Geometry need to be Transformed using (Element as FamilyInstance).GetTotalTransform()
        /// </summary>
        /// <returns>True if need to be transformed</returns>
        public static bool TransformThisObjectGeometryToGetTheTrueGeometry(this Element elem)
        {
            var cat = (BuiltInCategory)elem.Category.IdAsInt();

            return elem is FamilyInstance
                   && cat != BuiltInCategory.OST_Columns 
                   && cat != BuiltInCategory.OST_StructuralColumns;
        }

 

 

Question

Am I missing something? If not, is there others kind of Family with this Geometry behavior? Is it possible to identify them with a more robust approach?

 

It would be awesome if my method "GetGeometry" abstract this behavior.

 

Thanks

0 Likes

FamilyInstance Symbol vs Instance - Column behavior

Hello,

 

Introduction

First let me introduce what I understand on the geometry of a FamilyInstance. A FamilyInstance have GeometryInstance which can give you two kind of Geometry:

  1. Symbol : The geometry of the FamilyInstance in the Family coordinates, so you need to apply the Transform of the Family to get the Geomety you see in Model.
  2. Instance : The Geometry you see in Model in the correct position, but it doesn't compute reference so I banned it.

 

Some links which can be useful :

https://www.revitapidocs.com/2016/d3567707-4f77-5ed8-16f4-6d57411cf41b.htm

https://forums.autodesk.com/t5/revit-api-forum/getinstancegeometry-vs-getsymbolgeometry/td-p/1081688...

https://thebuildingcoder.typepad.com/blog/2010/02/retrieving-column-and-stair-geometry.html

 

The problem with columns

In all kind of objects I tested, what I explained with Symbol geometry which needs to be Transformed is True, BUT for columns it's like the Transform is already made in the Symbol geometry!

 

I must precise that I tested with custom columns in my own template, but I tested too with the same result in Revit base template "Systems-Default_Metric.rte" using Revit base Family "UC-Universal Column-Column".

 

What works for me (for now)

I created a method which identify if it's a column to decide if the Transform must be applied or not, but it doesn't look robust.

 

        
        /// <summary>
        /// Get the geometry of an element
        /// </summary>
public static List<Solid> GetGeometry(this Element elem, Options geomOptions)
        {
            //var doc = elem.Document;
            var solidList = new List<Solid>();

            if (geomOptions != null)
            {
                var geoElem = elem.get_Geometry(geomOptions);

                if (geoElem != null)
                {
                    foreach (var geomObj in geoElem)
                    {
                        if (geomObj is Solid obj) solidList.Add(obj);

                        //handle_geometry_instances - START
                        if (geomObj is GeometryInstance geoInst)
                        {
                            //InstanceGeometry return the TRUE geometry BUT it doesn't compute Reference so don't use it !!!!!
                            var geoE = geoInst.GetSymbolGeometry();

                            if (elem.TransformThisObjectGeometryToGetTheTrueGeometry()) geoE = geoInst.GetSymbolGeometry(((FamilyInstance)elem).GetTotalTransform());

                            foreach (var gObj2 in geoE)
                            {
                                var geoSolid2 = gObj2 as Solid;
                                if (geoSolid2 != null) solidList.Add(geoSolid2);
                            }
                        }
                        //handle_geometry_instances - END
                    }
                }
            }

            return solidList;
        }

        
        /// <summary>
        /// Use This method to determine if an Element Geometry need to be Transformed using (Element as FamilyInstance).GetTotalTransform()
        /// </summary>
        /// <returns>True if need to be transformed</returns>
        public static bool TransformThisObjectGeometryToGetTheTrueGeometry(this Element elem)
        {
            var cat = (BuiltInCategory)elem.Category.IdAsInt();

            return elem is FamilyInstance
                   && cat != BuiltInCategory.OST_Columns 
                   && cat != BuiltInCategory.OST_StructuralColumns;
        }

 

 

Question

Am I missing something? If not, is there others kind of Family with this Geometry behavior? Is it possible to identify them with a more robust approach?

 

It would be awesome if my method "GetGeometry" abstract this behavior.

 

Thanks

2 REPLIES 2
Message 2 of 3
jeremy_tammik
in reply to: lvirone

jeremy_tammik
Autodesk
Autodesk

I wonder if your first assumption is correct: 

  

> Symbol : The geometry of the FamilyInstance in the Family coordinates, so you need to apply the Transform of the Family to get the Geometry you see in Model.

  

My understanding is slightly different in one important point: if i define a rectangular column family and place an instance into the model with no joins or intersections, then what you say holds. However, if joins or intersections occur, the instance geometry will be affected by those, and the symbol geometry will not. So, just transforming the symbol geometry will not always return the geometry you see in the model. Do you agree on that?

  

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

I wonder if your first assumption is correct: 

  

> Symbol : The geometry of the FamilyInstance in the Family coordinates, so you need to apply the Transform of the Family to get the Geometry you see in Model.

  

My understanding is slightly different in one important point: if i define a rectangular column family and place an instance into the model with no joins or intersections, then what you say holds. However, if joins or intersections occur, the instance geometry will be affected by those, and the symbol geometry will not. So, just transforming the symbol geometry will not always return the geometry you see in the model. Do you agree on that?

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 3 of 3
lvirone
in reply to: jeremy_tammik

lvirone
Enthusiast
Enthusiast
Accepted solution

Yes I agreed with you until I tested it in a Revit Model and I saw something even more strange  😂

 

From what I see using my example in the image below, the geometry symbol seems to represent the True geometry you see in the Model, even you make cut and join it will always return the True geometry you see in the Model. BUT the Transform needs to be applied ONLY if the initial geometry is edited (by cut or join).So the columns behave like a FamilyInstance already Join/Cut. In addition, if you cut a FamilyInstance and duplicate it without cut, the copy SymbolGeometry will react like the Join/Cut one!

 

In summary: FamilySymbol with cut/join will result that the GeometrySymbol is the correct geometry without any need to Transform.

 

This is clearly visible in the image below, where I place a FamilyInstance (on the right) in Model coordinate (0,0,0) and a little rotate. In the middle I cut it, and on the left it's a copy of the one in the middle but without the cut. The geometry in Red is the little bottom face in the hole I extruded using my method "GetGeometry" method in the first message of this post. The result is I apply a Transform of the left and middle FamilyInstance SymbolGeometry but I don't need it, suppressing the Transform give the correct result.

 

lvirone_0-1715070917626.png

 

To see if you need to apply the transform, you can try to paint the FamilyInstance faces using paint tool in Revit. If you can paint the faces, then SymbolGeometry give you the correct geometry. If you can't paint, you need to make the Transform. I don't understand what is going on 😅

 

I hope you'll be able to understand what I tried to explain with my poor English 🙃

 

EDIT : It happens when FamilyInstance.HasModifiedGeometry: True

Which seems to be the default value for columns

 

Edit my first post code with this and it seems to work: ("GetGeometry" was already correct)

 

public static bool TransformThisObjectGeometryToGetTheTrueGeometry(this Element elem)
{
    return elem is FamilyInstance fam && !fam.HasModifiedGeometry();
}

 

0 Likes

Yes I agreed with you until I tested it in a Revit Model and I saw something even more strange  😂

 

From what I see using my example in the image below, the geometry symbol seems to represent the True geometry you see in the Model, even you make cut and join it will always return the True geometry you see in the Model. BUT the Transform needs to be applied ONLY if the initial geometry is edited (by cut or join).So the columns behave like a FamilyInstance already Join/Cut. In addition, if you cut a FamilyInstance and duplicate it without cut, the copy SymbolGeometry will react like the Join/Cut one!

 

In summary: FamilySymbol with cut/join will result that the GeometrySymbol is the correct geometry without any need to Transform.

 

This is clearly visible in the image below, where I place a FamilyInstance (on the right) in Model coordinate (0,0,0) and a little rotate. In the middle I cut it, and on the left it's a copy of the one in the middle but without the cut. The geometry in Red is the little bottom face in the hole I extruded using my method "GetGeometry" method in the first message of this post. The result is I apply a Transform of the left and middle FamilyInstance SymbolGeometry but I don't need it, suppressing the Transform give the correct result.

 

lvirone_0-1715070917626.png

 

To see if you need to apply the transform, you can try to paint the FamilyInstance faces using paint tool in Revit. If you can paint the faces, then SymbolGeometry give you the correct geometry. If you can't paint, you need to make the Transform. I don't understand what is going on 😅

 

I hope you'll be able to understand what I tried to explain with my poor English 🙃

 

EDIT : It happens when FamilyInstance.HasModifiedGeometry: True

Which seems to be the default value for columns

 

Edit my first post code with this and it seems to work: ("GetGeometry" was already correct)

 

public static bool TransformThisObjectGeometryToGetTheTrueGeometry(this Element elem)
{
    return elem is FamilyInstance fam && !fam.HasModifiedGeometry();
}

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report