Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to get" Floor & Slab "Location

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
Anonymous
4287 Views, 6 Replies

How to get" Floor & Slab "Location

As the Forums there lots of topic mention about "Location Point ,Curve". (ps:even stairs)

"How to get location of element":

https://forums.autodesk.com/t5/revit-api-forum/how-to-get-location-of-element/m-p/8595313

But didn't discover Floor & Slab part yet.

So could someone demo "Hot to get" Floor & Slab "Location"?

(If there are some post alreay been discover please kindly let me know )

Thx

Tags (3)
6 REPLIES 6
Message 2 of 7
naveen.kumar.t
in reply to: Anonymous

Hi @Anonymous ,

Since Floor is Created using the List of curves here the location point represents the each edges of the floor.

Unlike other elements which will be having Center Point or location point . 

 

You need to create a temporary transaction. During this temp transaction, delete the target slab by Document.Delete() method. This method will return all the deleted elements' ids after the slab is deleted. So the slab's boundary model line can be find by iterating all the return id (get the element from those ids and compare the object type if they are ModelLine class). Finally abort this temp transaction.

 

To get the Floor boundary points use the following code

//Get all the model lines of the floor
                Transaction TemporaryTransaction1 = new Transaction(doc);
                TemporaryTransaction1.Start("GET FLOOR CURVES");
                Reference r = uidoc.Selection.PickObject(ObjectType.Element);
                ElementId eid = r.ElementId;
                Element e = doc.GetElement(eid);
                IList<ElementId> eids = doc.Delete(eid) as IList<ElementId>;
                TemporaryTransaction1.RollBack();

                //ADD those model lines to the list
                List<ModelLine> mlines = new List<ModelLine>();
                foreach(ElementId MlineID in eids)
                {
                    Element mLine = doc.GetElement(MlineID) as Element;
                    if(mLine is ModelLine)
                    {
                        mlines.Add(mLine as ModelLine);
                    }

                }

                //From the model line get the end points
                foreach(ModelLine ML in mlines)
                {
                    LocationCurve LC = ML.Location as LocationCurve;
                    Line L = LC.Curve as Line;
                    XYZ p1 = L.GetEndPoint(0) as XYZ;
                    XYZ p2 = L.GetEndPoint(1) as XYZ;

                    string StartPoint = "(" + p1.X.ToString() + "," + p1.Y.ToString() + "," + p1.Z.ToString() + ")";
                    string EndPoint = "(" + p2.X.ToString() + "," + p2.Y.ToString() + "," + p2.Z.ToString() + ")";
                }

If this helped solve your problem please mark it as solution, so other users can get this solutions as wellSmiley Happy


Naveen Kumar T
Developer Technical Services
Autodesk Developer Network

Message 3 of 7
Anonymous
in reply to: naveen.kumar.t

@naveen.kumar.t  Thx~
It works but the output duplicate so  in order let someone else might be need,put the code down below(External way)

 public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            ICollection < ElementId > ids= uidoc.Selection.GetElementIds();
            Document doc = uidoc.Document;

            Transaction TemporaryTransaction1 = new Transaction(doc);
            TemporaryTransaction1.Start("Get Floor Curves");
            Reference r = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
            ElementId eid = r.ElementId;

            IList<ElementId>eids = doc.Delete(eid) as IList<ElementId>;
            TemporaryTransaction1.RollBack();

            List<ModelLine> mlines = new List<ModelLine>();
            foreach (ElementId MlineID in eids)
            {
                Element mLine = doc.GetElement(MlineID) as Element;
                if (mLine is ModelLine)
                {
                    mlines.Add(mLine as ModelLine);
                }
            }
            StringBuilder sb = new StringBuilder();
///---Will not have duplicate result ,should be out of "foreach(loop)---///
            XYZ p1 = new XYZ();
            XYZ p2 = new XYZ();
///---///
            foreach (ModelLine ML in mlines)
            {
                LocationCurve LC = ML.Location as LocationCurve;
                Line L = LC.Curve as Line;
                p1 = L.GetEndPoint(0) as XYZ;
                p2 = L.GetEndPoint(1) as XYZ;
            }
            sb.AppendLine("Start_Loca: " + p1.X.ToString() + "," + p1.Y.ToString() + "," + p1.Z.ToString());
            sb.AppendLine("End_Loca: " + p2.X.ToString() + "," + p2.Y.ToString() + "," + p2.Z.ToString());
            MessageBox.Show(sb.ToString());
            return Result.Succeeded;
        }

 

Message 4 of 7
Anonymous
in reply to: naveen.kumar.t

Hi @naveen.kumar.t 

I draw two floor in each storey , the floor is square and the floor has 4 points only 

when I read coordinates of each floor in each storey with Revit API, I read 8 points in each floor, why?

how can i read 4 points only for each floor

my code

ElementCategoryFilter floorFilter = new ElementCategoryFilter(BuiltInCategory.OST_Floors);

IList<Floor> allFloors = new FilteredElementCollector(doc).OfClass(typeof(Floor)).WherePasses(floorFilter).ToElements().Cast<Floor>().ToList();

int FloorCount = allFloors.Count;
double floorThickness = 0;

foreach (Floor floor in allFloors)
{
int mLineCount = 0;

//Get Element Type
ElementId eleTypeId = floor.GetTypeId();
FloorType floortype = doc.GetElement(eleTypeId) as FloorType;

//Get Parameter of Floor
ElementId level = null;

double floorElevationAtTop = 0;

Element elementFloorLevel = null;

foreach (BuiltInParameter bb in allParameter)
{
Parameter p = floor.get_Parameter(bb);

if (p != null)
{
if (p.Definition.Name == "Level")
{
level = p.AsElementId();
elementFloorLevel = doc.GetElement(level);
}

if (p.Definition.Name == "Elevation at Top")
{
floorElevationAtTop = Math.Round(UnitUtils.ConvertFromInternalUnits(p.AsDouble(), DisplayUnitType.DUT_METERS), 5);
}
}
}

//Get Coordinate of Floor
ICollection<ElementId> ids = uidoc.Selection.GetElementIds();

Transaction TemporaryTransaction1 = new Transaction(doc);
TemporaryTransaction1.Start("Get Floor Curves");

IList<ElementId> eids = doc.Delete(eleTypeId) as IList<ElementId>;
int eidsCount = eids.Count;
TemporaryTransaction1.RollBack();

List<ModelLine> mlines = new List<ModelLine>();
Element Mline = null;
XYZ p1 = new XYZ();
XYZ p2 = new XYZ();

foreach (ElementId MlineID in eids)
{
Element mLine = doc.GetElement(MlineID) as Element;
if (mLine is ModelLine)
{
Mline = mLine as ModelLine;
LocationCurve LC = Mline.Location as LocationCurve;
Line L = LC.Curve as Line;
p1 = L.GetEndPoint(0) as XYZ;

if (floorElevationAtTop == Math.Abs(Math.Round(UnitUtils.ConvertFromInternalUnits(p1.Z, DisplayUnitType.DUT_METERS), 5)))
{

mlines.Add(mLine as ModelLine);
}

}
}
mLineCount = mlines.Count;

double[] x = new double[mLineCount];
double[] y = new double[mLineCount];
double[] z = new double[mLineCount];
int i = 0;

foreach (ModelLine ML in mlines)
{

LocationCurve LC = ML.Location as LocationCurve;
Line L = LC.Curve as Line;
p1 = L.GetEndPoint(0) as XYZ;
p2 = L.GetEndPoint(1) as XYZ;

x[i] = Math.Abs(Math.Round(UnitUtils.ConvertFromInternalUnits(p1.X, DisplayUnitType.DUT_METERS), 5));
y[i] = Math.Abs(Math.Round(UnitUtils.ConvertFromInternalUnits(p1.Y, DisplayUnitType.DUT_METERS), 5));
z[i] = Math.Abs(Math.Round(UnitUtils.ConvertFromInternalUnits(p1.Z, DisplayUnitType.DUT_METERS), 5));

InfoCoordinate += "X : " + x[i] + Environment.NewLine
+ "Y : " + y[i] + Environment.NewLine
+ "Z : " + z[i] + Environment.NewLine + Environment.NewLine;

i++;
}

Message 5 of 7
naveen.kumar.t
in reply to: Anonymous

Hi @Anonymous ,

For example, let's take a square floor. From the floor, you are getting the model lines and from the model lines, you are getting the endpoints.

A square floor contains 4 model lines and each model line contains 2 endpoints. So it is obvious that you will get 8 points.

For clear understanding lets take 

Modeline line1 contains points(p1,p2)

Modeline line2 contains points(p2,p3)

Modeline line3 contains points(p3,p4)

Modeline line4 contains points(p4,p1)

if you add points to the list, you will get total number of points as 8.

 

So the solution to your problem is to remove points that are repetitive.

1)Collect all points from the floor.(i.e)List<XYZ> lstxyz

2)Remove repetitive points

3)After removing repetitive points, store the points to the list

Try using the below code to avoid repetition of points

 

private List<XYZ> GetDistinctPoints(List<XYZ> lstxyz)
        {
            List<XYZ> lstxyzRound = new List<XYZ>();
            int i = 1, j = 1;

            //round the points to 6 decimal places (you may not need this)
            foreach (XYZ xyz in lstxyz)
            {
                lstxyzRound.Add(new XYZ(Math.Round(xyz.X, 6), Math.Round(xyz.Y, 6), Math.Round(xyz.Z, 6)));
            }

            //order by Z,X,Y (depends on your need)
            lstxyzRound = lstxyzRound.OrderBy(p => p.Y).ToList();
            lstxyzRound = lstxyzRound.OrderBy(p => p.X).ToList();
            lstxyzRound = lstxyzRound.OrderBy(p => p.Z).ToList();

            //remove points from list if duplicates
            bool blnDuplicate = true;
            while (blnDuplicate)
            {
                blnDuplicate = false;
                for (i = j; i < lstxyzRound.Count; i++)
                {
                    if (lstxyzRound[i - 1].DistanceTo(lstxyzRound[i]) < 0.0001)
                    {
                        blnDuplicate = true;
                        j = i;
                        break;
                    }
                }
                if (blnDuplicate)
                {
                    lstxyzRound.RemoveAt(j);
                }
            }
            return lstxyzRound;
        } 

 

I hope this helps.


Naveen Kumar T
Developer Technical Services
Autodesk Developer Network

Message 6 of 7
Anonymous
in reply to: naveen.kumar.t

Thanks for your help, @naveen.kumar.t 

Message 7 of 7
Anonymous
in reply to: naveen.kumar.t

Hi @naveen.kumar.t ,

when i put point load on a distance (0,0,3) and read the location of point load by Revit API, the result was (-2.99985, 2.9991, 0)............I used the function of Point

and 

when i put line load on start point (4,0,3) and end point (0,0,3) and read the location of line load by Revit API, the result was start point (1.00015,2.99991,0) and end point (-2.99985,2.99991,0)..........I used the function of GetEndPoint(0) and GetEndPoint(1)

why the results are wrong?

and 

Is there another way to calculate the location of point load and line load?

my code

////////////////////////////////////////Line Load////////////////////////////////////////////////////////

ElementCategoryFilter lineLoads = new ElementCategoryFilter(BuiltInCategory.OST_LineLoads);
IList<LineLoad> allLineLoads = new FilteredElementCollector(doc).WherePasses(lineLoads).ToElements().Cast<LineLoad>().ToList();

int lineLoadsCount = allLineLoads.Count;

foreach (LineLoad lineLoad in allLineLoads)
{
if (lineLoad != null)
{
LoadOrientTo loadOrientTo = lineLoad.OrientTo;

XYZ xyzlineLoadForceStartPoint = lineLoad.ForceVector1;
XYZ xyzlineLoadForceEndPoint = lineLoad.ForceVector2;
XYZ xyzLineLoadMomentStartPoint = lineLoad.MomentVector1;
XYZ xyzLineLoadMomentEndPoint = lineLoad.MomentVector2;
XYZ xyzLineLoadStartPoint = lineLoad.GetCurve().GetEndPoint(0);
XYZ xyzLineLoadEndPoint = lineLoad.GetCurve().GetEndPoint(1);

bool isProjected = lineLoad.IsProjected;
bool isUniform = lineLoad.IsUniform;}
if (lineLoad == null)
{
throw new Exception("Can't get Line Load.");
}
}

///////////////////////////////////Point Load//////////////////////////////////

ElementCategoryFilter pointLoads = new ElementCategoryFilter(BuiltInCategory.OST_PointLoads);
IList<PointLoad> allPointLoads = new FilteredElementCollector(doc).WherePasses(pointLoads).ToElements().Cast<PointLoad>().ToList();

int pointLoadsCount = allPointLoads.Count;

foreach (PointLoad pointLoad in allPointLoads)
{

if (pointLoad != null)
{
LoadOrientTo loadOrientTo = pointLoad.OrientTo;

XYZ xyzPointLoadForce = pointLoad.ForceVector;
XYZ xyzPointLoadMoment = pointLoad.MomentVector;
XYZ xyzPointLoadLocation = pointLoad.Point;

}
if (pointLoad == null)
{
throw new Exception("Can't get Point Load.");
}
}

my model with Loadsloads.png

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

Post to forums  

Autodesk Design & Make Report