Revert "Refactor BIM_PT_gis"

This reverts commit 265ebaebb8.
This commit is contained in:
Dion Moult
2022-04-28 17:25:22 +10:00
parent 200a343746
commit 9483abcdd5
5 changed files with 355 additions and 95 deletions
@@ -24,15 +24,15 @@ classes = (
operator.DisableEditingGeoreferencing, operator.DisableEditingGeoreferencing,
operator.EditGeoreferencing, operator.EditGeoreferencing,
operator.SetIfcGridNorth, operator.SetIfcGridNorth,
# operator.SetBlenderGridNorth, operator.SetBlenderGridNorth,
# operator.SetIfcTrueNorth, operator.SetIfcTrueNorth,
# operator.SetBlenderTrueNorth, operator.SetBlenderTrueNorth,
operator.RemoveGeoreferencing, operator.RemoveGeoreferencing,
operator.AddGeoreferencing, operator.AddGeoreferencing,
# operator.ConvertLocalToGlobal, operator.ConvertLocalToGlobal,
# operator.ConvertGlobalToLocal, operator.ConvertGlobalToLocal,
# operator.GetCursorLocation, operator.GetCursorLocation,
# operator.SetCursorLocation, operator.SetCursorLocation,
prop.BIMGeoreferenceProperties, prop.BIMGeoreferenceProperties,
ui.BIM_PT_gis, ui.BIM_PT_gis,
ui.BIM_PT_gis_utilities, ui.BIM_PT_gis_utilities,
@@ -17,72 +17,345 @@
# 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/>.
import bpy import bpy
import blenderbim.tool as tool import json
import blenderbim.core.georeference as core import ifcopenshell
import blenderbim.bim.handler import ifcopenshell.util.unit
import ifcopenshell.util.attribute
import ifcopenshell.api
import blenderbim.bim.helper
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.georeference.data import Data
from ifcopenshell.api.unit.data import Data as UnitData
from math import radians, degrees, atan, tan, cos, sin
class AddGeoreferencing(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_georeferencing"
bl_label = "Add Georeferencing"
bl_options = {"REGISTER", "UNDO"}
bl_description = "Add a new georeference"
def _execute(self, context): class EnableEditingGeoreferencing(bpy.types.Operator):
core.add_georeferencing(tool.Ifc)
class EnableEditingGeoreferencing(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.enable_editing_georeferencing" bl_idname = "bim.enable_editing_georeferencing"
bl_label = "Enable Editing Georeferencing" bl_label = "Enable Editing Georeferencing"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
bl_description = "Enable editing georeferencing"
def _execute(self, context):
core.enable_editing_georeferencing(tool.Georeference)
class RemoveGeoreferencing(bpy.types.Operator, tool.Ifc.Operator): def execute(self, context):
bl_idname = "bim.remove_georeferencing" self.file = IfcStore.get_file()
bl_label = "Remove Georeferencing" props = context.scene.BIMGeoreferenceProperties
bl_options = {"REGISTER", "UNDO"} self.props = props
bl_description = "Remove the georeferencing"
props.projected_crs.clear()
def _execute(self, context):
core.remove_georeferencing(tool.Ifc) blenderbim.bim.helper.import_attributes(
"IfcProjectedCRS", props.projected_crs, Data.projected_crs, self.import_projected_crs_attributes
class EditGeoreferencing(bpy.types.Operator, tool.Ifc.Operator): )
bl_idname = "bim.edit_georeferencing"
bl_label = "Edit Georeferencing" props.map_conversion.clear()
bl_options = {"REGISTER", "UNDO"} blenderbim.bim.helper.import_attributes(
bl_description = "Edit the georeferencing" "IfcMapConversion", props.map_conversion, Data.map_conversion, self.import_map_conversion_attributes
)
def _execute(self, context):
core.edit_georeferencing(tool.Ifc, tool.Georeference) props.has_true_north = bool(Data.true_north)
if Data.true_north:
class DisableEditingGeoreferencing(bpy.types.Operator, tool.Ifc.Operator): props.true_north_abscissa = str(Data.true_north[0])
props.true_north_ordinate = str(Data.true_north[1])
props.is_editing = True
return {"FINISHED"}
def import_projected_crs_attributes(self, name, prop, data):
if name == "MapUnit":
new = self.props.projected_crs.add()
new.name = name
new.data_type = "enum"
new.is_null = data[name] is None
new.is_optional = True
new.enum_items = json.dumps(
{u["id"]: u["Name"] for u in UnitData.units.values() if u["UnitType"] == "LENGTHUNIT"}
)
if data["MapUnit"]:
new.enum_value = str(data["MapUnit"]["id"])
return True
def import_map_conversion_attributes(self, name, prop, data):
if name not in ["SourceCRS", "TargetCRS"]:
# Enforce a string data type to prevent data loss in single-precision Blender props
prop.data_type = "string"
prop.string_value = "" if prop.is_null else str(data[name])
return True
class DisableEditingGeoreferencing(bpy.types.Operator):
bl_idname = "bim.disable_editing_georeferencing" bl_idname = "bim.disable_editing_georeferencing"
bl_label = "Disable Editing Georeferencing" bl_label = "Disable Editing Georeferencing"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
bl_description = "Close editing panel"
def _execute(self, context): def execute(self, context):
core.disable_editing_georeferencing(tool.Georeference) props = context.scene.BIMGeoreferenceProperties
props.is_editing = False
return {"FINISHED"}
class SetIfcGridNorth(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.set_ifc_grid_north" class EditGeoreferencing(bpy.types.Operator):
bl_label = "Set IFC Grid North" bl_idname = "bim.edit_georeferencing"
bl_label = "Edit Georeferencing"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
bl_description = "Set IFC grid north"
def _execute(self, context):
core.set_ifc_grid_north()
class SetBlenderGridNorth(bpy.types.Operator, tool.Ifc.Operator): def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context):
self.file = IfcStore.get_file()
props = context.scene.BIMGeoreferenceProperties
projected_crs = blenderbim.bim.helper.export_attributes(props.projected_crs, self.export_crs_attributes)
map_conversion = blenderbim.bim.helper.export_attributes(props.map_conversion, self.export_map_attributes)
true_north = None
if props.has_true_north:
try:
true_north = [float(props.true_north_abscissa), float(props.true_north_ordinate)]
except ValueError:
self.report({"ERROR"}, "True North Abscissa and Ordinate expect a number")
ifcopenshell.api.run(
"georeference.edit_georeferencing",
self.file,
**{
"map_conversion": map_conversion,
"projected_crs": projected_crs,
"true_north": true_north,
}
)
Data.load(self.file)
bpy.ops.bim.disable_editing_georeferencing()
return {"FINISHED"}
def export_map_attributes(self, attributes, prop):
if not prop.is_null and prop.data_type == "string":
# We store our floats as string to prevent single precision data loss
attributes[prop.name] = float(prop.string_value)
return True
def export_crs_attributes(self, attributes, prop):
if not prop.is_null and prop.name == "MapUnit":
attributes[prop.name] = self.file.by_id(int(prop.enum_value))
return True
class SetBlenderGridNorth(bpy.types.Operator):
bl_idname = "bim.set_blender_grid_north" bl_idname = "bim.set_blender_grid_north"
bl_label = "Set Blender Grid North" bl_label = "Set Blender Grid North"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
bl_description = "Set Blender grif north"
def execute(self, context):
context.scene.sun_pos_properties.north_offset = -radians(
ifcopenshell.util.geolocation.xaxis2angle(
float(context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisAbscissa").string_value),
float(context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisOrdinate").string_value),
)
)
return {"FINISHED"}
class SetIfcGridNorth(bpy.types.Operator):
bl_idname = "bim.set_ifc_grid_north"
bl_label = "Set IFC Grid North"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
x_angle = -context.scene.sun_pos_properties.north_offset
context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisAbscissa").string_value = str(cos(x_angle))
context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisOrdinate").string_value = str(sin(x_angle))
return {"FINISHED"}
class SetBlenderTrueNorth(bpy.types.Operator):
bl_idname = "bim.set_blender_true_north"
bl_label = "Set Blender True North"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
context.scene.sun_pos_properties.north_offset = -radians(
ifcopenshell.util.geolocation.yaxis2angle(
float(context.scene.BIMGeoreferenceProperties.true_north_abscissa),
float(context.scene.BIMGeoreferenceProperties.true_north_ordinate),
)
)
return {"FINISHED"}
class SetIfcTrueNorth(bpy.types.Operator):
bl_idname = "bim.set_ifc_true_north"
bl_label = "Set IFC True North"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
y_angle = -context.scene.sun_pos_properties.north_offset + radians(90)
context.scene.BIMGeoreferenceProperties.true_north_abscissa = str(cos(y_angle))
context.scene.BIMGeoreferenceProperties.true_north_ordinate = str(sin(y_angle))
return {"FINISHED"}
class RemoveGeoreferencing(bpy.types.Operator):
bl_idname = "bim.remove_georeferencing"
bl_label = "Remove Georeferencing"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
core.set_blender_grid_north() ifcopenshell.api.run("georeference.remove_georeferencing", IfcStore.get_file())
Data.load(IfcStore.get_file())
return {"FINISHED"}
class AddGeoreferencing(bpy.types.Operator):
bl_idname = "bim.add_georeferencing"
bl_label = "Add Georeferencing"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context):
ifcopenshell.api.run("georeference.add_georeferencing", IfcStore.get_file())
Data.load(IfcStore.get_file())
return {"FINISHED"}
class ConvertLocalToGlobal(bpy.types.Operator):
bl_idname = "bim.convert_local_to_global"
bl_label = "Convert Local To Global"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
file = IfcStore.get_file()
props = context.scene.BIMGeoreferenceProperties
return file and props.coordinate_input.count(",") == 2
def execute(self, context):
if not Data.is_loaded:
Data.load(IfcStore.get_file())
props = context.scene.BIMGeoreferenceProperties
x, y, z = [float(co) for co in props.coordinate_input.split(",")]
if props.has_blender_offset:
results = ifcopenshell.util.geolocation.xyz2enh(
x,
y,
z,
float(props.blender_eastings),
float(props.blender_northings),
float(props.blender_orthogonal_height),
float(props.blender_x_axis_abscissa),
float(props.blender_x_axis_ordinate),
1.0,
)
x, y, z = results
# TODO: what if the project CRS units and the project units are different?
if Data.map_conversion:
results = ifcopenshell.util.geolocation.xyz2enh(
x,
y,
z,
Data.map_conversion["Eastings"],
Data.map_conversion["Northings"],
Data.map_conversion["OrthogonalHeight"],
Data.map_conversion.get("XAxisAbscissa", 1.0),
Data.map_conversion.get("XAxisOrdinate", 0.0),
Data.map_conversion.get("Scale", 1.0),
)
else:
results = (x, y, z)
props.coordinate_output = ",".join([str(r) for r in results])
context.scene.cursor.location = results
return {"FINISHED"}
class ConvertGlobalToLocal(bpy.types.Operator):
bl_idname = "bim.convert_global_to_local"
bl_label = "Convert Global To Local"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
file = IfcStore.get_file()
props = context.scene.BIMGeoreferenceProperties
return file and file.by_type("IfcUnitAssignment") and props.coordinate_input.count(",") == 2
def execute(self, context):
if not Data.is_loaded:
Data.load(IfcStore.get_file())
props = context.scene.BIMGeoreferenceProperties
x, y, z = [float(co) for co in props.coordinate_input.split(",")]
if Data.map_conversion:
results = ifcopenshell.util.geolocation.enh2xyz(
x,
y,
z,
Data.map_conversion["Eastings"],
Data.map_conversion["Northings"],
Data.map_conversion["OrthogonalHeight"],
Data.map_conversion.get("XAxisAbscissa", 1.0),
Data.map_conversion.get("XAxisOrdinate", 0.0),
Data.map_conversion.get("Scale", 1.0),
)
else:
results = (x, y, z)
if props.has_blender_offset:
results = ifcopenshell.util.geolocation.enh2xyz(
results[0],
results[1],
results[2],
float(props.blender_eastings),
float(props.blender_northings),
float(props.blender_orthogonal_height),
float(props.blender_x_axis_abscissa),
float(props.blender_x_axis_ordinate),
1.0,
)
props.coordinate_output = ",".join([str(r) for r in results])
scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file())
context.scene.cursor.location = [o * scale for o in results]
return {"FINISHED"}
class GetCursorLocation(bpy.types.Operator):
bl_idname = "bim.get_cursor_location"
bl_label = "Get Cursor Location"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
file = IfcStore.get_file()
return file and file.by_type("IfcUnitAssignment")
def execute(self, context):
props = context.scene.BIMGeoreferenceProperties
scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file())
project_coordinates = [o / scale for o in context.scene.cursor.location]
props.coordinate_input = ",".join([str(o) for o in project_coordinates])
return {"FINISHED"}
class SetCursorLocation(bpy.types.Operator):
bl_idname = "bim.set_cursor_location"
bl_label = "Set Cursor Location"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
file = IfcStore.get_file()
props = context.scene.BIMGeoreferenceProperties
return file and file.by_type("IfcUnitAssignment") and props.coordinate_output.count(",") == 2
def execute(self, context):
props = context.scene.BIMGeoreferenceProperties
scale = ifcopenshell.util.unit.calculate_unit_scale(IfcStore.get_file())
context.scene.cursor.location = [float(co) * scale for co in props.coordinate_output.split(",")]
return {"FINISHED"}
@@ -18,10 +18,10 @@
import ifcopenshell.util.geolocation import ifcopenshell.util.geolocation
from bpy.types import Panel from bpy.types import Panel
#from ifcopenshell.api.georeference.data import Data from ifcopenshell.api.georeference.data import Data
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.helper import draw_attributes, draw_attribute from blenderbim.bim.helper import draw_attributes, draw_attribute
from blenderbim.bim.module.georeference.data import GeoreferenceData
class BIM_PT_gis(Panel): class BIM_PT_gis(Panel):
bl_label = "IFC Georeferencing" bl_label = "IFC Georeferencing"
@@ -31,15 +31,18 @@ class BIM_PT_gis(Panel):
bl_region_type = "WINDOW" bl_region_type = "WINDOW"
bl_context = "scene" bl_context = "scene"
bl_parent_id = "BIM_PT_geometry" bl_parent_id = "BIM_PT_geometry"
@classmethod
def poll(cls, context):
return IfcStore.get_file()
def draw(self, context): def draw(self, context):
self.layout.use_property_split = True self.layout.use_property_split = True
self.layout.use_property_decorate = False self.layout.use_property_decorate = False
props = context.scene.BIMGeoreferenceProperties props = context.scene.BIMGeoreferenceProperties
if not Data.is_loaded:
if not GeoreferenceData.is_loaded: Data.load(IfcStore.get_file())
GeoreferenceData.load()
if props.is_editing: if props.is_editing:
return self.draw_editable_ui(context) return self.draw_editable_ui(context)
self.draw_ui(context) self.draw_ui(context)
@@ -73,19 +76,18 @@ class BIM_PT_gis(Panel):
row.prop(props, "true_north_ordinate") row.prop(props, "true_north_ordinate")
if hasattr(context.scene, "sun_pos_properties"): if hasattr(context.scene, "sun_pos_properties"):
row = self.layout.row(align=True) row = self.layout.row(align=True)
# row.operator("bim.set_ifc_true_north", text="Set IFC North") row.operator("bim.set_ifc_true_north", text="Set IFC North")
# row.operator("bim.set_blender_true_north", text="Set Blender North") row.operator("bim.set_blender_true_north", text="Set Blender North")
def draw_ui(self, context): def draw_ui(self, context):
props = context.scene.BIMGeoreferenceProperties props = context.scene.BIMGeoreferenceProperties
if not GeoreferenceData.data["projected_crs"]: if not Data.projected_crs:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="Not Georeferenced") row.label(text="Not Georeferenced")
if IfcStore.get_file().schema != "IFC2X3": if IfcStore.get_file().schema != "IFC2X3":
row.operator("bim.add_georeferencing", icon="ADD", text="") row.operator("bim.add_georeferencing", icon="ADD", text="")
if props.has_blender_offset: if props.has_blender_offset:
row = self.layout.row() row = self.layout.row()
row.label(text="Blender Offset", icon="TRACKING_REFINE_FORWARDS") row.label(text="Blender Offset", icon="TRACKING_REFINE_FORWARDS")
@@ -118,13 +120,13 @@ class BIM_PT_gis(Panel):
) )
) )
if GeoreferenceData.data["projected_crs"]: if Data.projected_crs:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="Projected CRS", icon="WORLD") row.label(text="Projected CRS", icon="WORLD")
row.operator("bim.enable_editing_georeferencing", icon="GREASEPENCIL", text="") row.operator("bim.enable_editing_georeferencing", icon="GREASEPENCIL", text="")
row.operator("bim.remove_georeferencing", icon="X", text="") row.operator("bim.remove_georeferencing", icon="X", text="")
for key, value in GeoreferenceData.data["projected_crs"].items(): for key, value in Data.projected_crs.items():
if key == "id" or key == "type" or not value: if key == "id" or key == "type" or not value:
continue continue
if key == "MapUnit": if key == "MapUnit":
@@ -135,11 +137,11 @@ class BIM_PT_gis(Panel):
row.label(text=key) row.label(text=key)
row.label(text=str(value)) row.label(text=str(value))
if GeoreferenceData.data["map_conversion"]: if Data.map_conversion:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="Map Conversion", icon="GRID") row.label(text="Map Conversion", icon="GRID")
for key, value in GeoreferenceData.data["map_conversion"].items(): for key, value in Data.map_conversion.items():
if key == "id" or key == "type" or key == "SourceCRS" or key == "TargetCRS" or value is None: if key == "id" or key == "type" or key == "SourceCRS" or key == "TargetCRS" or value is None:
continue continue
row = self.layout.row(align=True) row = self.layout.row(align=True)
@@ -152,22 +154,22 @@ class BIM_PT_gis(Panel):
text=str( text=str(
round( round(
ifcopenshell.util.geolocation.xaxis2angle( ifcopenshell.util.geolocation.xaxis2angle(
GeoreferenceData.data["map_conversion"]["XAxisAbscissa"], GeoreferenceData.data["map_conversion"]["XAxisOrdinate"] Data.map_conversion["XAxisAbscissa"], Data.map_conversion["XAxisOrdinate"]
), ),
3, 3,
) )
) )
) )
if GeoreferenceData.data["true_north"]: if Data.true_north:
row = self.layout.row() row = self.layout.row()
row.label(text="True North", icon="LIGHT_SUN") row.label(text="True North", icon="LIGHT_SUN")
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="Vector") row.label(text="Vector")
row.label(text=str(GeoreferenceData.data["true_north"][0:2])[1:-1]) row.label(text=str(Data.true_north[0:2])[1:-1])
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="Derived Angle") row.label(text="Derived Angle")
row.label(text=str(round(ifcopenshell.util.geolocation.yaxis2angle(*GeoreferenceData.data["true_north"][0:2]), 3))) row.label(text=str(round(ifcopenshell.util.geolocation.yaxis2angle(*Data.true_north[0:2]), 3)))
class BIM_PT_gis_utilities(Panel): class BIM_PT_gis_utilities(Panel):
@@ -183,12 +185,11 @@ class BIM_PT_gis_utilities(Panel):
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.prop(props, "coordinate_input", text="Input") row.prop(props, "coordinate_input", text="Input")
#row.operator("bim.get_cursor_location", text="", icon="TRACKER") row.operator("bim.get_cursor_location", text="", icon="TRACKER")
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.prop(props, "coordinate_output", text="Output") row.prop(props, "coordinate_output", text="Output")
#row.operator("bim.set_cursor_location", text="", icon="TRACKER") row.operator("bim.set_cursor_location", text="", icon="TRACKER")
row = self.layout.row(align=True) row = self.layout.row(align=True)
#row.operator("bim.convert_local_to_global", text="Local to Global") row.operator("bim.convert_local_to_global", text="Local to Global")
#row.operator("bim.convert_global_to_local", text="Global to Local") row.operator("bim.convert_global_to_local", text="Global to Local")
-13
View File
@@ -246,19 +246,6 @@ class Geometry:
def should_generate_uvs(cls, obj): pass def should_generate_uvs(cls, obj): pass
def should_use_presentation_style_assignment(cls): pass def should_use_presentation_style_assignment(cls): pass
@interface
class Georeference:
def clear_projected_crs(cls): pass
def clear_map_conversion(cls): pass
def get_file(cls): pass
def set_false_is_editing(cls): pass
def import_projected_crs_attributes(cls, name, prop, data): pass
def import_map_conversion_attributes(cls, name, prop, data): pass
def export_crs_attributes(cls, attributes, prop): pass
def export_map_attributes(cls, attributes, prop): pass
def set_ifc_grid_north(cls): pass
def set_blender_grid_north(cls): pass
@interface @interface
class Ifc: class Ifc:
@@ -27,7 +27,6 @@ from blenderbim.tool.demo import Demo
from blenderbim.tool.document import Document from blenderbim.tool.document import Document
from blenderbim.tool.drawing import Drawing from blenderbim.tool.drawing import Drawing
from blenderbim.tool.geometry import Geometry from blenderbim.tool.geometry import Geometry
from blenderbim.tool.georeference import Georeference
from blenderbim.tool.ifc import Ifc from blenderbim.tool.ifc import Ifc
from blenderbim.tool.library import Library from blenderbim.tool.library import Library
from blenderbim.tool.material import Material from blenderbim.tool.material import Material