.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

how to get all vertecies of an entity solid3d

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
ioanb7
3175 Views, 4 Replies

how to get all vertecies of an entity solid3d

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);
                }

            }
        }
4 REPLIES 4
Message 2 of 5
_gile
in reply to: ioanb7

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.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 5
ioanb7
in reply to: _gile

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);
	}
}

 

Message 4 of 5
_gile
in reply to: ioanb7

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.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 5
ioanb7
in reply to: _gile

 

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);
}

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost