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/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations from __future__ import annotations
import os
import re
import bpy import bpy
import time import time
import json import json
import bmesh
import logging import logging
import mathutils import mathutils
import numpy as np import numpy as np
import numpy.typing as npt
import multiprocessing import multiprocessing
import ifcopenshell import ifcopenshell
import ifcopenshell.geom import ifcopenshell.geom
@@ -37,8 +33,6 @@ import ifcopenshell.util.placement
import ifcopenshell.util.representation import ifcopenshell.util.representation
import ifcopenshell.util.shape import ifcopenshell.util.shape
import blenderbim.tool as tool import blenderbim.tool as tool
import blenderbim.core.spatial
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
from itertools import chain, accumulate from itertools import chain, accumulate
from blenderbim.bim.ifc import IfcStore, IFC_CONNECTED_TYPE from blenderbim.bim.ifc import IfcStore, IFC_CONNECTED_TYPE
from blenderbim.tool.loader import OBJECT_DATA_TYPE from blenderbim.tool.loader import OBJECT_DATA_TYPE
@@ -542,19 +536,11 @@ class IfcImporter:
props = bpy.context.scene.BIMGeoreferenceProperties props = bpy.context.scene.BIMGeoreferenceProperties
if props.has_blender_offset: if props.has_blender_offset:
return 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() return tool.Loader.set_manual_blender_offset()
if self.file.schema == "IFC2X3": return tool.Loader.guess_false_origin(self.file)
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)
def apply_blender_offset_to_matrix_world(self, obj: bpy.types.Object, matrix: np.ndarray) -> mathutils.Matrix: def apply_blender_offset_to_matrix_world(self, obj: bpy.types.Object, matrix: np.ndarray) -> mathutils.Matrix:
props = bpy.context.scene.BIMGeoreferenceProperties 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 # 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 # Users can configure this if they have to handle larger sites but beware of surveying precision
self.distance_limit = 1000 self.distance_limit = 1000
self.false_origin_mode = "AUTOMATIC"
self.false_origin = None self.false_origin = None
self.element_offset = 0 self.element_offset = 0
self.element_limit = 30000 self.element_limit = 30000
@@ -1591,9 +1578,11 @@ class IfcImportSettings:
settings.angular_tolerance = props.angular_tolerance settings.angular_tolerance = props.angular_tolerance
settings.void_limit = props.void_limit settings.void_limit = props.void_limit
settings.distance_limit = props.distance_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 settings.false_origin_mode = props.false_origin_mode
if settings.false_origin == [0, 0, 0]: try:
settings.false_origin = None 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_offset = props.element_offset
settings.element_limit = props.element_limit settings.element_limit = props.element_limit
return settings return settings
@@ -153,13 +153,22 @@ class BIMProjectProperties(PropertyGroup):
angular_tolerance: FloatProperty(name="Angular Tolerance", default=0.5) angular_tolerance: FloatProperty(name="Angular Tolerance", default=0.5)
void_limit: IntProperty(name="Void Limit", default=30) void_limit: IntProperty(name="Void Limit", default=30)
distance_limit: FloatProperty(name="Distance Limit", default=1000, subtype="DISTANCE") 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( false_origin: StringProperty(
name="False Origin", name="False Origin",
description=( description="False origin in project units that the Blender origin will correlate to",
"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"
),
default="0,0,0", default="0,0,0",
) )
element_offset: IntProperty(name="Element Offset", default=0) element_offset: IntProperty(name="Element Offset", default=0)
@@ -145,7 +145,10 @@ class BIM_PT_project(Panel):
row = self.layout.row() row = self.layout.row()
row.prop(pprops, "distance_limit") row.prop(pprops, "distance_limit")
row = self.layout.row() 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 = self.layout.row()
row.label(text="Element Range") 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_northings = str(offset_point[1])
props.blender_orthogonal_height = str(offset_point[2]) props.blender_orthogonal_height = str(offset_point[2])
props.has_blender_offset = True 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)