mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
Improve absolute coordinate support for georeferencing
This commit is contained in:
@@ -107,7 +107,9 @@ class MaterialCreator():
|
|||||||
slots = [s.name for s in obj.material_slots]
|
slots = [s.name for s in obj.material_slots]
|
||||||
material_to_slot = {}
|
material_to_slot = {}
|
||||||
for i, material in enumerate(mesh['ios_materials']):
|
for i, material in enumerate(mesh['ios_materials']):
|
||||||
if 'surface-style-' in material:
|
if material == 'NULLMAT':
|
||||||
|
continue
|
||||||
|
elif 'surface-style-' in material:
|
||||||
material = material.split('-')[2]
|
material = material.split('-')[2]
|
||||||
material_to_slot[i] = slots.index(material)
|
material_to_slot[i] = slots.index(material)
|
||||||
|
|
||||||
@@ -315,8 +317,10 @@ class IfcImporter():
|
|||||||
self.clean_mesh()
|
self.clean_mesh()
|
||||||
|
|
||||||
def auto_set_workarounds(self):
|
def auto_set_workarounds(self):
|
||||||
if 'DDS-CAD' in self.file.wrapped_data.header.file_name.originating_system:
|
if 'DDS-CAD' in self.file.wrapped_data.header.file_name.originating_system \
|
||||||
|
or 'DDS' in self.file.wrapped_data.header.file_name.preprocessor_version:
|
||||||
self.ifc_import_settings.should_treat_styled_item_as_material = True
|
self.ifc_import_settings.should_treat_styled_item_as_material = True
|
||||||
|
self.ifc_import_settings.should_reset_absolute_coordinates = True
|
||||||
applications = self.file.by_type('IfcApplication')
|
applications = self.file.by_type('IfcApplication')
|
||||||
if not applications:
|
if not applications:
|
||||||
return
|
return
|
||||||
@@ -345,9 +349,13 @@ class IfcImporter():
|
|||||||
|
|
||||||
def is_point_far_away(self, point):
|
def is_point_far_away(self, point):
|
||||||
# Arbitrary threshold based on experience
|
# Arbitrary threshold based on experience
|
||||||
return abs(point.Coordinates[0]) > 1000000 \
|
if hasattr(point, 'Coordinates'):
|
||||||
or abs(point.Coordinates[1]) > 1000000 \
|
return abs(point.Coordinates[0]) > 1000000 \
|
||||||
or abs(point.Coordinates[2]) > 1000000
|
or abs(point.Coordinates[1]) > 1000000 \
|
||||||
|
or abs(point.Coordinates[2]) > 1000000
|
||||||
|
return abs(point[0]) > 1000000 \
|
||||||
|
or abs(point[1]) > 1000000 \
|
||||||
|
or abs(point[2]) > 1000000
|
||||||
|
|
||||||
def process_element_filter(self):
|
def process_element_filter(self):
|
||||||
if not self.ifc_import_settings.ifc_selector:
|
if not self.ifc_import_settings.ifc_selector:
|
||||||
@@ -461,6 +469,22 @@ class IfcImporter():
|
|||||||
# 12D can have some funky coordinates out of any sensible range. This
|
# 12D can have some funky coordinates out of any sensible range. This
|
||||||
# method will not work all the time, but will catch most issues.
|
# method will not work all the time, but will catch most issues.
|
||||||
offset_point = None
|
offset_point = None
|
||||||
|
for point_list in self.file.by_type('IfcCartesianPointList3D'):
|
||||||
|
coord_list = [None] * len(point_list.CoordList)
|
||||||
|
for i, point in enumerate(point_list.CoordList):
|
||||||
|
if len(point) == 2 or not self.is_point_far_away(point):
|
||||||
|
coord_list[i] = point
|
||||||
|
continue
|
||||||
|
if not offset_point:
|
||||||
|
offset_point = (point[0], point[1], point[2])
|
||||||
|
self.ifc_import_settings.logger.info(f'Resetting absolute coordinates by {point}')
|
||||||
|
point = (
|
||||||
|
point[0] - offset_point[0],
|
||||||
|
point[1] - offset_point[1],
|
||||||
|
point[2] - offset_point[2]
|
||||||
|
)
|
||||||
|
coord_list[i] = point
|
||||||
|
point_list.CoordList = coord_list
|
||||||
for point in self.file.by_type('IfcCartesianPoint'):
|
for point in self.file.by_type('IfcCartesianPoint'):
|
||||||
if len(point.Coordinates) == 2 or not self.is_point_far_away(point):
|
if len(point.Coordinates) == 2 or not self.is_point_far_away(point):
|
||||||
continue
|
continue
|
||||||
@@ -504,19 +528,33 @@ class IfcImporter():
|
|||||||
projected_crs = projected_crs[0]
|
projected_crs = projected_crs[0]
|
||||||
scene = bpy.context.scene
|
scene = bpy.context.scene
|
||||||
scene.BIMProperties.has_georeferencing = True
|
scene.BIMProperties.has_georeferencing = True
|
||||||
scene.MapConversion.eastings = str(map_conversion.Eastings)
|
map_conversion_map = {
|
||||||
scene.MapConversion.northings = str(map_conversion.Northings)
|
'Eastings': 'eastings',
|
||||||
scene.MapConversion.orthogonal_height = str(map_conversion.OrthogonalHeight)
|
'Northings': 'northings',
|
||||||
scene.MapConversion.x_axis_abscissa = str(map_conversion.XAxisAbscissa)
|
'OrthogonalHeight': 'orthogonal_height',
|
||||||
scene.MapConversion.x_axis_ordinate = str(map_conversion.XAxisOrdinate)
|
'XAxisAbscissa': 'x_axis_abscissa',
|
||||||
scene.MapConversion.scale = str(map_conversion.Scale)
|
'XAxisOrdinate': 'x_axis_ordinate',
|
||||||
scene.TargetCRS.name = projected_crs.Name
|
'Scale': 'scale'
|
||||||
scene.TargetCRS.description = projected_crs.Description
|
}
|
||||||
scene.TargetCRS.geodetic_datum = projected_crs.GeodeticDatum
|
target_crs_map = {
|
||||||
scene.TargetCRS.vertical_datum = projected_crs.VerticalDatum
|
'Name': 'name',
|
||||||
scene.TargetCRS.map_projection = projected_crs.MapProjection
|
'Description': 'description',
|
||||||
scene.TargetCRS.map_zone = projected_crs.MapZone
|
'GeodeticDatum': 'geodetic_datum',
|
||||||
scene.TargetCRS.map_unit = self.get_unit_name(projected_crs.MapUnit)
|
'VerticalDatum': 'vertical_datum',
|
||||||
|
'MapProjection': 'map_projection',
|
||||||
|
'MapZone': 'map_zone',
|
||||||
|
'MapUnit': 'map_unit'
|
||||||
|
}
|
||||||
|
for keyA, keyB in map_conversion_map.items():
|
||||||
|
value = getattr(map_conversion, keyA)
|
||||||
|
if value is not None:
|
||||||
|
setattr(scene.MapConversion, keyB, str(value))
|
||||||
|
for keyA, keyB in target_crs_map.items():
|
||||||
|
value = getattr(projected_crs, keyA)
|
||||||
|
if value is not None:
|
||||||
|
if keyA == 'MapUnit':
|
||||||
|
value = self.get_unit_name(value)
|
||||||
|
setattr(scene.TargetCRS, keyB, str(value))
|
||||||
|
|
||||||
def get_unit_name(self, named_unit):
|
def get_unit_name(self, named_unit):
|
||||||
name = ''
|
name = ''
|
||||||
|
|||||||
Reference in New Issue
Block a user