from Autodesk.Revit.DB import *
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
app = doc.Application
rvt_year = int(app.VersionNumber)
def convert_internal_units(value, get_internal=True, units='m'):
"""Function to convert Internal units to meters or vice versa.
:param value: Value to convert
:param get_internal: True to get internal units, False to get Meters
:param units: Select desired Units: ['m',]
:return: Length in Internal units or Meters."""
if rvt_year >= 2021:
if units == 'm': units = UnitTypeId.Meters
else:
if units == 'm': units = DisplayUnitType.DUT_METERS
if get_internal:
return UnitUtils.ConvertToInternalUnits(value, units)
return UnitUtils.ConvertFromInternalUnits(value, units)
class PointConverter:
pt_internal = None
pt_survey = None
pt_project = None
def __init__(self, x, y, z, coord_sys='internal'):
""" PointConverter - Convert coordinate into desired coordinate system.
Args:
x : Float in meters representing the x-coordinate.
y : Float in meters representing the y-coordinate.
z : Float in meters representing the z-coordinate.
coord_sys : Coordinate System of provided coordinates.
Possible values: 'internal'/'project'/'survey'
Return: None"""
srvTrans = self.GetSurveyTransform()
projTrans = self.GetProjectTransform()
X = convert_internal_units(x, get_internal=True)
Y = convert_internal_units(y, get_internal=True)
Z = convert_internal_units(z, get_internal=True)
if coord_sys.lower() == 'internal':
self.pt_internal = XYZ(X, Y, Z)
self.pt_survey = self.ApplyInverseTransformation(srvTrans, self.pt_internal)
self.pt_project = self.ApplyInverseTransformation(projTrans, self.pt_internal)
elif coord_sys.lower() == 'project':
self.pt_project = XYZ(X, Y, Z)
self.pt_internal = self.ApplyTransformation(projTrans, self.pt_project)
self.pt_survey = self.ApplyInverseTransformation(srvTrans, self.pt_internal)
elif coord_sys.lower() == 'survey':
self.pt_survey = XYZ(X, Y, Z)
self.pt_internal = self.ApplyTransformation(srvTrans, self.pt_survey)
self.pt_project = self.ApplyInverseTransformation(projTrans, self.pt_internal)
else: raise Exception("Wrong argument value for 'coord_sys' in PointConverter class.")
def GetSurveyTransform(self):
"""Gets the Active Project Locations Transform (Survey)."""
return doc.ActiveProjectLocation.GetTotalTransform()
def GetProjectTransform(self):
"""Get the Project Base Points Transform."""
basePtLoc = next((l for l in FilteredElementCollector(doc) \
.OfClass(ProjectLocation) \
.WhereElementIsNotElementType() \
.ToElements() if l.Name == "Project"), None)
return basePtLoc.GetTotalTransform()
def ApplyInverseTransformation(self, t, pt):
"""Applies the inverse transformation of
the given Transform to the given point."""
return t.Inverse.OfPoint(pt)
def ApplyTransformation(self, t, pt):
"""Applies the transformation of
the given Transform to the given point."""
return t.OfPoint(pt)
def print_coord_in_m(pt, prefix=""):
"""Helper Function to display Point Coordinates
in Meters to compare to Coordinates displayed in Revit."""
x = round(convert_internal_units(pt.X, get_internal=False), 4)
y = round(convert_internal_units(pt.Y, get_internal=False), 4)
z = round(convert_internal_units(pt.Z, get_internal=False), 4)
print(prefix, 'N:{}'.format(y), 'E:{}'.format(x), 'Elev:{}'.format(z))
X = 2.8284
Y = -4.899
Z = 0
converter = PointConverter(X, Y, Z, coord_sys='survey')
pt_internal = converter.pt_internal
pt_project = converter.pt_project
pt_survey = converter.pt_survey
print_coord_in_m(pt_internal, prefix='Internal: ')
print_coord_in_m(pt_project, prefix='Project: ')
print_coord_in_m(pt_survey, prefix='Survey: ')
Author = 'Erik Frits'