Through the Interface: Generating a mesh for a 3D solid using AutoCADs Brep API from .NET

April 2015

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    


« New APIs in AutoCAD 2012 | Main | Displaying transient AutoCAD points that respect PDMODE using .NET »

March 25, 2011

Generating a mesh for a 3D solid using AutoCAD’s Brep API from .NET

Thanks for Balaji Ramamoorthy – who recently joined our team in India – and Adam Nagy for helping generate the code for this post.

There are lots of reasons people might want to tessellate a 3D solid in AutoCAD to generate a mesh. The code in today’s post uses the Boundary Representation (Brep) API in AutoCAD to do just that, generating a set of 3D faces.

A few points about the implementation:

  • I’ve only made a small number of settings to control the mesh generation: more are available for you to experiment with.
  • It should be simple enough to generate a SubDMesh, rather than a set of faces, but that’s left as an exercise for the reader.
  • I only tested with a very simple solid (a sphere). The settings may need tweaking depending on the complexity of the solid you’re meshing.

Here’s the C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.BoundaryRepresentation;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.Runtime;

using AcDb = Autodesk.AutoCAD.DatabaseServices;


namespace MeshSolid


  public class MeshCreator


    // Mesh a selected solid



    static public void MeshFromSolid()


      Document doc =


      Database db = doc.Database;

      Editor ed = doc.Editor;


      // Ask the user to select a solid


      PromptEntityOptions peo =

        new PromptEntityOptions("Select a 3D solid");

      peo.SetRejectMessage("\nA 3D solid must be selected.");

      peo.AddAllowedClass(typeof(Solid3d), true);

      PromptEntityResult per = ed.GetEntity(peo);


      if (per.Status != PromptStatus.OK)



      Transaction tr =


      using (tr)


        BlockTable bt =






        BlockTableRecord btr =







        Solid3d sol =




          ) as Solid3d;


        // Calculate the approximate size of our solid


        double length =







          using (Brep brp = new Brep(sol))


            // Create and set our mesh control object


            using (Mesh2dControl mc = new Mesh2dControl())


              // These settings seem extreme, but only result

              // in ~500 faces for a sphere (during my testing,

              // anyway). Other control settings are available


              mc.MaxNodeSpacing = length / 10000;

              mc.MaxSubdivisions = 100000000;


              // Create a mesh filter object


              using (Mesh2dFilter mf = new Mesh2dFilter())


                // Use it to map our control settings to the Brep


                mf.Insert(brp, mc);


                // Generate a mesh using the filter


                using (Mesh2d m = new Mesh2d(mf))


                  // Extract individual faces from the mesh data


                  foreach (Element2d e in m.Element2ds)


                    Point3dCollection pts = new Point3dCollection();

                    foreach (Node n in e.Nodes)







                    // A face could be a triangle or a quadrilateral

                    // (the Booleans indicate the edge visibility)


                    AcDb.Face face = null;

                    if (pts.Count == 3)

                      face =

                        new AcDb.Face(

                          pts[0], pts[1], pts[2],

                          true, true, true, true


                    else if (pts.Count == 4)

                      face =

                        new AcDb.Face(

                          pts[0], pts[1], pts[2], pts[3],

                          true, true, true, true



                    // If we have a valid face, add it to the

                    // database and the transaction


                    if (face != null)


                      // Make each face yellow for visibility


                      face.ColorIndex = 2;



                      tr.AddNewlyCreatedDBObject(face, true);









        catch (System.Exception ex)


          ed.WriteMessage("Exception: {0}", ex.Message);







Here’s what happens when we run the SOLMESH command, selecting a simple sphere (which I later moved to the side, for comparison):

Meshed version of a sphere

And now with the realistic visual style set, just to show we have opacity:

And now in the realistic visual style


As mentioned in the comments, the code was randomly crashing on larger models. Viru Aithal and Balaji Ramamoorthy tracked down the problem, which is due to a common issue with AutoCAD objects: the enumerators for Mesh2dElement2dCollection and Element2dNodeCollection both return newly-created objects (a Node and an Element2d, respectively) which need to be disposed of before the .NET Finalizer (which works on a background thread) attempts to do so for you. Two lines (with calls to n.Dispose() and e.Dispose()) have been added to the above code to address this issue.

blog comments powered by Disqus


10 Random Posts