Display TargetScale in Contexts UI / edit target scale denominator (#6816)

This commit is contained in:
falken10vdl
2025-06-27 07:48:14 +02:00
committed by GitHub
parent efb3b9d255
commit 2698ba69d5
6 changed files with 55 additions and 1 deletions
@@ -52,12 +52,19 @@ class ContextData:
def get_subcontexts(cls, context: ifcopenshell.entity_instance) -> list[dict[str, Any]]:
results = []
for subcontext in context.HasSubContexts:
target_scale_denominator = None
if subcontext.TargetScale is not None:
scale_value = float(subcontext.TargetScale)
if scale_value > 0:
target_scale_denominator = 1.0 / scale_value
results.append(
{
"id": subcontext.id(),
"context_type": subcontext.ContextType,
"context_identifier": subcontext.ContextIdentifier,
"target_view": subcontext.TargetView,
"target_scale_denominator": target_scale_denominator,
}
)
return results
@@ -84,5 +84,26 @@ class BIM_PT_context(bpy.types.Panel):
row.label(text=subcontext["context_type"])
row.label(text=subcontext["context_identifier"])
row.label(text=subcontext["target_view"])
scale_col = row.column()
scale_col.ui_units_x = 6
if subcontext["target_scale_denominator"] is not None:
scale_value = subcontext["target_scale_denominator"]
if scale_value == int(scale_value):
scale_str = str(int(scale_value))
if len(scale_str) > 4:
scale_str = f"{float(scale_value):.3g}"
else:
scale_str = f"{scale_value:.4g}"
if len(scale_str) > 4:
scale_str = f"{float(scale_value):.3g}"
scale_col.label(text=f"1:{scale_str}")
else:
scale_col.label(text="")
row.operator("bim.enable_editing_context", icon="GREASEPENCIL", text="").context = subcontext["id"]
row.operator("bim.remove_context", icon="X", text="").context = subcontext["id"]
+2
View File
@@ -30,6 +30,7 @@ def add_context(
context_type: Optional[str] = None,
context_identifier: Optional[str] = None,
target_view: Optional[str] = None,
target_scale: Optional[float] = None,
parent: Optional[str] = None,
) -> ifcopenshell.entity_instance:
return ifc.run(
@@ -37,6 +38,7 @@ def add_context(
context_type=context_type,
context_identifier=context_identifier,
target_view=target_view,
target_scale=target_scale,
parent=parent,
)
+18
View File
@@ -54,6 +54,17 @@ class Context(bonsai.core.tool.Context):
elif name == "CoordinateSpaceDimension":
props.context_attributes.remove(props.context_attributes.find("CoordinateSpaceDimension"))
return True
elif name == "TargetScale":
props.context_attributes.remove(props.context_attributes.find("TargetScale"))
scale_denominator = None
if data.get(name) is not None and data.get(name) != 0:
scale_denominator = 1.0 / data.get(name)
new_prop = props.context_attributes.add()
new_prop.name = "ScaleDenominator"
new_prop.data_type = "float"
if scale_denominator is not None:
new_prop.float_value = scale_denominator
return True
else: # IfcGeometricRepresentationContext
# Import precision as a string because Blender has problem displaying 1e-7 and smaller numbers in UI.
if name == "Precision":
@@ -79,6 +90,13 @@ class Context(bonsai.core.tool.Context):
if blender_attribute.name == "Precision":
attributes["Precision"] = float(blender_attribute.get_value())
return True
elif blender_attribute.name == "ScaleDenominator":
scale_denominator = blender_attribute.get_value()
if scale_denominator is not None and scale_denominator != 0:
attributes["TargetScale"] = 1.0 / scale_denominator
else:
attributes["TargetScale"] = None
return True
return False
return bonsai.bim.helper.export_attributes(props.context_attributes, callback=callback)
+1 -1
View File
@@ -65,7 +65,7 @@ class TestImportAttributes(test.bim.bootstrap.NewFile):
subject.set_context(subcontext)
subject.import_attributes()
props = subject.get_context_props()
assert props.context_attributes["TargetScale"].float_value == 0.5
assert props.context_attributes["ScaleDenominator"].float_value == 2.0 # ScaleDenominator = 1.0 / TargetScale
assert props.context_attributes["TargetView"].enum_value == "NOTDEFINED"
assert props.context_attributes["UserDefinedTargetView"].string_value == "UserDefinedTargetView"
assert "Precision" not in props.context_attributes
@@ -26,6 +26,7 @@ def add_context(
context_type: Optional[ifcopenshell.util.representation.CONTEXT_TYPE] = None,
context_identifier: Optional[ifcopenshell.util.representation.REPRESENTATION_IDENTIFIER] = None,
target_view: Optional[ifcopenshell.util.representation.TARGET_VIEW] = None,
target_scale: Optional[float] = None,
parent: Optional[ifcopenshell.entity_instance] = None,
) -> ifcopenshell.entity_instance:
"""Adds a new geometric representation context
@@ -107,6 +108,9 @@ def add_context(
the common target views above or consult the IFC documentation
(under the IfcShapeRepresentation page) for more details. Optional
for contexts, but mandatory for subcontexts.
:param target_scale: It defines the intended scale at which the representation
is designed to be viewed or printed
:type target_scale: float, optional
:param parent: the parent context. Must be left as None (the default)
for contexts, and only set for subcontexts. Note that there are only
contexts and subcontexts, a subcontext cannot have any children.
@@ -186,6 +190,7 @@ def add_context(
"parent": parent,
"context_identifier": context_identifier,
"target_view": target_view,
"target_scale": target_scale,
}
return usecase.execute()
@@ -221,6 +226,7 @@ class Usecase:
"ContextType": self.settings["context_type"],
"ParentContext": self.settings["parent"],
"TargetView": self.settings["target_view"],
"TargetScale": self.settings["target_scale"],
}
)