明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1518|回复: 0

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

[复制链接]
发表于 2011-3-25 13:52:41 | 显示全部楼层 |阅读模式

作者:kean

原文地址:http://through-the-interface.typepad.com/through_the_interface/2011/03/generating-a-mesh-for-a-3d-solid-using-autocads-brep-api-from-net.html

 

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 he 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

 

    [CommandMethod("SOLMESH")]

    static public void MeshFromSolid()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      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)

        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;

 

        try

        {

          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)

                    {

                      pts.Add(n.Point);

                    }

 

                    // 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;

 

                      btr.AppendEntity(face);

                      tr.AddNewlyCreatedDBObject(face, true);

                    }

                  }

                }

              }

            }

          }

          tr.Commit();

        }

        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):

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
"觉得好,就打赏"
还没有人打赏,支持一下

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-12-24 20:50 , Processed in 0.164610 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表