mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
You can now specify custom project norths when loading in models in absolute terms
This commit is contained in:
@@ -1498,6 +1498,7 @@ class IfcImportSettings:
|
||||
self.distance_limit = 1000
|
||||
self.false_origin_mode = "AUTOMATIC"
|
||||
self.false_origin = None
|
||||
self.project_north = None
|
||||
self.element_offset = 0
|
||||
self.element_limit = 30000
|
||||
self.has_filter = None
|
||||
@@ -1533,6 +1534,10 @@ class IfcImportSettings:
|
||||
settings.false_origin = [float(o) for o in props.false_origin.split(",")[:3]]
|
||||
except:
|
||||
settings.false_origin = [0, 0, 0]
|
||||
try:
|
||||
settings.project_north = float(props.project_north)
|
||||
except:
|
||||
settings.project_north = 0
|
||||
settings.element_offset = props.element_offset
|
||||
settings.element_limit = props.element_limit
|
||||
return settings
|
||||
|
||||
@@ -35,7 +35,6 @@ class GeoreferenceData:
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.data["coordinate_operation_class"] = cls.coordinate_operation_class()
|
||||
cls.data["blender_derived_angle"] = cls.blender_derived_angle()
|
||||
cls.data["coordinate_operation"] = cls.coordinate_operation()
|
||||
cls.data["map_derived_angle"] = cls.map_derived_angle()
|
||||
cls.data["projected_crs"] = cls.projected_crs()
|
||||
@@ -56,19 +55,6 @@ class GeoreferenceData:
|
||||
version = tool.Ifc.get_schema()
|
||||
return [(c, c, get_entity_doc(version, c).get("description", "")) for c in sorted(names)]
|
||||
|
||||
@classmethod
|
||||
def blender_derived_angle(cls):
|
||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||
if props.has_blender_offset:
|
||||
return str(
|
||||
round(
|
||||
ifcopenshell.util.geolocation.xaxis2angle(
|
||||
float(props.blender_x_axis_abscissa), float(props.blender_x_axis_ordinate)
|
||||
),
|
||||
3,
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def coordinate_operation(cls):
|
||||
if tool.Ifc.get_schema() == "IFC2X3":
|
||||
|
||||
@@ -119,11 +119,12 @@ class BIMGeoreferenceProperties(PropertyGroup):
|
||||
blender_eastings: StringProperty(name="Blender Eastings", default="0")
|
||||
blender_northings: StringProperty(name="Blender Northings", default="0")
|
||||
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_project_north: StringProperty(name="Blender Angle to Grid North", 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")
|
||||
blender_x_axis_abscissa: StringProperty(name="Blender X Axis Abscissa", default="1")
|
||||
blender_x_axis_ordinate: StringProperty(name="Blender X Axis Ordinate", default="0")
|
||||
true_north_angle: StringProperty(name="True North Angle", update=update_true_north_angle)
|
||||
true_north_abscissa: StringProperty(name="True North Abscissa", update=update_true_north_vector)
|
||||
true_north_ordinate: StringProperty(name="True North Ordinate", update=update_true_north_vector)
|
||||
|
||||
@@ -92,7 +92,7 @@ class BIM_PT_gis(Panel):
|
||||
|
||||
if props.has_blender_offset:
|
||||
row = self.layout.row()
|
||||
row.label(text="Blender Session Origin", icon="TRACKING_REFINE_FORWARDS")
|
||||
row.label(text="Blender Session Coordinates", icon="TRACKING_REFINE_FORWARDS")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=f"Eastings ({GeoreferenceData.data['local_unit_symbol']})")
|
||||
@@ -104,14 +104,8 @@ class BIM_PT_gis(Panel):
|
||||
row.label(text=f"OrthogonalHeight ({GeoreferenceData.data['local_unit_symbol']})")
|
||||
row.label(text=props.blender_orthogonal_height)
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="XAxisAbscissa")
|
||||
row.label(text=props.blender_x_axis_abscissa)
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="XAxisOrdinate")
|
||||
row.label(text=props.blender_x_axis_ordinate)
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="Derived Grid North")
|
||||
row.label(text=GeoreferenceData.data["blender_derived_angle"])
|
||||
row.label(text="Angle to Grid North")
|
||||
row.label(text=props.blender_project_north)
|
||||
|
||||
if GeoreferenceData.data["projected_crs"]:
|
||||
row = self.layout.row(align=True)
|
||||
@@ -144,7 +138,7 @@ class BIM_PT_gis(Panel):
|
||||
row.label(text=str(value))
|
||||
if key == "XAxisOrdinate":
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="Derived Angle")
|
||||
row.label(text="*Angle to Grid North")
|
||||
row.label(text=GeoreferenceData.data["map_derived_angle"])
|
||||
|
||||
|
||||
@@ -195,7 +189,7 @@ class BIM_PT_gis_true_north(Panel):
|
||||
row.operator("bim.enable_editing_true_north", icon="GREASEPENCIL", text="")
|
||||
row.operator("bim.remove_true_north", icon="X", text="")
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="Derived Angle")
|
||||
row.label(text="*Angle to True North")
|
||||
row.label(text=GeoreferenceData.data["true_derived_angle"])
|
||||
else:
|
||||
row = self.layout.row(align=True)
|
||||
|
||||
@@ -918,6 +918,8 @@ class LinkIfc(bpy.types.Operator):
|
||||
if pprops.false_origin_mode == "MANUAL":
|
||||
row = self.layout.row()
|
||||
row.prop(pprops, "false_origin")
|
||||
row = self.layout.row()
|
||||
row.prop(pprops, "project_north")
|
||||
|
||||
def execute(self, context):
|
||||
start = time.time()
|
||||
@@ -1071,6 +1073,7 @@ def run():
|
||||
pprops.distance_limit = {pprops.distance_limit}
|
||||
pprops.false_origin_mode = "{pprops.false_origin_mode}"
|
||||
pprops.false_origin = "{pprops.false_origin}"
|
||||
pprops.project_north = "{pprops.project_north}"
|
||||
bpy.ops.bim.load_linked_project(filepath="{self.filepath}")
|
||||
bpy.ops.wm.save_as_mainfile(filepath="{blend_filepath}")
|
||||
|
||||
@@ -1413,6 +1416,7 @@ class LoadLinkedProject(bpy.types.Operator):
|
||||
"distance_limit": pprops.distance_limit,
|
||||
"false_origin_mode": pprops.false_origin_mode,
|
||||
"false_origin": pprops.false_origin,
|
||||
"project_north": pprops.project_north,
|
||||
}
|
||||
with open(self.json_filepath, "w") as f:
|
||||
json.dump(data, f)
|
||||
|
||||
@@ -171,6 +171,11 @@ class BIMProjectProperties(PropertyGroup):
|
||||
description="False origin in project units that the Blender origin will correlate to",
|
||||
default="0,0,0",
|
||||
)
|
||||
project_north: StringProperty(
|
||||
name="Angle to Grid North",
|
||||
description="The angle (postive is anticlockwise) pointing to grid north relative to project north",
|
||||
default="0",
|
||||
)
|
||||
element_offset: IntProperty(name="Element Offset", default=0)
|
||||
element_limit: IntProperty(name="Element Offset", default=30000)
|
||||
should_disable_undo_on_save: BoolProperty(
|
||||
|
||||
@@ -175,6 +175,8 @@ class BIM_PT_project(Panel):
|
||||
if pprops.false_origin_mode == "MANUAL":
|
||||
row = self.layout.row()
|
||||
row.prop(pprops, "false_origin")
|
||||
row = self.layout.row()
|
||||
row.prop(pprops, "project_north")
|
||||
|
||||
row = self.layout.row()
|
||||
row.label(text="Element Range")
|
||||
|
||||
@@ -91,7 +91,7 @@ class Georeference(blenderbim.core.tool.Georeference):
|
||||
elif name == "XAxisAbscissa":
|
||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||
props.is_changing_angle = True
|
||||
if data["XAxisAbscissa"] is None or data["XAxisOrdinate"]:
|
||||
if data["XAxisAbscissa"] is None or data["XAxisOrdinate"] is None:
|
||||
props.x_axis_is_null = True
|
||||
else:
|
||||
props.grid_north_angle = str(
|
||||
|
||||
@@ -568,15 +568,36 @@ class Loader(blenderbim.core.tool.Loader):
|
||||
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:
|
||||
has_offset = not np.allclose(model_offset, zero_origin)
|
||||
|
||||
parameters = ifcopenshell.util.geolocation.get_helmert_transformation_parameters(ifc_file)
|
||||
model_north = ifcopenshell.util.geolocation.xaxis2angle(parameters.xaa, parameters.xao)
|
||||
project_north = cls.settings.project_north
|
||||
model_rotation = project_north - model_north
|
||||
if model_rotation > 180:
|
||||
model_rotation = (360 - model_rotation) * -1
|
||||
elif model_rotation < -180:
|
||||
model_rotation = (model_rotation * -1) - 360
|
||||
has_rotation = not np.isclose(model_north, project_north)
|
||||
|
||||
if not has_offset:
|
||||
model_offset = false_origin = (0, 0, 0)
|
||||
|
||||
if not has_rotation:
|
||||
project_north = 0
|
||||
|
||||
if has_offset or has_rotation:
|
||||
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.blender_project_north = str(project_north)
|
||||
props.blender_offset_x = str(model_offset[0])
|
||||
props.blender_offset_y = str(model_offset[1])
|
||||
props.blender_offset_z = str(model_offset[2])
|
||||
xaa, xao = ifcopenshell.util.geolocation.angle2xaxis(model_rotation)
|
||||
props.blender_x_axis_abscissa = str(xaa)
|
||||
props.blender_x_axis_ordinate = str(xao)
|
||||
props.has_blender_offset = True
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -543,7 +543,9 @@ def xaxis2angle(x: float, y: float) -> float:
|
||||
the page?". See the diagram on the IfcGeometricRepresentationContext
|
||||
documentation for clarification.
|
||||
|
||||
The angle indicates "how do I rotate grid east to get to project east?".
|
||||
The angle indicates "how do I rotate project east to get to grid east?".
|
||||
Alternatively: "how do I rotate project north to get to grid north?".
|
||||
Positive angles are anticlockwise.
|
||||
|
||||
:param x: The X axis abscissa
|
||||
:param y: The X axis ordinate
|
||||
@@ -562,6 +564,7 @@ def yaxis2angle(x: float, y: float) -> float:
|
||||
documentation for clarification.
|
||||
|
||||
The angle indicates "how do I rotate project north to get to true north?".
|
||||
Positive angles are anticlockwise.
|
||||
|
||||
:param x: The Y axis abscissa
|
||||
:param y: The Y axis ordinate
|
||||
|
||||
Reference in New Issue
Block a user