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: 

Convert Mesh to Solid

2 REPLIES 2
Reply
Message 1 of 3
danail.momchilov
627 Views, 2 Replies

Convert Mesh to Solid

danail.momchilov
Contributor
Contributor

Hi! I am trying to create a C# method, that transforms a Mesh to Solid object. it came out as an issue from Dynamo, as Dynamo solids are converted to DB.Mesh when Unwrapped.

 

My initial approach was to use the TessellatedShapeBuilder class. I would simply get each triangle from the mesh and try to add it as a new face in the builder. Here's the code:

 

        public static IList<Autodesk.Revit.DB.GeometryObject> ReturnRevitSolid(Autodesk.DesignScript.Geometry.Solid inputSolid)
        {
            try
            {
                // convert the Dynamo solid to API mesh
                IList<GeometryObject> solidGeomObject = inputSolid.ToRevitType();

                Autodesk.Revit.DB.Mesh revitMesh;

                if (solidGeomObject.Count == 1)
                    revitMesh = (Autodesk.Revit.DB.Mesh)solidGeomObject[0];
                else
                    return null;

                // define the shape builder object
                TessellatedShapeBuilder builder = new TessellatedShapeBuilder();
                builder.Target = TessellatedShapeBuilderTarget.Solid;
                builder.OpenConnectedFaceSet(true);

                // get all the mesh data
                ElementId materialId = revitMesh.MaterialElementId;
                int trianglesNumb = revitMesh.NumTriangles;

                // create a face from each triangle and add it to the solid
                for (int i = 0; i < trianglesNumb; i++)
                {
                    MeshTriangle meshTriangle = revitMesh.get_Triangle(i);
                    List<XYZ> vertecesList = new List<XYZ> { meshTriangle.get_Vertex(0), meshTriangle.get_Vertex(1), meshTriangle.get_Vertex(2) };
                    TessellatedFace face = new TessellatedFace(vertecesList, materialId);

                    builder.AddFace(face);
                }

                builder.CloseConnectedFaceSet();
                builder.Build();

                TessellatedShapeBuilderResult result = builder.GetBuildResult();

                return result.GetGeometricalObjects();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

 

However, I only got an 'Internal Error' as a result:

danailmomchilov_0-1703172178704.png

 

I then noticed there are 12 triangles and 12 normals for a simple cuboid, which means each planar face is divided in two triangles (logically). So I thought maybe adding two triangles, that usually form a single face might be causing the issue. That's why I've decided to sort the triangles in a dictionary and add the ones, having identical normals under the same key. Then after cleaning duplicate points I would get the correct XYZ list so that a face can be formed properly. Here's the updated code:

 

        public static IList<GeometryObject> ReturnRevitSolidTest(Autodesk.DesignScript.Geometry.Solid inputSolid)
        {
            try
            {
                // convert the Dynamo solid to API mesh
                IList<GeometryObject> solidGeomObject = inputSolid.ToRevitType();

                Autodesk.Revit.DB.Mesh revitMesh;

                if (solidGeomObject.Count == 1)
                    revitMesh = (Autodesk.Revit.DB.Mesh)solidGeomObject[0];
                else
                    return null;

                // match triangles, based on identical normals, if any
                IList<XYZ> normals = revitMesh.GetNormals();
                int trianglesNumb = revitMesh.NumTriangles;

                Dictionary<XYZ, List<XYZ>> pointsByNormals = new Dictionary<XYZ, List<XYZ>>();

                for (int i = 0; i < trianglesNumb; i++)
                {
                    MeshTriangle triangle = revitMesh.get_Triangle(i);
                    XYZ normal = normals[i];

                    if (!pointsByNormals.ContainsKey(normal))
                        pointsByNormals[normal] = new List<XYZ>();

                    for  (int j = 0; j < 3; j++)
                    {
                        XYZ vertex = triangle.get_Vertex(j);
                        pointsByNormals[normal].Add(vertex);
                    }
                }

                // remove duplicating points from the list
                foreach (var kvp in pointsByNormals)
                {
                    List<XYZ> uniquePoints = kvp.Value.Distinct().ToList();
                    pointsByNormals[kvp.Key] = uniquePoints;
                }

                // define the shape builder object
                TessellatedShapeBuilder builder = new TessellatedShapeBuilder();
                builder.Target = TessellatedShapeBuilderTarget.Solid;
                builder.OpenConnectedFaceSet(true);

                ElementId materialId = revitMesh.MaterialElementId;

                // create face from each points set and add it to the shape builder
                foreach (XYZ normal in normals)
                {
                    TessellatedFace face = new TessellatedFace(pointsByNormals[normal], materialId);
                    builder.AddFace(face);
                }

                builder.CloseConnectedFaceSet();
                builder.Build();

                TessellatedShapeBuilderResult result = builder.GetBuildResult();

                return result.GetGeometricalObjects();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

 

Unfortunately it didn't work again. The error I got was that one:

 

danailmomchilov_1-1703173139765.png

 

Any suggestion would be of great help 🙂

I was also thinking I might try to use this class: https://www.revitapidocs.com/2024/94c1fef4-2933-ce67-9c2d-361cbf8a42b4.htm


But I think the general approach would be more or less the same in this case, as it would still require that I add individual faces to the object until a proper solid is obtained.

0 Likes

Convert Mesh to Solid

Hi! I am trying to create a C# method, that transforms a Mesh to Solid object. it came out as an issue from Dynamo, as Dynamo solids are converted to DB.Mesh when Unwrapped.

 

My initial approach was to use the TessellatedShapeBuilder class. I would simply get each triangle from the mesh and try to add it as a new face in the builder. Here's the code:

 

        public static IList<Autodesk.Revit.DB.GeometryObject> ReturnRevitSolid(Autodesk.DesignScript.Geometry.Solid inputSolid)
        {
            try
            {
                // convert the Dynamo solid to API mesh
                IList<GeometryObject> solidGeomObject = inputSolid.ToRevitType();

                Autodesk.Revit.DB.Mesh revitMesh;

                if (solidGeomObject.Count == 1)
                    revitMesh = (Autodesk.Revit.DB.Mesh)solidGeomObject[0];
                else
                    return null;

                // define the shape builder object
                TessellatedShapeBuilder builder = new TessellatedShapeBuilder();
                builder.Target = TessellatedShapeBuilderTarget.Solid;
                builder.OpenConnectedFaceSet(true);

                // get all the mesh data
                ElementId materialId = revitMesh.MaterialElementId;
                int trianglesNumb = revitMesh.NumTriangles;

                // create a face from each triangle and add it to the solid
                for (int i = 0; i < trianglesNumb; i++)
                {
                    MeshTriangle meshTriangle = revitMesh.get_Triangle(i);
                    List<XYZ> vertecesList = new List<XYZ> { meshTriangle.get_Vertex(0), meshTriangle.get_Vertex(1), meshTriangle.get_Vertex(2) };
                    TessellatedFace face = new TessellatedFace(vertecesList, materialId);

                    builder.AddFace(face);
                }

                builder.CloseConnectedFaceSet();
                builder.Build();

                TessellatedShapeBuilderResult result = builder.GetBuildResult();

                return result.GetGeometricalObjects();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

 

However, I only got an 'Internal Error' as a result:

danailmomchilov_0-1703172178704.png

 

I then noticed there are 12 triangles and 12 normals for a simple cuboid, which means each planar face is divided in two triangles (logically). So I thought maybe adding two triangles, that usually form a single face might be causing the issue. That's why I've decided to sort the triangles in a dictionary and add the ones, having identical normals under the same key. Then after cleaning duplicate points I would get the correct XYZ list so that a face can be formed properly. Here's the updated code:

 

        public static IList<GeometryObject> ReturnRevitSolidTest(Autodesk.DesignScript.Geometry.Solid inputSolid)
        {
            try
            {
                // convert the Dynamo solid to API mesh
                IList<GeometryObject> solidGeomObject = inputSolid.ToRevitType();

                Autodesk.Revit.DB.Mesh revitMesh;

                if (solidGeomObject.Count == 1)
                    revitMesh = (Autodesk.Revit.DB.Mesh)solidGeomObject[0];
                else
                    return null;

                // match triangles, based on identical normals, if any
                IList<XYZ> normals = revitMesh.GetNormals();
                int trianglesNumb = revitMesh.NumTriangles;

                Dictionary<XYZ, List<XYZ>> pointsByNormals = new Dictionary<XYZ, List<XYZ>>();

                for (int i = 0; i < trianglesNumb; i++)
                {
                    MeshTriangle triangle = revitMesh.get_Triangle(i);
                    XYZ normal = normals[i];

                    if (!pointsByNormals.ContainsKey(normal))
                        pointsByNormals[normal] = new List<XYZ>();

                    for  (int j = 0; j < 3; j++)
                    {
                        XYZ vertex = triangle.get_Vertex(j);
                        pointsByNormals[normal].Add(vertex);
                    }
                }

                // remove duplicating points from the list
                foreach (var kvp in pointsByNormals)
                {
                    List<XYZ> uniquePoints = kvp.Value.Distinct().ToList();
                    pointsByNormals[kvp.Key] = uniquePoints;
                }

                // define the shape builder object
                TessellatedShapeBuilder builder = new TessellatedShapeBuilder();
                builder.Target = TessellatedShapeBuilderTarget.Solid;
                builder.OpenConnectedFaceSet(true);

                ElementId materialId = revitMesh.MaterialElementId;

                // create face from each points set and add it to the shape builder
                foreach (XYZ normal in normals)
                {
                    TessellatedFace face = new TessellatedFace(pointsByNormals[normal], materialId);
                    builder.AddFace(face);
                }

                builder.CloseConnectedFaceSet();
                builder.Build();

                TessellatedShapeBuilderResult result = builder.GetBuildResult();

                return result.GetGeometricalObjects();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

 

Unfortunately it didn't work again. The error I got was that one:

 

danailmomchilov_1-1703173139765.png

 

Any suggestion would be of great help 🙂

I was also thinking I might try to use this class: https://www.revitapidocs.com/2024/94c1fef4-2933-ce67-9c2d-361cbf8a42b4.htm


But I think the general approach would be more or less the same in this case, as it would still require that I add individual faces to the object until a proper solid is obtained.

2 REPLIES 2
Message 2 of 3

jeremy_tammik
Autodesk
Autodesk

It may be easier to create a direct shape from the mesh; here are many examples showing how:

  

  

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

It may be easier to create a direct shape from the mesh; here are many examples showing how:

  

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 3 of 3

vengateshhp2001
Observer
Observer
Hi Jeremy_tammik,
After converting the mesh into direct shape, if we check the property of element geometry it shows Mesh only.
Is there any Direct method to convert the Mesh into solid?
Thank you
0 Likes

Hi Jeremy_tammik,
After converting the mesh into direct shape, if we check the property of element geometry it shows Mesh only.
Is there any Direct method to convert the Mesh into solid?
Thank you

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

Post to forums  

Autodesk Design & Make Report