Bonsai - support editing IfcPresentationLayerWithStyle attributes

Example - https://imgur.com/a/JRs8RZm
This commit is contained in:
Andrej730
2025-01-24 16:31:55 +05:00
parent e3ea12a517
commit d21c24b070
4 changed files with 50 additions and 20 deletions
+14 -16
View File
@@ -35,22 +35,20 @@ class LayersData:
cls.is_loaded = True
@classmethod
def total_layers(cls):
def total_layers(cls) -> int:
return len(tool.Ifc.get().by_type("IfcPresentationLayerAssignment"))
@classmethod
def active_layers(cls):
if not bpy.context.active_object:
return []
data = bpy.context.active_object.data
if not data:
return []
if not isinstance(data, bpy.types.Mesh) or not data.BIMMeshProperties.ifc_definition_id:
return []
results = dict()
shape = tool.Ifc.get().by_id(data.BIMMeshProperties.ifc_definition_id)
for inverse in getattr(shape, "LayerAssignments", []):
results[inverse.id()] = inverse.Name or "Unnamed"
for inverse in getattr(shape, "LayerAssignment", []):
results[inverse.id()] = inverse.Name or "Unnamed"
return results
def active_layers(cls) -> dict[int, str]:
results = {}
if not (obj := bpy.context.active_object) or not (shape := tool.Geometry.get_active_representation(obj)):
return results
attr_name = None
if shape.is_a("IfcShapeModel"):
attr_name = "LayerAssignments"
elif shape.is_a("IfcRepresentationItem"):
attr_name = "LayerAssignment"
if attr_name is None:
return results
return {layer.id(): layer.Name for layer in getattr(shape, attr_name)}
@@ -19,6 +19,7 @@
import bpy
import json
import ifcopenshell.api
import ifcopenshell.api.layer
import ifcopenshell.util.element
import ifcopenshell.util.attribute
import bonsai.bim.helper
@@ -37,8 +38,15 @@ class LoadLayers(bpy.types.Operator):
props.layers.clear()
for layer in tool.Ifc.get().by_type("IfcPresentationLayerAssignment"):
new = props.layers.add()
new.name = layer.Name or "Unnamed"
new.name = layer.Name
new.ifc_definition_id = layer.id()
if layer.is_a("IfcPresentationLayerWithStyle"):
new.with_style = True
# IfcLogical can also be UNKNOWN, not just bool.
ifc_logical_is_true = lambda x: x is True
new["on"] = ifc_logical_is_true(layer.LayerOn)
new["frozen"] = ifc_logical_is_true(layer.LayerFrozen)
new["blocked"] = ifc_logical_is_true(layer.LayerBlocked)
props.is_editing = True
bpy.ops.bim.disable_editing_layer()
return {"FINISHED"}
@@ -17,6 +17,7 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
import bonsai.tool as tool
from bonsai.bim.prop import StrProperty, Attribute
from bpy.types import PropertyGroup
from bpy.props import (
@@ -31,9 +32,31 @@ from bpy.props import (
)
def update_layer_property(self: "Layer", context: bpy.types.Context, *, property: str) -> None:
# TODO: make use of those attributes in Bonsai somehow?
layer = tool.Ifc.get().by_id(self.ifc_definition_id)
setattr(layer, f"Layer{property.capitalize()}", getattr(self, property))
class Layer(PropertyGroup):
name: StringProperty(name="Name")
ifc_definition_id: IntProperty(name="IFC Definition ID")
with_style: BoolProperty(description="Whether it's IfcPresentationLayerWithStyle.", default=False)
on: BoolProperty(
name="Layer Visibility",
description="Currently has no effect in Bonsai.",
update=lambda self, context: update_layer_property(self, context, property="on"),
)
frozen: BoolProperty(
name="Layer Frozen",
description="Currently has no effect in Bonsai.",
update=lambda self, context: update_layer_property(self, context, property="frozen"),
)
blocked: BoolProperty(
name="Layer Blocked",
description="Currently has not effect in Bonsai",
update=lambda self, context: update_layer_property(self, context, property="blocked"),
)
class BIMLayerProperties(PropertyGroup):
+4 -3
View File
@@ -85,9 +85,10 @@ class BIM_UL_layers(UIList):
op = row.operator("bim.assign_presentation_layer", text="", icon="KEYFRAME", emboss=False)
op.layer = item.ifc_definition_id
# TODO: replace placeholder UI for hiding presentation layers
row.operator("bim.disable_editing_layer", text="", icon="HIDE_OFF", emboss=False)
row.operator("bim.disable_editing_layer", text="", icon="FREEZE", emboss=False)
if item.with_style:
row.prop(item, "on", text="", icon="HIDE_OFF" if item.on else "HIDE_ON", emboss=False)
row.prop(item, "frozen", text="", icon="FREEZE" if item.frozen else "MESH_PLANE", emboss=False)
row.prop(item, "blocked", text="", icon="LOCKED" if item.blocked else "UNLOCKED", emboss=False)
if context.scene.BIMLayerProperties.active_layer_id == item.ifc_definition_id:
op = row.operator("bim.select_layer_products", text="", icon="RESTRICT_SELECT_OFF")