//---------------------------------------------------------------------------------------------------------------- private static void SchrijfObject(Entity acEnt) { MeshDataCollection meshData = SubDMesh.GetObjectMesh(acEnt, new MeshFaceterData()); Point3dCollection vertexarray = meshData.VertexArray; Int32Collection facearray = meshData.FaceArray; //Schrijf aantalvertices int aantalvertices = vertexarray.Count; binWriter.Write(aantalvertices); //Schrijf vertices weg for (int i = 0; i < aantalvertices; i++) { Point3d punt = vertexarray[i]; binWriter.Write(Convert.ToSingle(punt.X)); binWriter.Write(Convert.ToSingle(punt.Y)); binWriter.Write(Convert.ToSingle(punt.Z)); } //Schrijf facearraycount int facearraycount = facearray.Count; binWriter.Write(facearraycount); //Schrijf facearray weg for (int i = 0; i < facearraycount; i++) { binWriter.Write(facearray[i]); } }
/// <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(); } }
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); }
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); } } } }