mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
New option to ignore site, to import incorrectly geolocated IFCs
This behaviour occurs extensively in IFC files coming from Revit
This commit is contained in:
@@ -16,35 +16,6 @@ class IfcSchema():
|
||||
|
||||
ifc_schema = IfcSchema()
|
||||
|
||||
# Helper functions, to be refactored
|
||||
|
||||
def a2p(o,z,x):
|
||||
y = z.cross(x)
|
||||
r = mathutils.Matrix((x, y, z, o))
|
||||
r.resize_4x4()
|
||||
r.transpose()
|
||||
return r
|
||||
|
||||
def get_axis2placement(plc):
|
||||
z = mathutils.Vector(plc.Axis.DirectionRatios if plc.Axis else (0,0,1))
|
||||
x = mathutils.Vector(plc.RefDirection.DirectionRatios if plc.RefDirection else (1,0,0))
|
||||
o = plc.Location.Coordinates
|
||||
return a2p(o,z,x)
|
||||
|
||||
def get_cartesiantransformationoperator(plc):
|
||||
#z = mathutils.Vector(plc.Axis3.DirectionRatios if plc.Axis3 else (0,0,1))
|
||||
x = mathutils.Vector(plc.Axis1.DirectionRatios if plc.Axis1 else (1,0,0))
|
||||
z = x.cross(mathutils.Vector(plc.Axis2.DirectionRatios if plc.Axis2 else (0,1,0)))
|
||||
o = plc.LocalOrigin.Coordinates
|
||||
return a2p(o,z,x)
|
||||
|
||||
def get_local_placement(plc):
|
||||
if plc.PlacementRelTo is None:
|
||||
parent = mathutils.Matrix()
|
||||
else:
|
||||
parent = get_local_placement(plc.PlacementRelTo)
|
||||
return parent @ get_axis2placement(plc.RelativePlacement)
|
||||
|
||||
class MaterialCreator():
|
||||
def __init__(self):
|
||||
self.mesh = None
|
||||
@@ -202,7 +173,7 @@ class IfcImporter():
|
||||
|
||||
object = bpy.data.objects.new(self.get_name(element), mesh)
|
||||
|
||||
element_matrix = get_local_placement(element.ObjectPlacement)
|
||||
element_matrix = self.get_local_placement(element.ObjectPlacement)
|
||||
|
||||
# Blender supports reusing a mesh with a different transformation
|
||||
# applied at the object level. In contrast, IFC supports reusing a mesh
|
||||
@@ -217,7 +188,7 @@ class IfcImporter():
|
||||
shared_shape_transformation = self.get_representation_cartesian_transformation(
|
||||
self.file.by_id(self.mesh_shapes[mesh_name].product.id()))
|
||||
if shared_shape_transformation:
|
||||
shared_transform = get_cartesiantransformationoperator(shared_shape_transformation)
|
||||
shared_transform = self.get_cartesiantransformationoperator(shared_shape_transformation)
|
||||
shared_transform.invert()
|
||||
element_matrix = element_matrix @ shared_transform
|
||||
|
||||
@@ -225,7 +196,7 @@ class IfcImporter():
|
||||
# transformation to our current element's object transformation
|
||||
transformation = self.get_representation_cartesian_transformation(element)
|
||||
if transformation:
|
||||
element_matrix = get_cartesiantransformationoperator(transformation) @ element_matrix
|
||||
element_matrix = self.get_cartesiantransformationoperator(transformation) @ element_matrix
|
||||
|
||||
element_matrix[0][3] *= self.unit_scale
|
||||
element_matrix[1][3] *= self.unit_scale
|
||||
@@ -298,8 +269,39 @@ class IfcImporter():
|
||||
print('Could not create mesh for {}: {}/{}'.format(
|
||||
element.GlobalId, self.get_name(element)))
|
||||
|
||||
def a2p(self, o, z, x):
|
||||
y = z.cross(x)
|
||||
r = mathutils.Matrix((x, y, z, o))
|
||||
r.resize_4x4()
|
||||
r.transpose()
|
||||
return r
|
||||
|
||||
def get_axis2placement(self, plc):
|
||||
z = mathutils.Vector(plc.Axis.DirectionRatios if plc.Axis else (0,0,1))
|
||||
x = mathutils.Vector(plc.RefDirection.DirectionRatios if plc.RefDirection else (1,0,0))
|
||||
o = plc.Location.Coordinates
|
||||
return self.a2p(o,z,x)
|
||||
|
||||
def get_cartesiantransformationoperator(self, plc):
|
||||
#z = mathutils.Vector(plc.Axis3.DirectionRatios if plc.Axis3 else (0,0,1))
|
||||
x = mathutils.Vector(plc.Axis1.DirectionRatios if plc.Axis1 else (1,0,0))
|
||||
z = x.cross(mathutils.Vector(plc.Axis2.DirectionRatios if plc.Axis2 else (0,1,0)))
|
||||
o = plc.LocalOrigin.Coordinates
|
||||
return self.a2p(o,z,x)
|
||||
|
||||
def get_local_placement(self, plc):
|
||||
if plc.PlacementRelTo is None:
|
||||
parent = mathutils.Matrix()
|
||||
else:
|
||||
parent = self.get_local_placement(plc.PlacementRelTo)
|
||||
if self.ifc_import_settings.should_ignore_site_coordinates \
|
||||
and 'IfcSite' in [o.is_a() for o in plc.PlacesObject]:
|
||||
return parent
|
||||
return parent @ self.get_axis2placement(plc.RelativePlacement)
|
||||
|
||||
class IfcImportSettings:
|
||||
def __init__(self):
|
||||
self.logger = None
|
||||
self.input_file = None
|
||||
self.should_ignore_site_coordinates = False
|
||||
self.should_import_curves = False
|
||||
|
||||
@@ -58,6 +58,7 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
|
||||
ifc_import_settings.logger = logging.getLogger('ImportIFC')
|
||||
ifc_import_settings.logger.info('Starting import')
|
||||
ifc_import_settings.input_file = self.filepath
|
||||
ifc_import_settings.should_ignore_site_coordinates = bpy.context.scene.BIMProperties.import_should_ignore_site_coordinates
|
||||
ifc_import_settings.should_import_curves = bpy.context.scene.BIMProperties.import_should_import_curves
|
||||
ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
|
||||
ifc_importer.execute()
|
||||
|
||||
@@ -63,6 +63,7 @@ class BIMProperties(bpy.types.PropertyGroup):
|
||||
export_has_representations: bpy.props.BoolProperty(name="Export Representations", default=True)
|
||||
export_should_export_all_materials_as_styled_items: bpy.props.BoolProperty(name="Export All Materials as Styled Items", default=False)
|
||||
export_should_use_presentation_style_assignment: bpy.props.BoolProperty(name="Export with Presentation Style Assignment", default=False)
|
||||
import_should_ignore_site_coordinates: bpy.props.BoolProperty(name="Import Ignoring Site Coordinates", default=False)
|
||||
import_should_import_curves: bpy.props.BoolProperty(name="Import Curves", default=False)
|
||||
qa_reject_element_reason: bpy.props.StringProperty(name="Element Rejection Reason")
|
||||
pset_name: bpy.props.EnumProperty(items=getPsetNames, name="Pset Name")
|
||||
@@ -452,5 +453,7 @@ class MVDPanel(bpy.types.Panel):
|
||||
row = layout.row()
|
||||
row.prop(bim_properties, "export_should_use_presentation_style_assignment")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(bim_properties, "import_should_ignore_site_coordinates")
|
||||
row = layout.row()
|
||||
row.prop(bim_properties, "import_should_import_curves")
|
||||
|
||||
Reference in New Issue
Block a user