mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 17:57:02 +00:00
Fix bug where Blender floats lost precision for geolocation. Everything is now a string.
This commit is contained in:
@@ -53,21 +53,16 @@ class EnableEditingGeoreferencing(bpy.types.Operator):
|
|||||||
|
|
||||||
for attribute in IfcStore.get_schema().declaration_by_name("IfcMapConversion").all_attributes():
|
for attribute in IfcStore.get_schema().declaration_by_name("IfcMapConversion").all_attributes():
|
||||||
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
|
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
|
||||||
if data_type == "entity":
|
if data_type == "entity" or data_type == "select":
|
||||||
continue
|
continue
|
||||||
|
print(attribute.name(), data_type)
|
||||||
new = props.map_conversion.add()
|
new = props.map_conversion.add()
|
||||||
new.name = attribute.name()
|
new.name = attribute.name()
|
||||||
new.is_null = Data.map_conversion[attribute.name()] is None
|
new.is_null = Data.map_conversion[attribute.name()] is None
|
||||||
new.is_optional = attribute.optional()
|
new.is_optional = attribute.optional()
|
||||||
new.data_type = data_type
|
# Enforce a string data type to prevent data loss in singpe-precision Blender props
|
||||||
if data_type == "string":
|
new.data_type = "string"
|
||||||
new.string_value = "" if new.is_null else Data.map_conversion[attribute.name()]
|
new.string_value = "" if new.is_null else str(Data.map_conversion[attribute.name()])
|
||||||
elif data_type == "float":
|
|
||||||
new.float_value = 0.0 if new.is_null else Data.map_conversion[attribute.name()]
|
|
||||||
elif data_type == "integer":
|
|
||||||
new.int_value = 0 if new.is_null else Data.map_conversion[attribute.name()]
|
|
||||||
elif data_type == "boolean":
|
|
||||||
new.bool_value = False if new.is_null else Data.map_conversion[attribute.name()]
|
|
||||||
|
|
||||||
props.has_true_north = bool(Data.true_north)
|
props.has_true_north = bool(Data.true_north)
|
||||||
if Data.true_north:
|
if Data.true_north:
|
||||||
@@ -120,19 +115,14 @@ class EditGeoreferencing(bpy.types.Operator):
|
|||||||
map_conversion = {}
|
map_conversion = {}
|
||||||
for attribute in IfcStore.get_schema().declaration_by_name("IfcMapConversion").all_attributes():
|
for attribute in IfcStore.get_schema().declaration_by_name("IfcMapConversion").all_attributes():
|
||||||
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
|
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
|
||||||
if data_type == "entity":
|
if data_type == "entity" or data_type == "select":
|
||||||
continue
|
continue
|
||||||
blender_attribute = props.map_conversion.get(attribute.name())
|
blender_attribute = props.map_conversion.get(attribute.name())
|
||||||
if blender_attribute.is_null:
|
if blender_attribute.is_null:
|
||||||
map_conversion[attribute.name()] = None
|
map_conversion[attribute.name()] = None
|
||||||
elif blender_attribute.data_type == "string":
|
elif blender_attribute.data_type == "string":
|
||||||
map_conversion[attribute.name()] = blender_attribute.string_value
|
# We store our floats as string to prevent single precision data loss
|
||||||
elif blender_attribute.data_type == "float":
|
map_conversion[attribute.name()] = float(blender_attribute.string_value)
|
||||||
map_conversion[attribute.name()] = blender_attribute.float_value
|
|
||||||
elif blender_attribute.data_type == "integer":
|
|
||||||
map_conversion[attribute.name()] = blender_attribute.int_value
|
|
||||||
elif blender_attribute.data_type == "boolean":
|
|
||||||
map_conversion[attribute.name()] = blender_attribute.bool_value
|
|
||||||
|
|
||||||
true_north = None
|
true_north = None
|
||||||
if props.has_true_north:
|
if props.has_true_north:
|
||||||
@@ -163,8 +153,8 @@ class SetBlenderGridNorth(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
context.scene.sun_pos_properties.north_offset = -radians(
|
context.scene.sun_pos_properties.north_offset = -radians(
|
||||||
ifcopenshell.util.geolocation.xaxis2angle(
|
ifcopenshell.util.geolocation.xaxis2angle(
|
||||||
context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisAbscissa").float_value,
|
float(context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisAbscissa").string_value),
|
||||||
context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisOrdinate").float_value,
|
float(context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisOrdinate").string_value),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -176,8 +166,8 @@ class SetIfcGridNorth(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
x_angle = -context.scene.sun_pos_properties.north_offset
|
x_angle = -context.scene.sun_pos_properties.north_offset
|
||||||
context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisAbscissa").float_value = cos(x_angle)
|
context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisAbscissa").string_value = str(cos(x_angle))
|
||||||
context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisOrdinate").float_value = sin(x_angle)
|
context.scene.BIMGeoreferenceProperties.map_conversion.get("XAxisOrdinate").string_value = str(sin(x_angle))
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -138,27 +138,23 @@ class BIM_PT_gis(Panel):
|
|||||||
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 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":
|
||||||
unit_value = value.get("Prefix", "") or ""
|
unit_value = value.get("Prefix", "") or ""
|
||||||
unit_value += value["Name"]
|
unit_value += value["Name"]
|
||||||
value = unit_value
|
value = unit_value
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.label(text=key)
|
row.label(text=key)
|
||||||
row.label(text=str(value))
|
row.label(text=str(value))
|
||||||
|
|
||||||
if not Data.projected_crs["Name"]:
|
|
||||||
row = self.layout.row(align=True)
|
|
||||||
row.label(text="Undefined CRS")
|
|
||||||
|
|
||||||
if 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 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 not value:
|
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)
|
||||||
row.label(text=key)
|
row.label(text=key)
|
||||||
|
|||||||
Reference in New Issue
Block a user