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]]: def get_subcontexts(cls, context: ifcopenshell.entity_instance) -> list[dict[str, Any]]:
results = [] results = []
for subcontext in context.HasSubContexts: 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( results.append(
{ {
"id": subcontext.id(), "id": subcontext.id(),
"context_type": subcontext.ContextType, "context_type": subcontext.ContextType,
"context_identifier": subcontext.ContextIdentifier, "context_identifier": subcontext.ContextIdentifier,
"target_view": subcontext.TargetView, "target_view": subcontext.TargetView,
"target_scale_denominator": target_scale_denominator,
} }
) )
return results return results
@@ -84,5 +84,26 @@ class BIM_PT_context(bpy.types.Panel):
row.label(text=subcontext["context_type"]) row.label(text=subcontext["context_type"])
row.label(text=subcontext["context_identifier"]) row.label(text=subcontext["context_identifier"])
row.label(text=subcontext["target_view"]) 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.enable_editing_context", icon="GREASEPENCIL", text="").context = subcontext["id"]
row.operator("bim.remove_context", icon="X", 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_type: Optional[str] = None,
context_identifier: Optional[str] = None, context_identifier: Optional[str] = None,
target_view: Optional[str] = None, target_view: Optional[str] = None,
target_scale: Optional[float] = None,
parent: Optional[str] = None, parent: Optional[str] = None,
) -> ifcopenshell.entity_instance: ) -> ifcopenshell.entity_instance:
return ifc.run( return ifc.run(
@@ -37,6 +38,7 @@ def add_context(
context_type=context_type, context_type=context_type,
context_identifier=context_identifier, context_identifier=context_identifier,
target_view=target_view, target_view=target_view,
target_scale=target_scale,
parent=parent, parent=parent,
) )
+18
View File
@@ -54,6 +54,17 @@ class Context(bonsai.core.tool.Context):
elif name == "CoordinateSpaceDimension": elif name == "CoordinateSpaceDimension":
props.context_attributes.remove(props.context_attributes.find("CoordinateSpaceDimension")) props.context_attributes.remove(props.context_attributes.find("CoordinateSpaceDimension"))
return True 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 else: # IfcGeometricRepresentationContext
# Import precision as a string because Blender has problem displaying 1e-7 and smaller numbers in UI. # Import precision as a string because Blender has problem displaying 1e-7 and smaller numbers in UI.
if name == "Precision": if name == "Precision":
@@ -79,6 +90,13 @@ class Context(bonsai.core.tool.Context):
if blender_attribute.name == "Precision": if blender_attribute.name == "Precision":
attributes["Precision"] = float(blender_attribute.get_value()) attributes["Precision"] = float(blender_attribute.get_value())
return True 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 False
return bonsai.bim.helper.export_attributes(props.context_attributes, callback=callback) 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.set_context(subcontext)
subject.import_attributes() subject.import_attributes()
props = subject.get_context_props() 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["TargetView"].enum_value == "NOTDEFINED"
assert props.context_attributes["UserDefinedTargetView"].string_value == "UserDefinedTargetView" assert props.context_attributes["UserDefinedTargetView"].string_value == "UserDefinedTargetView"
assert "Precision" not in props.context_attributes assert "Precision" not in props.context_attributes
@@ -26,6 +26,7 @@ def add_context(
context_type: Optional[ifcopenshell.util.representation.CONTEXT_TYPE] = None, context_type: Optional[ifcopenshell.util.representation.CONTEXT_TYPE] = None,
context_identifier: Optional[ifcopenshell.util.representation.REPRESENTATION_IDENTIFIER] = None, context_identifier: Optional[ifcopenshell.util.representation.REPRESENTATION_IDENTIFIER] = None,
target_view: Optional[ifcopenshell.util.representation.TARGET_VIEW] = None, target_view: Optional[ifcopenshell.util.representation.TARGET_VIEW] = None,
target_scale: Optional[float] = None,
parent: Optional[ifcopenshell.entity_instance] = None, parent: Optional[ifcopenshell.entity_instance] = None,
) -> ifcopenshell.entity_instance: ) -> ifcopenshell.entity_instance:
"""Adds a new geometric representation context """Adds a new geometric representation context
@@ -107,6 +108,9 @@ def add_context(
the common target views above or consult the IFC documentation the common target views above or consult the IFC documentation
(under the IfcShapeRepresentation page) for more details. Optional (under the IfcShapeRepresentation page) for more details. Optional
for contexts, but mandatory for subcontexts. 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) :param parent: the parent context. Must be left as None (the default)
for contexts, and only set for subcontexts. Note that there are only for contexts, and only set for subcontexts. Note that there are only
contexts and subcontexts, a subcontext cannot have any children. contexts and subcontexts, a subcontext cannot have any children.
@@ -186,6 +190,7 @@ def add_context(
"parent": parent, "parent": parent,
"context_identifier": context_identifier, "context_identifier": context_identifier,
"target_view": target_view, "target_view": target_view,
"target_scale": target_scale,
} }
return usecase.execute() return usecase.execute()
@@ -221,6 +226,7 @@ class Usecase:
"ContextType": self.settings["context_type"], "ContextType": self.settings["context_type"],
"ParentContext": self.settings["parent"], "ParentContext": self.settings["parent"],
"TargetView": self.settings["target_view"], "TargetView": self.settings["target_view"],
"TargetScale": self.settings["target_scale"],
} }
) )