Hi,
I have a door in a dwg file and using AutoCAD I would like to export all it's vertices. For now it exports just the extrude geometry. I would use an export tool but it's essential I get the layer name as well as the points in the same object.
The type of objects I retrieve are either: Solid3d, ExtrudedSurface, Line. But I am only interested in Solid3d.
The code is below.
Regards,
Ioan
[CommandMethod("EXPORTVERTICES")] public static void ThreeDocumentToFile() { var doc = Application.DocumentManager.MdiActiveDocument; // If we didn't find a document, return if (doc == null) return; // We could probably get away without locking the document // - as we only need to read - but it's good practice to // do it anyway using (var dl = doc.LockDocument()) { var db = doc.Database; var ed = doc.Editor; // Capture our Extents3d objects in a list var sols = new List<DataMe>(); using (var tr = doc.TransactionManager.StartTransaction()) { // Start by getting the modelspace var ms = (BlockTableRecord)tr.GetObject( SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead ); // Get each Solid3d in modelspace and add its extents // to the list foreach (var id in ms) { var obj = tr.GetObject(id, OpenMode.ForRead); var sol = obj as Solid3d; DataMe dataMe = new DataMe(); if (sol != null) { dataMe.extents = sol.GeometricExtents; dataMe.layer = sol.Layer; } var pl = obj as Polyline; if (pl != null) { Point3dCollection lst = new Point3dCollection(); int pts = pl.NumberOfVertices; //ed.WriteMessage("\nNumber of params : " + (pts + 1).ToString()); for (int i = 0; i < (pts); i++) { lst.Add(pl.GetPointAtParameter(i)); } foreach (Point3d p in lst) { //ed.WriteMessage("\nPoint :" + p.ToString()); dataMe.points.Add(p); } } sols.Add(dataMe); } tr.Commit(); } string output = GetSolidsString(sols); SaveFileDialog saveFileDialog1 = new SaveFileDialog("Save to json", "door.json", "json", "Save", SaveFileDialog.SaveFileDialogFlags.AllowAnyExtension); if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) { System.IO.File.WriteAllText(saveFileDialog1.Filename, output); } } }
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Hi,
You can use the Brep (Boundary Representation) API.
It requires to reference acdbmgdbrep.dll.
var pts = new Point3dCollection(); using (var brep = new Autodesk.AutoCAD.BoundaryRepresentation.Brep(solid)) { foreach (var vertex in brep.Vertices) { pts.Add(vertex.Point); } }
Maybe this post give you more informations about the Brep API.
Hi,
Do these vertices have a integer ID or a way to reference them in order to create faces?
I get the following error in the way I am doing it: cannot convert from 'Autodesk.AutoCAD.BoundaryRepresentation.Vertex' to 'Autodesk.AutoCAD.DatabaseServices.Vertex' [...].
List<Vertex> vertexs = new List<Vertex>(); using (var brep = new Autodesk.AutoCAD.BoundaryRepresentation.Brep(sol)) { foreach (var vertex in brep.Vertices) { VertexMe vertexMe = new VertexMe(); vertexMe.Point = vertex.Point; //brep.Faces.First().Loops.First().Edges.First().Vertex1. foreach(var edge in vertex.Edges) { EdgeMe edgeMe = new EdgeMe(); edgeMe.vertex1 = vertexs.IndexOf(edge.Vertex1); // <-- ERROR: if (edgeMe.vertex1 == -1) { vertexs.Add(edge.Vertex1); edgeMe.vertex1 = vertexs.Count - 1; } edgeMe.vertex2 = vertexs.IndexOf(edge.Vertex2); if (edgeMe.vertex2 == -1) { vertexs.Add(edge.Vertex2); edgeMe.vertex2 = vertexs.Count - 1; } vertexMe.Edges.Add(edgeMe); } dataMe.points.Add(vertexMe); } }
I don't know anything about VertexMe type.
Anyway, you can directly get the faces using Brep.Faces property
Each Face contains a loop collection you can get with Face.Loops property (external loop and eventually internal loops).
Each BoundaryLoop contains an edges collection you can get with the BoundaryLoop.Edges property.
The code sample I linked upper shows the Brep tree architecture.
Hi,
Thank you a lot for your help so far.
So I am trying to get the vertices, which works great for now. I have X Y Z coordinates for all of them.
Then, I have to connect them in order to make them triangles. So I might have the first vertix connected with the 2nd and 3rd, the 5th with 1st and 6th and so on. I need a way to get those ids so that I have: X Y Z coordinates + vertex ID ++ List of adjacent edges [[2nd, 3rd], [5th, 1st]].
I hoped the method below works but it doesn't. I found ids that are not connected to any vertices and ids that are duplicated.
EdgeMe, VertexMe, DataMe are just data structures that help in serialising the data into json later on.
public class EdgeMe { public int vertex1; public int vertex2; } public class VertexMe { public int id; public Point3d Point; public List<EdgeMe> Edges = new List<EdgeMe>(); } public class DataMe{ public Extents3d extents; public string layer; public List<VertexMe> points = new List<VertexMe>(); } //... // Get each Solid3d in modelspace and add its extents // to the list foreach (var id in ms) { var obj = tr.GetObject(id, OpenMode.ForRead); var sol = obj as Solid3d; DataMe dataMe = new DataMe(); if (sol != null) { dataMe.extents = sol.GeometricExtents; dataMe.layer = sol.Layer; using (var brep = new Autodesk.AutoCAD.BoundaryRepresentation.Brep(sol)) { foreach (var vertex in brep.Vertices) { VertexMe vertexMe = new VertexMe(); vertexMe.Point = vertex.Point; vertexMe.id = vertex.Brep.GetHashCode(); foreach(var edge in vertex.Edges) { EdgeMe edgeMe = new EdgeMe(); edgeMe.vertex1 = edge.Vertex1.Brep.GetHashCode(); edgeMe.vertex2 = edge.Vertex2.Brep.GetHashCode(); vertexMe.Edges.Add(edgeMe); } dataMe.points.Add(vertexMe); } } } sols.Add(dataMe); }