Get the vertices points of a polygon

Ali.sadeghi.h1994
Enthusiast
Enthusiast

Get the vertices points of a polygon

Ali.sadeghi.h1994
Enthusiast
Enthusiast

Hi everyone. I wish you a good day.

I am looking for a way to get the coordinates of the vertices of a polygon(or get the vertices points as point) and then place the desired element on each vertex. I know how to place the element on the points, but I can't write a code to get the vertices points of the selected polygon (automatically).

 

Vertices.png

 

I would be very grateful if someone could guide me.

0 Likes
Reply
Accepted solutions (1)
597 Views
7 Replies
Replies (7)

ahmedsherif9220
Contributor
Contributor

Good Morning, 

you will find the answer here The Building Coder: GetPolygon Extension Methods (typepad.com)

hope it will help you.

sherif

Ali.sadeghi.h1994
Enthusiast
Enthusiast

Thank you very much.

That link helped me to solve a part of my problem that was getting Top Face of a floor or any other elements. Mentioned part is first step to get vertices of a Face(ex. Top Face of a floor). I put the code here and I found a way get to the vertices but it still doesn't work. The way is that I think we can get CurveLoop Lines and then access them and their parameters but unfortunately my code does not work. In the code below we can get the Top Face of a Floor in the line that I marked with ( //*******Get Top Face*******) and the codes after that does not work to get Lines of the CurveLoop. If you know the error please correct it. ( It should be mentioned that I need Vertices at the end but I couldn't get them).

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using System.Collections;
using ElementFiltering;
//using System.Windows.Forms;
using Autodesk.Revit.DB.DirectContext3D;

namespace GetTopFace
{
    [Transaction(TransactionMode.Manual)]
    [RegenerationAttribute(RegenerationOption.Manual)]
    internal partial class GetFace : IExternalCommand
    {
        Application m_rvtApp;
        Document m_rvtDoc;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {

            UIApplication rvtUIApp = commandData.Application;
            UIDocument rvtUIDoc = rvtUIApp.ActiveUIDocument;
            //m_rvtApp = rvtUIApp.Application;
            m_rvtDoc = rvtUIDoc.Document;

            Reference SelElem = rvtUIDoc.Selection.PickObject(ObjectType.Element, "Please Select First Floor!");
            Element elem = m_rvtDoc.GetElement(SelElem);


            // Options For Geometry
            Options opt = new Options();
            opt.ComputeReferences = true;
            opt.DetailLevel = ViewDetailLevel.Fine;

            PlanarFace planarTopface = null;
            FaceArray faces = null;
            Face topFace = null;


            GeometryElement elemGeom = elem.get_Geometry(opt);
            foreach (GeometryObject geomObj in elemGeom)
            {
                Solid geomSolid = geomObj as Solid;
                faces = geomSolid.Faces;
                //GetTopFaceOfElement;            //*******Get Top Face*******
                foreach (Face f in faces)
                {
                    PlanarFace pf = f as PlanarFace;
                    if (pf.FaceNormal.IsAlmostEqualTo(new XYZ(0, 0, 1)))
                    {
                        planarTopface = pf;
                        topFace = pf;
                    }
                }
            }


            // ??????How to Get Lines of CurveLoop of the TopFace ????????  --  it does not work 😞  --
            CurveLoop[] curves = topFace.GetEdgesAsCurveLoops().ToArray();
            Array curves1 = curves;
            Line[] lines = null;
            foreach (CurveLoop i in curves1)
            {
                foreach (Line l in i)
                {
                    lines.Append(l);
                }
            }

            return Result.Succeeded;
        }

 

0 Likes

ahmedsherif9220
Contributor
Contributor

ok you need the vertex,

from planar face you got the lines 
cast it in curves then tesselate then you got your points 

 

 CurveLoop[] curves = topFace.GetEdgesAsCurveLoops().ToArray();
            Array curves1 = curves;
            XYZ[] points= null;
            foreach (CurveLoop i in curves1)
            {
                foreach (Line l in i)
                {
                   var curve = l as Curve;
                  var pointsofcuvre =  curve.Tesselate();
// noww you have the two points of the curve
                 foreach(point in pointsofcurve)
                 {
                 points.add(point);
                 }
                }
            }

            return Result.Succeeded;
        }

 

Ali.sadeghi.h1994
Enthusiast
Enthusiast

Thanks again for your  guides and useful tips.

That seems to be correct but when second foreach loop wants to add the point  to the defined List of XYZ, an error appears. I think I have to use a copy of point not the reference point but I don't know how. Below I've put screenshot of the error.Error.JPG

 

0 Likes

ahmedsherif9220
Contributor
Contributor

hola ali

send me the project please and i will fix it to you 

thanks 

0 Likes

ahmedsherif9220
Contributor
Contributor

              try that it will give you the number of vertix

				UIDocument uidoc = this.Application.ActiveUIDocument;
			Document doc = uidoc.Document;
			var x = uidoc.Selection.PickObject(ObjectType.Element);
			Element elem = doc.GetElement(x);


            // Options For Geometry
            Options opt = new Options();
            opt.ComputeReferences = true;
            opt.DetailLevel = ViewDetailLevel.Fine;

            PlanarFace planarTopface = null;
            FaceArray faces = null;
            Face topFace = null;
           List<XYZ> points = new List<XYZ>();
			            

            GeometryElement elemGeom = elem.get_Geometry(opt);
            foreach (GeometryObject geomObj in elemGeom)
            {
                Solid geomSolid = geomObj as Solid;
                faces = geomSolid.Faces;
                //GetTopFaceOfElement;            //*******Get Top Face*******
                foreach (Face f in faces)
                {
                    PlanarFace pf = f as PlanarFace;
                    if (pf.FaceNormal.IsAlmostEqualTo(new XYZ(0, 0, 1)))
                    {
                        planarTopface = pf;
                        topFace = pf;
                    }
                }
            }


			            // ??????How to Get Lines of CurveLoop of the TopFace ????????  --  it does not work   --
			            CurveLoop[] curves = topFace.GetEdgesAsCurveLoops().ToArray();
			            Array curves1 = curves;
			           foreach (CurveLoop i in curves1)
			            {
			                foreach (Line l in i)
			                {
			                   var curve = l as Curve;
			                   var pointsofcuvre =  curve.Tessellate();
							// noww you have the two points of the curve
							points.AddRange(pointsofcuvre.ToList());
			                }
			            }
			           TaskDialog.Show("sfdsf",points.Count.ToString());

Ali.sadeghi.h1994
Enthusiast
Enthusiast
Accepted solution

I Have found the solution and I put the code here. The code returns vertices on the top surface of a floor. User selects the Floor and its  upper vertices and Location of them will be shown.

Thanks to my friend @ahmedsherif9220  for his guides.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using System.Collections;
using ElementFiltering;
//using System.Windows.Forms;
using Autodesk.Revit.DB.DirectContext3D;

namespace GetVertices
{
    [Transaction(TransactionMode.Manual)]
    [RegenerationAttribute(RegenerationOption.Manual)]
    internal partial class GetVertices : IExternalCommand
    {
        //  member variables 
        Application m_rvtApp;
        Document m_rvtDoc;

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //  Get the access to the top most objects
            UIApplication rvtUIApp = commandData.Application;
            UIDocument rvtUIDoc = rvtUIApp.ActiveUIDocument;
            //m_rvtApp = rvtUIApp.Application;
            m_rvtDoc = rvtUIDoc.Document;

            Reference SelElem = rvtUIDoc.Selection.PickObject(ObjectType.Element, "Please Select a Floor!");
            Element elem = m_rvtDoc.GetElement(SelElem);


            // Options For Geometry
            Options opt = new Options();
            opt.ComputeReferences = true;
            opt.DetailLevel = ViewDetailLevel.Fine;

            PlanarFace planarTopface = null;
            FaceArray faces = null;
            Face topFace = null;


            GeometryElement elemGeom = elem.get_Geometry(opt);
            foreach (GeometryObject geomObj in elemGeom)
            {
                Solid geomSolid = geomObj as Solid;
                faces = geomSolid.Faces;
                //GetTopFaceOfElement(geomSolid);
                foreach (Face f in faces)
                {
                    PlanarFace pf = f as PlanarFace;
                    if (pf.FaceNormal.IsAlmostEqualTo(new XYZ(0, 0, 1)))
                    {
                        planarTopface = pf;
                        topFace = pf;
                    }
                }
            }

            CurveLoop[] curves = topFace.GetEdgesAsCurveLoops().ToArray();
            Array curves1 = curves;
            List<XYZ> points = new List<XYZ>();
            List<Line> linesAround = new List<Line>();


            foreach (CurveLoop i in curves1)
            {
                foreach (Line l in i)
                {
                    var curve = l as Curve;
                    var pointsofcurve = curve.Tessellate();
                    linesAround.Add(l);
                    //now you have the two points of the curve
                    foreach (XYZ point in pointsofcurve)
                    {
                        points.Add(point);
                    }
                }
            }

            List<XYZ> verts = new List<XYZ>();

            // Adding points to  vertices list which is called  verts
            int z = 0;
            while (z < points.Count)
            {
                verts.Add(points[z]);
                z = z + 2;
            }

            string s = null;
            for(int v=0; v < verts.Count; v++)
            {
                s+="Vertex "+(v+1).ToString()+" Location is: "+$"({verts[v].X},{verts[v].Y},{verts[v].Z})\n";
            }

            TaskDialog.Show("Vertices of Selected Floor Information", "Number Of Detected Lines: " + linesAround.Count.ToString() + "\nNumber Of Detected Vertices: " + verts.Count.ToString()+"\n"+s);

            return Result.Succeeded;
        }
0 Likes