mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 02:23:34 +00:00
Bonsai - support editing IfcPresentationLayerWithStyle attributes
Example - https://imgur.com/a/JRs8RZm
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user