mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Display project units instead of hardcoded ones (#1699)
* Display project units instead of hardcoded ones * Treat MapUnit as a regular attribute * Remove left over attributes * Refactor operator for MapUnit change * Fix unit fetch failing because of wrong id type
This commit is contained in:
@@ -26,6 +26,7 @@ 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
|
||||
|
||||
|
||||
@@ -37,36 +38,15 @@ class EnableEditingGeoreferencing(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
props = context.scene.BIMGeoreferenceProperties
|
||||
self.props = props
|
||||
|
||||
props.projected_crs.clear()
|
||||
|
||||
for attribute in IfcStore.get_schema().declaration_by_name("IfcProjectedCRS").all_attributes():
|
||||
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
|
||||
if data_type == "entity":
|
||||
continue
|
||||
new = props.projected_crs.add()
|
||||
new.name = attribute.name()
|
||||
new.is_null = Data.projected_crs[attribute.name()] is None
|
||||
new.is_optional = attribute.optional()
|
||||
new.data_type = data_type
|
||||
if data_type == "string":
|
||||
new.string_value = "" if new.is_null else Data.projected_crs[attribute.name()]
|
||||
elif data_type == "float":
|
||||
new.float_value = 0.0 if new.is_null else Data.projected_crs[attribute.name()]
|
||||
elif data_type == "integer":
|
||||
new.int_value = 0 if new.is_null else Data.projected_crs[attribute.name()]
|
||||
elif data_type == "boolean":
|
||||
new.bool_value = False if new.is_null else Data.projected_crs[attribute.name()]
|
||||
|
||||
props.is_map_unit_null = Data.projected_crs["MapUnit"] is None
|
||||
if not props.is_map_unit_null:
|
||||
props.map_unit_type = Data.projected_crs["MapUnit"]["type"]
|
||||
if props.map_unit_type == "IfcSIUnit":
|
||||
prefix = ifcopenshell.util.unit.get_prefix(Data.projected_crs["MapUnit"]["Prefix"]) or ""
|
||||
name = ifcopenshell.util.unit.get_unit_name(Data.projected_crs["MapUnit"]["Name"])
|
||||
props.map_unit_si = prefix + name
|
||||
elif props.map_unit_type == "IfcConversionBasedUnit":
|
||||
props.map_unit_imperial = Data.projected_crs["MapUnit"]["Name"]
|
||||
blenderbim.bim.helper.import_attributes(
|
||||
"IfcProjectedCRS",
|
||||
props.projected_crs,
|
||||
Data.projected_crs,
|
||||
self.import_projected_crs_attributes)
|
||||
|
||||
props.map_conversion.clear()
|
||||
blenderbim.bim.helper.import_attributes(
|
||||
@@ -81,6 +61,20 @@ class EnableEditingGeoreferencing(bpy.types.Operator):
|
||||
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"
|
||||
})
|
||||
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
|
||||
@@ -88,6 +82,7 @@ class EnableEditingGeoreferencing(bpy.types.Operator):
|
||||
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_label = "Disable Editing Georeferencing"
|
||||
@@ -111,20 +106,15 @@ class EditGeoreferencing(bpy.types.Operator):
|
||||
self.file = IfcStore.get_file()
|
||||
props = context.scene.BIMGeoreferenceProperties
|
||||
|
||||
projected_crs = blenderbim.bim.helper.export_attributes(props.projected_crs)
|
||||
|
||||
map_unit = ""
|
||||
if not props.is_map_unit_null:
|
||||
map_unit = props.map_unit_si if props.map_unit_type == "IfcSIUnit" else props.map_unit_imperial
|
||||
|
||||
map_conversion = blenderbim.bim.helper.export_attributes(props.map_conversion, self.export_attributes)
|
||||
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:
|
||||
pass
|
||||
except ValueError:
|
||||
self.report({"ERROR"}, "True North Abscissa and Ordinate expect a number")
|
||||
|
||||
ifcopenshell.api.run(
|
||||
"georeference.edit_georeferencing",
|
||||
@@ -132,20 +122,24 @@ class EditGeoreferencing(bpy.types.Operator):
|
||||
**{
|
||||
"map_conversion": map_conversion,
|
||||
"projected_crs": projected_crs,
|
||||
"map_unit": map_unit,
|
||||
"true_north": true_north,
|
||||
}
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
Data.load(self.file)
|
||||
bpy.ops.bim.disable_editing_georeferencing()
|
||||
return {"FINISHED"}
|
||||
|
||||
def export_attributes(self, attributes, prop):
|
||||
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"
|
||||
|
||||
@@ -36,22 +36,6 @@ class BIMGeoreferenceProperties(PropertyGroup):
|
||||
is_editing: BoolProperty(name="Is Editing")
|
||||
map_conversion: CollectionProperty(name="Map Conversion", type=Attribute)
|
||||
projected_crs: CollectionProperty(name="Projected CRS", type=Attribute)
|
||||
map_unit_type: EnumProperty(
|
||||
items=[(n, n, "") for n in ["IfcSIUnit", "IfcConversionBasedUnit"]],
|
||||
name="Map Unit Type",
|
||||
default="IfcSIUnit",
|
||||
)
|
||||
map_unit_si: EnumProperty(
|
||||
items=[(n, n.lower().capitalize(), "") for n in ["MILLIMETRE", "CENTIMETRE", "METRE", "KILOMETRE"]],
|
||||
name="Map Unit SI",
|
||||
default="METRE",
|
||||
)
|
||||
map_unit_imperial: EnumProperty(
|
||||
items=[(n, n.lower().capitalize(), "") for n in ["inch", "foot", "yard", "mile"]],
|
||||
name="Map Unit SI",
|
||||
default="foot",
|
||||
)
|
||||
is_map_unit_null: BoolProperty(name="Is Map Unit Null")
|
||||
coordinate_input: StringProperty(name="Coordinate Input", description="Formatted \"x,y,z\" (without quotes)")
|
||||
coordinate_output: StringProperty(name="Coordinate Output", description="Formatted \"x,y,z\" (without quotes)")
|
||||
has_blender_offset: BoolProperty(name="Has Blender Offset")
|
||||
|
||||
@@ -56,14 +56,6 @@ class BIM_PT_gis(Panel):
|
||||
|
||||
draw_attributes(props.projected_crs, self.layout)
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "map_unit_type", text="MapUnit")
|
||||
if props.map_unit_type == "IfcSIUnit":
|
||||
row.prop(props, "map_unit_si", text="")
|
||||
elif props.map_unit_type == "IfcConversionBasedUnit":
|
||||
row.prop(props, "map_unit_imperial", text="")
|
||||
row.prop(props, "is_map_unit_null", icon="RADIOBUT_OFF" if props.is_map_unit_null else "RADIOBUT_ON", text="")
|
||||
|
||||
row = self.layout.row()
|
||||
row.label(text="Map Conversion", icon="GRID")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user