Creating PolyfaceMesh from a 3D Solid

By Balaji Ramamoorthy

Here is a sample code to create a Polyface Mesh from a 3D solid. Most of the code in this blog post is from Kean’s blog post on a similar topic with some changes made to create a Polyface Mesh. As in the original post, I have tested it with a sphere and the mesh parameters may need tweaking for more complex solids.

using Autodesk.AutoCAD.BoundaryRepresentation;
 
[CommandMethod("SOL2POLYFACEMESH")]
static public void PolyfaceMeshFromSolid()
{
    Document doc =
    Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;
 
    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)
        return;
 
    Transaction tr = db.TransactionManager.StartTransaction();
    using (tr)
    {
        BlockTable bt = (BlockTable)tr.GetObject
            (
                db.BlockTableId, 
                OpenMode.ForRead, 
                false
            );
 
        BlockTableRecord btr = (BlockTableRecord)
                tr.GetObject(
                                bt[BlockTableRecord.ModelSpace],
                                OpenMode.ForWrite, false
                            );
 
        Solid3d sol = tr.GetObject(
                                    per.ObjectId, 
                                    OpenMode.ForRead
                                  ) as Solid3d;
 
        // Calculate the approximate size of our solid
        double length = sol.GeometricExtents.MinPoint.GetVectorTo
                        (sol.GeometricExtents.MaxPoint).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
 
                    PolyFaceMesh pfm = new PolyFaceMesh();
                    pfm.SetDatabaseDefaults();
                    pfm.ColorIndex = 2;
                    btr.AppendEntity(pfm);
 
                    short v0 = 0;
                    short v1 = 0;
                    short v2 = 0;
                    short v3 = 0;
                    short v = 0;
 
                    Dictionary vertexLookup 
                            = new Dictionary();
 
                    using (Mesh2d m = new Mesh2d(mf))
                    {
                        // Extract individual faces 
                        // from the mesh data
 
                        foreach (Element2d e in m.Element2ds)
                        {
                            foreach (Node n in e.Nodes)
                            {
                                if (! vertexLookup.ContainsKey(n.Point))
                                {
                                    PolyFaceMeshVertex pfmVertex 
                                        = new PolyFaceMeshVertex(n.Point);
 
                                    pfm.AppendVertex(pfmVertex);
                                    vertexLookup.Add(n.Point, ++v);
 
                                    tr.AddNewlyCreatedDBObject
                                            (pfmVertex, true);
                                }
 
                                n.Dispose();
                            }
                        }
 
                        foreach (Element2d e in m.Element2ds)
                        {
                            Point3dCollection pts 
                                    = new Point3dCollection();
                            foreach (Node n in e.Nodes)
                            {
                                pts.Add(n.Point);
 
                                n.Dispose();
                            }
 
                            e.Dispose();
 
                            v0 = 0;
                            if (vertexLookup.ContainsKey(pts[0]))
                                v0 = vertexLookup[pts[0]];
 
                            v1 = 0;
                            if (vertexLookup.ContainsKey(pts[1]))
                                v1 = vertexLookup[pts[1]];
 
                            v2 = 0;
                            if (vertexLookup.ContainsKey(pts[2]))
                                v2 = vertexLookup[pts[2]];
 
                            v3 = 0;
                            if (pts.Count == 4)
                            {
                                if (vertexLookup.ContainsKey(pts[3]))
                                    v3 = vertexLookup[pts[3]];
                            }
 
                            FaceRecord fr 
                               = new FaceRecord(v0, v1, v2, v3);
                            pfm.AppendFaceRecord(fr);
                            tr.AddNewlyCreatedDBObject(fr, true);
                        }
                    }
 
                    tr.AddNewlyCreatedDBObject(pfm, true);
 
                    vertexLookup.Clear();
                }
            }
        }
        tr.Commit();
    }
}

Here is a screenshot of the Polyface Mesh created from the sphere :
PolyfaceMesh


Comments

2 responses to “Creating PolyfaceMesh from a 3D Solid”

  1. Ernesto Gatto Avatar
    Ernesto Gatto

    no se ingles alguien me puede decir que significa edge surface gracias

  2. F_Rollan Avatar
    F_Rollan

    Could you post the same sample in ARX (c++) ?
    thanks.

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading