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:
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:
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.
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:
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:
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.
It may be easier to create a direct shape from the mesh; here are many examples showing how:
It may be easier to create a direct shape from the mesh; here are many examples showing how:
Can't find what you're looking for? Ask the community or share your knowledge.