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
Solved! Go to Solution.
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 well
@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; }
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++;
}
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.
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 Loads
Can't find what you're looking for? Ask the community or share your knowledge.