Implement model offset workaround for Bentley ProStructures. See #1047.

In an ideal world, projects are geolocated properly in IFC. If not, they tend to store it in the spatial structure placement which is then inherited (e.g. Revit) or in the geometry coords themselves (e.g. 12D). In the case of Bentley ProStructures, it seemas s though large coords can be found in both object placements and geometry coords and who knows where else. In this scenario, a model offset is a clean solution rather than patching. However, it will lead to mesh inaccuracies in Blender due to the mixing of large numbers in both object locations and geometry coordinates.

Also model offsetting is useful to have available in general.
This commit is contained in:
Dion Moult
2020-10-26 13:36:18 +11:00
parent ef0f00792a
commit e1c1cf6c9b
3 changed files with 19 additions and 1 deletions
@@ -17,6 +17,7 @@ import multiprocessing
import zipfile
import tempfile
from pathlib import Path
from itertools import cycle
from . import helper
from . import schema
from . import ifc
@@ -1933,7 +1934,13 @@ class IfcImporter():
num_vertex_indices = len(geometry.faces)
mesh.vertices.add(num_vertices)
mesh.vertices.foreach_set('co', geometry.verts)
if self.ifc_import_settings.should_offset_model:
# Potentially, there is a smarter way to do this. See #1047
v_index = cycle((0, 1, 2))
verts = [v+self.ifc_import_settings.model_offset_coordinates[next(v_index)] for v in geometry.verts]
mesh.vertices.foreach_set('co', verts)
else:
mesh.vertices.foreach_set('co', geometry.verts)
mesh.loops.add(num_vertex_indices)
mesh.loops.foreach_set('vertex_index', geometry.faces)
mesh.polygons.add(num_loops)
@@ -2128,6 +2135,8 @@ class IfcImportSettings:
settings.should_merge_by_material = scene_bim.import_should_merge_by_material
settings.should_merge_materials_by_colour = scene_bim.import_should_merge_materials_by_colour
settings.should_clean_mesh = scene_bim.import_should_clean_mesh
settings.should_offset_model = scene_bim.import_should_offset_model
settings.model_offset_coordinates = [float(o) for o in scene_bim.import_model_offset_coordinates.split(',')] if scene_bim.import_model_offset_coordinates else (0, 0, 0)
settings.deflection_tolerance = scene_bim.import_deflection_tolerance
settings.angular_tolerance = scene_bim.import_angular_tolerance
return settings
@@ -1216,6 +1216,8 @@ class BIMProperties(PropertyGroup):
import_should_clean_mesh: BoolProperty(name="Import and Clean Mesh", default=True)
import_deflection_tolerance: FloatProperty(name="Import Deflection Tolerance", default=0.001)
import_angular_tolerance: FloatProperty(name="Import Angular Tolerance", default=0.5)
import_should_offset_model: BoolProperty(name="Import and Offset Model", default=False)
import_model_offset_coordinates: StringProperty(name="Model Offset Coordinates", default='0,0,0')
qa_reject_element_reason: StringProperty(name="Element Rejection Reason")
person: EnumProperty(items=getPersons, name="Person")
organisation: EnumProperty(items=getOrganisations, name="Organisation")
@@ -1754,6 +1754,13 @@ class BIM_PT_mvd(Panel):
row = layout.row()
row.prop(bim_properties, 'import_should_ignore_site_coordinates')
layout.label(text='ProStructures Workarounds:')
row = layout.row()
row.prop(bim_properties, 'import_should_offset_model')
row = layout.row()
row.prop(bim_properties, 'import_model_offset_coordinates')
layout.label(text='12D Workarounds:')
row = layout.row()