Every family instance has a location in Revit, but the way to retrieve it differs between free-standing and hosted elements. A free-standing element (furniture, equipment) exposes a LocationPoint directly. A hosted element (door, window) is positioned along its host's LocationCurve at a parameter stored in HostParameter. All coordinates are in feet.
API References
FamilyInstance.Location— the element's location (LocationPoint or LocationCurve)FamilyInstance.Host— the containing element if hosted; null otherwiseFamilyInstance.HostParameter— insertion parameter along the host's curveCurve.Evaluate(t, normalized)— returns the XYZ point at parameter t
Implementation
csharp
FamilyInstance familyInstance = (FamilyInstance)instance;
// First try: direct location point (works for free-standing elements)
LocationPoint locationPoint = familyInstance.Location as LocationPoint;
if (locationPoint != null)
{
// Revit stores coordinates in feet — convert to metres for output
double x = ConvertUnits.FeetToMeter(locationPoint.Point.X);
double y = ConvertUnits.FeetToMeter(locationPoint.Point.Y);
double z = ConvertUnits.FeetToMeter(locationPoint.Point.Z);
return new Point3d(x, y, z);
}
// Second try: the element is hosted (e.g. door or window in a wall).
// The insertion point is stored as a parameter along the host's location curve.
Element host = familyInstance.Host;
if (host == null) return null;
LocationCurve locationCurve = host.Location as LocationCurve;
if (locationCurve == null) return null;
// HostParameter is the normalised curve parameter (0..1) of the insertion point
XYZ point = locationCurve.Curve.Evaluate(familyInstance.HostParameter, normalized: false);
if (point == null) return null;
double hx = ConvertUnits.FeetToMeter(point.X);
double hy = ConvertUnits.FeetToMeter(point.Y);
double hz = ConvertUnits.FeetToMeter(point.Z);
return new Point3d(hx, hy, hz);