mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 02:47:48 +00:00
False origin is always in terms of map coordinates, not as an offset.
Previously, the false origin would be in terms of local coordinates. This means that the same false origin would give two different results on files with different map conversions. Now, false origin is ... well, a true map coordinate and works equally for both IFCs with and without a map conversion.
This commit is contained in:
@@ -539,7 +539,7 @@ class IfcImporter:
|
||||
elif self.ifc_import_settings.false_origin_mode == "DISABLED":
|
||||
return
|
||||
elif self.ifc_import_settings.false_origin_mode == "MANUAL":
|
||||
return tool.Loader.set_manual_blender_offset()
|
||||
return tool.Loader.set_manual_blender_offset(self.file)
|
||||
return tool.Loader.guess_false_origin(self.file)
|
||||
|
||||
def apply_blender_offset_to_matrix_world(self, obj: bpy.types.Object, matrix: np.ndarray) -> mathutils.Matrix:
|
||||
@@ -569,9 +569,9 @@ class IfcImporter:
|
||||
obj.BIMObjectProperties.blender_offset_type = "OBJECT_PLACEMENT"
|
||||
matrix = ifcopenshell.util.geolocation.global2local(
|
||||
matrix,
|
||||
float(props.blender_eastings) * self.unit_scale,
|
||||
float(props.blender_northings) * self.unit_scale,
|
||||
float(props.blender_orthogonal_height) * self.unit_scale,
|
||||
float(props.blender_offset_x) * self.unit_scale,
|
||||
float(props.blender_offset_y) * self.unit_scale,
|
||||
float(props.blender_offset_z) * self.unit_scale,
|
||||
float(props.blender_x_axis_abscissa),
|
||||
float(props.blender_x_axis_ordinate),
|
||||
)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from blenderbim.bim.prop import StrProperty, Attribute
|
||||
from blenderbim.bim.prop import Attribute
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
@@ -49,6 +49,9 @@ class BIMGeoreferenceProperties(PropertyGroup):
|
||||
blender_orthogonal_height: StringProperty(name="Blender Orthogonal Height", default="0")
|
||||
blender_x_axis_abscissa: StringProperty(name="Blender X Axis Abscissa", default="1")
|
||||
blender_x_axis_ordinate: StringProperty(name="Blender X Axis Ordinate", default="0")
|
||||
blender_offset_x: StringProperty(name="Blender Offset X", default="0")
|
||||
blender_offset_y: StringProperty(name="Blender Offset Y", default="0")
|
||||
blender_offset_z: StringProperty(name="Blender Offset Z", default="0")
|
||||
has_true_north: BoolProperty(name="Has True North", default=True)
|
||||
true_north_abscissa: StringProperty(name="True North Abscissa")
|
||||
true_north_ordinate: StringProperty(name="True North Ordinate")
|
||||
|
||||
@@ -90,7 +90,7 @@ class BIM_PT_gis(Panel):
|
||||
|
||||
if props.has_blender_offset:
|
||||
row = self.layout.row()
|
||||
row.label(text="Blender Offset", icon="TRACKING_REFINE_FORWARDS")
|
||||
row.label(text="Blender Session Origin", icon="TRACKING_REFINE_FORWARDS")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="Eastings")
|
||||
|
||||
@@ -555,24 +555,33 @@ class Loader(blenderbim.core.tool.Loader):
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def set_manual_blender_offset(cls) -> None:
|
||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||
props.blender_eastings = str(cls.settings.false_origin[0])
|
||||
props.blender_northings = str(cls.settings.false_origin[1])
|
||||
props.blender_orthogonal_height = str(cls.settings.false_origin[2])
|
||||
props.has_blender_offset = True
|
||||
def set_manual_blender_offset(cls, ifc_file: ifcopenshell.file) -> None:
|
||||
model_origin = np.array(ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, 0, 0, 0))
|
||||
false_origin = np.array(cls.settings.false_origin)
|
||||
model_offset = false_origin - model_origin
|
||||
zero_origin = np.array((0, 0, 0))
|
||||
has_model_offset = not np.allclose(model_offset, zero_origin)
|
||||
if has_model_offset:
|
||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||
props.blender_offset_x = str(model_offset[0])
|
||||
props.blender_offset_y = str(model_offset[1])
|
||||
props.blender_offset_z = str(model_offset[2])
|
||||
props.blender_eastings = str(false_origin[0])
|
||||
props.blender_northings = str(false_origin[1])
|
||||
props.blender_orthogonal_height = str(false_origin[2])
|
||||
props.has_blender_offset = True
|
||||
|
||||
@classmethod
|
||||
def guess_false_origin_and_project_north(cls, element: ifcopenshell.entity_instance) -> None:
|
||||
def guess_false_origin_and_project_north(cls, ifc_file: ifcopenshell.file, element: ifcopenshell.entity_instance) -> None:
|
||||
if not element.ObjectPlacement or not element.ObjectPlacement.is_a("IfcLocalPlacement"):
|
||||
return
|
||||
placement = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
||||
offset_point = [placement[0][3], placement[1][3], placement[2][3]]
|
||||
cls.settings.false_origin = ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, *offset_point)
|
||||
cls.set_manual_blender_offset(ifc_file)
|
||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||
props.blender_eastings = str(placement[0][3])
|
||||
props.blender_northings = str(placement[1][3])
|
||||
props.blender_orthogonal_height = str(placement[2][3])
|
||||
x_axis = mathutils.Vector(placement[:, 0][0:3])
|
||||
default_x_axis = mathutils.Vector((1, 0, 0))
|
||||
x_axis = Vector(placement[:, 0][0:3])
|
||||
default_x_axis = Vector((1, 0, 0))
|
||||
if (default_x_axis - x_axis).length > 0.01:
|
||||
props.blender_x_axis_abscissa = str(placement[0][0])
|
||||
props.blender_x_axis_ordinate = str(placement[1][0])
|
||||
@@ -622,9 +631,10 @@ class Loader(blenderbim.core.tool.Loader):
|
||||
elements_checked += 1
|
||||
mat = ifcopenshell.util.shape.get_shape_matrix(shape)
|
||||
point = mat @ np.array((shape.geometry.verts[0], shape.geometry.verts[1], shape.geometry.verts[2], 1.0))
|
||||
point = point / cls.unit_scale
|
||||
if cls.is_point_far_away(point, is_meters=False):
|
||||
return point
|
||||
if cls.is_point_far_away(point, is_meters=True):
|
||||
# Arbitrary origins should be to the nearest millimeter.
|
||||
# Anything more precise is just ridiculous from a practical surveying perspective.
|
||||
return [round(float(p), 3) / cls.unit_scale for p in point[:3]]
|
||||
|
||||
@classmethod
|
||||
def guess_false_origin_from_elements(cls, ifc_file: ifcopenshell.file) -> None:
|
||||
@@ -635,11 +645,8 @@ class Loader(blenderbim.core.tool.Loader):
|
||||
offset_point = cls.get_offset_point(ifc_file)
|
||||
if offset_point is None:
|
||||
return
|
||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||
props.blender_eastings = str(offset_point[0])
|
||||
props.blender_northings = str(offset_point[1])
|
||||
props.blender_orthogonal_height = str(offset_point[2])
|
||||
props.has_blender_offset = True
|
||||
cls.settings.false_origin = ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, *offset_point)
|
||||
cls.set_manual_blender_offset(ifc_file)
|
||||
|
||||
@classmethod
|
||||
def guess_false_origin(cls, ifc_file: ifcopenshell.file) -> None:
|
||||
@@ -649,8 +656,8 @@ class Loader(blenderbim.core.tool.Loader):
|
||||
project = ifc_file.by_type("IfcContext")[0]
|
||||
site = cls.find_decomposed_ifc_class(project, "IfcSite")
|
||||
if site and cls.is_element_far_away(site):
|
||||
return cls.guess_false_origin_and_project_north(site)
|
||||
return cls.guess_false_origin_and_project_north(ifc_file, site)
|
||||
building = cls.find_decomposed_ifc_class(project, "IfcBuilding")
|
||||
if building and cls.is_element_far_away(building):
|
||||
return cls.guess_false_origin_and_project_north(building)
|
||||
return cls.guess_false_origin_and_project_north(ifc_file, building)
|
||||
return cls.guess_false_origin_from_elements(ifc_file)
|
||||
|
||||
Reference in New Issue
Block a user