False origins can now be explicitly auto, manual, or disabled

This commit is contained in:
Dion Moult
2024-06-16 14:50:33 +10:00
parent b253b74e88
commit 348ef4023f
4 changed files with 42 additions and 27 deletions
+10 -21
View File
@@ -17,16 +17,12 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import os
import re
import bpy
import time
import json
import bmesh
import logging
import mathutils
import numpy as np
import numpy.typing as npt
import multiprocessing
import ifcopenshell
import ifcopenshell.geom
@@ -37,8 +33,6 @@ import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape
import blenderbim.tool as tool
import blenderbim.core.spatial
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
from itertools import chain, accumulate
from blenderbim.bim.ifc import IfcStore, IFC_CONNECTED_TYPE
from blenderbim.tool.loader import OBJECT_DATA_TYPE
@@ -542,19 +536,11 @@ class IfcImporter:
props = bpy.context.scene.BIMGeoreferenceProperties
if props.has_blender_offset:
return
if self.ifc_import_settings.false_origin:
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()
if self.file.schema == "IFC2X3":
project = self.file.by_type("IfcProject")[0]
else:
project = self.file.by_type("IfcContext")[0]
site = tool.Loader.find_decomposed_ifc_class(project, "IfcSite")
if site and tool.Loader.is_element_far_away(site):
return tool.Loader.guess_false_origin_and_project_north(site)
building = tool.Loader.find_decomposed_ifc_class(project, "IfcBuilding")
if building and tool.Loader.is_element_far_away(building):
return tool.Loader.guess_false_origin_and_project_north(building)
return tool.Loader.guess_false_origin_from_elements(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:
props = bpy.context.scene.BIMGeoreferenceProperties
@@ -1560,6 +1546,7 @@ class IfcImportSettings:
# Locations greater than 1km are not considered "small sites" according to the georeferencing guide
# Users can configure this if they have to handle larger sites but beware of surveying precision
self.distance_limit = 1000
self.false_origin_mode = "AUTOMATIC"
self.false_origin = None
self.element_offset = 0
self.element_limit = 30000
@@ -1591,9 +1578,11 @@ class IfcImportSettings:
settings.angular_tolerance = props.angular_tolerance
settings.void_limit = props.void_limit
settings.distance_limit = props.distance_limit
settings.false_origin = [float(o) for o in props.false_origin.split(",")] if props.false_origin else None
if settings.false_origin == [0, 0, 0]:
settings.false_origin = None
settings.false_origin_mode = props.false_origin_mode
try:
settings.false_origin = [float(o) for o in props.false_origin.split(",")[:3]]
except:
settings.false_origin = [0, 0, 0]
settings.element_offset = props.element_offset
settings.element_limit = props.element_limit
return settings
@@ -153,13 +153,22 @@ class BIMProjectProperties(PropertyGroup):
angular_tolerance: FloatProperty(name="Angular Tolerance", default=0.5)
void_limit: IntProperty(name="Void Limit", default=30)
distance_limit: FloatProperty(name="Distance Limit", default=1000, subtype="DISTANCE")
false_origin_mode: bpy.props.EnumProperty(
items=[
(
"AUTOMATIC",
"Automatic",
"An automatic false origin will be detected from geometry with large coordinates",
),
("MANUAL", "Manual", "You can specify the false origin coordinates"),
("DISABLED", "Disabled", "The model in original local coordinates will be shown as is"),
],
name="False Origin Mode",
default="AUTOMATIC",
)
false_origin: StringProperty(
name="False Origin",
description=(
"False origin that will be used to offset the entire model.\n"
"(0,0,0) value is interpreted as an unset false origin - false origin will be guessed based on Distance Limit.\n"
"False origin is defined in project units"
),
description="False origin in project units that the Blender origin will correlate to",
default="0,0,0",
)
element_offset: IntProperty(name="Element Offset", default=0)
@@ -145,7 +145,10 @@ class BIM_PT_project(Panel):
row = self.layout.row()
row.prop(pprops, "distance_limit")
row = self.layout.row()
row.prop(pprops, "false_origin")
row.prop(pprops, "false_origin_mode")
if pprops.false_origin_mode == "MANUAL":
row = self.layout.row()
row.prop(pprops, "false_origin")
row = self.layout.row()
row.label(text="Element Range")
+14
View File
@@ -665,3 +665,17 @@ class Loader(blenderbim.core.tool.Loader):
props.blender_northings = str(offset_point[1])
props.blender_orthogonal_height = str(offset_point[2])
props.has_blender_offset = True
@classmethod
def guess_false_origin(cls, ifc_file: ifcopenshell.file) -> None:
if ifc_file.schema == "IFC2X3":
project = ifc_file.by_type("IfcProject")[0]
else:
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)
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_from_elements(ifc_file)