Beispiel #1
0
        /// <summary> 将任意实体转换为网格 </summary>
        public static void CreateMeshFromSolid()
        {
            //Select a solid.
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            PromptEntityOptions opts = new PromptEntityOptions("\r\n" + "Select Solid:");

            opts.SetRejectMessage("\r\n" + "That\'s not a solid!");
            opts.AddAllowedClass(typeof(Solid3d), false);
            PromptEntityResult res = ed.GetEntity(opts);

            //Exit sub if user cancelled selection.
            if (res.Status != PromptStatus.OK)
            {
                return;
            }

            //Usual transaction stuff
            Database db = Application.DocumentManager.MdiActiveDocument.Database;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Solid3d   mySolid = tr.GetObject(res.ObjectId, OpenMode.ForRead, false) as Solid3d;
                Extents3d ext     = mySolid.Bounds.Value;
                Vector3d  vec     = ext.MaxPoint - ext.MinPoint;

                // 实体转换为网格的生成算法,即平滑或插值的参数
                //Define params governing mesh generation algorithm(See ObjectARX helpfiles for explanation of params you may need to change them depending on the scale of the solid)
                MeshFaceterData myFaceterData = new MeshFaceterData(0.01 * vec.Length, 40 * Math.PI / 180, 2, 2, 15, 5, 5, 0);

                //Create new mesh from solid (smoothing level 1)
                MeshDataCollection meshData = SubDMesh.GetObjectMesh(mySolid, myFaceterData);
                SubDMesh           myMesh   = new SubDMesh();
                myMesh.SetSubDMesh(meshData.VertexArray, meshData.FaceArray, 1);

                //Add mesh to database. (Don't remove solid).
                myMesh.SetDatabaseDefaults();
                var btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                btr.AppendEntity(myMesh);
                tr.AddNewlyCreatedDBObject(myMesh, true);

                //Our work here is done
                tr.Commit();
            }
        }
Beispiel #2
0
        internal static List <MeshData> SolidInfoForCollection(Document doc, Point3d camPos, ObjectIdCollection ids)
        {
            var sols = new List <MeshData>();

            using (var tr = doc.TransactionManager.StartOpenCloseTransaction())
            {
                foreach (ObjectId id in ids)
                {
                    Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;

                    // Entity handle to name the Three.js objects
                    String hand = ent.Handle.ToString();
                    Autodesk.AutoCAD.Colors.EntityColor clr = ent.EntityColor;

                    // Entity color to use for the Three.js objects
                    long b, g, r;
                    if (ent.ColorIndex < 256)
                    {
                        System.Byte byt = System.Convert.ToByte(ent.ColorIndex);
                        int         rgb = Autodesk.AutoCAD.Colors.EntityColor.LookUpRgb(byt);
                        b = (rgb & 0xffL);
                        g = (rgb & 0xff00L) >> 8;
                        r = rgb >> 16;
                    }
                    else
                    {
                        b = 127;
                        g = 127;
                        r = 127;
                    }
                    String entColor = "0x" + String.Format("{0:X2}{1:X2}{2:X2}", r, g, b);

                    // Entity extents
                    Extents3d ext  = ent.GeometricExtents;
                    var       tmp  = ext.MinPoint + 0.5 * (ext.MaxPoint - ext.MinPoint);
                    Vector3d  dir  = ext.MaxPoint - ext.MinPoint;
                    var       mid  = new Point3d(ext.MinPoint.X, tmp.Y, tmp.Z);
                    var       dist = camPos.DistanceTo(mid);

                    if (id.ObjectClass.Name.Equals("AcDbSubDMesh"))
                    {
                        // Already a Mesh. Get the face info and clean it up
                        // a bit to export it as a THREE.Face3 which only has three vertices

                        var mesh = ent as SubDMesh;

                        Point3dCollection threeVertices = new Point3dCollection();
                        Autodesk.AutoCAD.Geometry.Int32Collection threeFaceInfo = new Autodesk.AutoCAD.Geometry.Int32Collection();

                        Point3dCollection vertices = mesh.Vertices;

                        int[] faceArr = mesh.FaceArray.ToArray();
                        int[] edgeArr = mesh.EdgeArray.ToArray();

                        Autodesk.AutoCAD.Geometry.Int32Collection faceVertices = new Autodesk.AutoCAD.Geometry.Int32Collection();

                        int verticesInFace = 0;
                        int facecnt        = 0;
                        for (int x = 0; x < faceArr.Length; facecnt++, x = x + verticesInFace + 1)
                        {
                            faceVertices.Clear();

                            verticesInFace = faceArr[x];
                            for (int y = x + 1; y <= x + verticesInFace; y++)
                            {
                                faceVertices.Add(faceArr[y]);
                            }

                            // Merging of mesh faces can result in faces with multiple vertices
                            // A simple collinearity check can help remove those redundant vertices
                            bool continueCollinearCheck = false;
                            do
                            {
                                continueCollinearCheck = false;
                                for (int index = 0; index < faceVertices.Count; index++)
                                {
                                    int v1 = index;
                                    int v2 = (index + 1) >= faceVertices.Count ? (index + 1) - faceVertices.Count : index + 1;
                                    int v3 = (index + 2) >= faceVertices.Count ? (index + 2) - faceVertices.Count : index + 2;

                                    // Check collinear
                                    Point3d p1 = vertices[faceVertices[v1]];
                                    Point3d p2 = vertices[faceVertices[v2]];
                                    Point3d p3 = vertices[faceVertices[v3]];

                                    Vector3d vec1 = p1 - p2;
                                    Vector3d vec2 = p2 - p3;
                                    if (vec1.IsCodirectionalTo(vec2))
                                    {
                                        faceVertices.RemoveAt(v2);
                                        continueCollinearCheck = true;
                                        break;
                                    }
                                }
                            } while (continueCollinearCheck);

                            if (faceVertices.Count == 3)
                            {
                                Point3d p1 = vertices[faceVertices[0]];
                                Point3d p2 = vertices[faceVertices[1]];
                                Point3d p3 = vertices[faceVertices[2]];

                                if (!threeVertices.Contains(p1))
                                {
                                    threeVertices.Add(p1);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p1));

                                if (!threeVertices.Contains(p2))
                                {
                                    threeVertices.Add(p2);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p2));

                                if (!threeVertices.Contains(p3))
                                {
                                    threeVertices.Add(p3);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p3));
                            }
                            else if (faceVertices.Count == 4)
                            { // A face with 4 vertices, lets split it to
                                // make it easier later to create a THREE.Face3
                                Point3d p1 = vertices[faceVertices[0]];
                                Point3d p2 = vertices[faceVertices[1]];
                                Point3d p3 = vertices[faceVertices[2]];

                                if (!threeVertices.Contains(p1))
                                {
                                    threeVertices.Add(p1);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p1));

                                if (!threeVertices.Contains(p2))
                                {
                                    threeVertices.Add(p2);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p2));

                                if (!threeVertices.Contains(p3))
                                {
                                    threeVertices.Add(p3);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p3));

                                p1 = vertices[faceVertices[2]];
                                p2 = vertices[faceVertices[3]];
                                p3 = vertices[faceVertices[0]];

                                if (!threeVertices.Contains(p1))
                                {
                                    threeVertices.Add(p1);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p1));

                                if (!threeVertices.Contains(p2))
                                {
                                    threeVertices.Add(p2);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p2));

                                if (!threeVertices.Contains(p3))
                                {
                                    threeVertices.Add(p3);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p3));
                            }
                            else
                            {
                                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Face with more than 4 vertices will need triangulation to import in Three.js ");
                            }
                        }

                        sols.Add(new MeshData(dist, hand, ext, threeVertices, threeFaceInfo, entColor));
                    }
                    else if (id.ObjectClass.Name.Equals("AcDb3dSolid"))
                    {
                        // Mesh the solid to export to Three.js
                        Autodesk.AutoCAD.DatabaseServices.Solid3d sld = tr.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Solid3d;

                        MeshFaceterData mfd = new MeshFaceterData();
                        // Only triangles
                        mfd.FaceterMeshType = 2;

                        // May need change based on how granular we want the mesh to be.
                        mfd.FaceterMaxEdgeLength = dir.Length * 0.025;

                        MeshDataCollection md = SubDMesh.GetObjectMesh(sld, mfd);

                        Point3dCollection threeVertices = new Point3dCollection();
                        Autodesk.AutoCAD.Geometry.Int32Collection threeFaceInfo = new Autodesk.AutoCAD.Geometry.Int32Collection();

                        Point3dCollection vertices = md.VertexArray;

                        int[] faceArr = md.FaceArray.ToArray();

                        Autodesk.AutoCAD.Geometry.Int32Collection faceVertices = new Autodesk.AutoCAD.Geometry.Int32Collection();

                        int verticesInFace = 0;
                        int facecnt        = 0;
                        for (int x = 0; x < faceArr.Length; facecnt++, x = x + verticesInFace + 1)
                        {
                            faceVertices.Clear();

                            verticesInFace = faceArr[x];
                            for (int y = x + 1; y <= x + verticesInFace; y++)
                            {
                                faceVertices.Add(faceArr[y]);
                            }

                            if (faceVertices.Count == 3)
                            {
                                Point3d p1 = vertices[faceVertices[0]];
                                Point3d p2 = vertices[faceVertices[1]];
                                Point3d p3 = vertices[faceVertices[2]];

                                if (!threeVertices.Contains(p1))
                                {
                                    threeVertices.Add(p1);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p1));

                                if (!threeVertices.Contains(p2))
                                {
                                    threeVertices.Add(p2);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p2));

                                if (!threeVertices.Contains(p3))
                                {
                                    threeVertices.Add(p3);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p3));
                            }
                        }

                        sols.Add(new MeshData(dist, hand, ext, threeVertices, threeFaceInfo, entColor));

                        tr.Commit();
                    }
                }
            }
            return(sols);
        }
Beispiel #3
0
        static public void MeshFromSolid()
        {
            Utils.Utils.Init();

            Document acDoc   = acApp.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            Editor   ed      = acDoc.Editor;

            while (true)
            {
                // 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.Cancel || per.Status == PromptStatus.Error)
                {
                    Utils.Utils.End(); return;
                }

                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    // Open the Block table for read
                    BlockTable acBlkTbl;
                    acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                    // Open the Block table record Model space for write
                    BlockTableRecord acBlkTblRec;
                    acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                    Solid3d sol = acTrans.GetObject(per.ObjectId, OpenMode.ForWrite) as Solid3d;

                    try
                    {
                        // Set mesh/faces properties
                        MeshFaceterData mfd = new MeshFaceterData();
                        mfd.FaceterMeshType      = 2;
                        mfd.FaceterDevNormal     = 40;
                        mfd.FaceterDevSurface    = 0.05;
                        mfd.FaceterGridRatio     = 0;
                        mfd.FaceterMaxEdgeLength = 0;

                        MeshDataCollection md = SubDMesh.GetObjectMesh(sol, mfd);

                        // Create mesh
                        SubDMesh mesh = new SubDMesh();
                        mesh.SetDatabaseDefaults();
                        mesh.SetSubDMesh(md.VertexArray, md.FaceArray, 0);
                        mesh.Layer = sol.Layer;

                        // Add mesh to DB
                        acBlkTblRec.AppendEntity(mesh);
                        acTrans.AddNewlyCreatedDBObject(mesh, true);

                        // Delete solid object
                        sol.Erase(true);

                        acTrans.Commit();
                    }
                    catch (System.Exception ex)
                    {
                        ed.WriteMessage("Exception: {0}", ex.Message);
                    }
                }
            }
        }