Some UI to mark booleans as manual #3709

Currently it allows only to either set all object's booleans to be marked as manual or all of them marked as automatic, can't change some specific boolean.

Short demo - https://imgur.com/a/bczv35N
This commit is contained in:
Andrej730
2023-10-17 18:18:58 +05:00
parent 35d66f5d8c
commit 7ff98d2918
5 changed files with 82 additions and 25 deletions
@@ -25,6 +25,7 @@ classes = (
operator.RemoveFilling,
operator.RemoveOpening,
operator.SelectDecomposition,
operator.BooleansMarkAsManual,
prop.VoidProperties,
ui.BIM_PT_voids,
ui.BIM_PT_booleans,
@@ -67,32 +67,39 @@ class VoidsData:
return results
class BooleansData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"total_booleans": cls.total_booleans()}
cls.data = {}
cls.data["total_booleans"] = cls.booleans()
cls.data["manual_booleans"] = cls.manual_booleans()
cls.is_loaded = True
@classmethod
def total_booleans(cls):
def booleans(cls):
obj = bpy.context.active_object
if (
not obj.data
or not hasattr(obj.data, "BIMMeshProperties")
or not obj.data.BIMMeshProperties.ifc_definition_id
):
return 0
return []
representation = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
total_booleans = 0
for item in representation.Items:
while True:
if item.is_a("IfcBooleanResult"):
total_booleans += 1
item = item.FirstOperand
else:
break
return total_booleans
return tool.Model.get_booleans(representation=representation)
@classmethod
def manual_booleans(cls):
obj = bpy.context.active_object
if (
not obj.data
or not hasattr(obj.data, "BIMMeshProperties")
or not obj.data.BIMMeshProperties.ifc_definition_id
):
return []
representation = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
return tool.Model.get_manual_booleans(tool.Ifc.get_entity(obj), representation=representation)
@@ -218,3 +218,42 @@ class SelectDecomposition(bpy.types.Operator):
if subobj:
subobj.select_set(True)
return {"FINISHED"}
class BooleansMarkAsManual(bpy.types.Operator):
bl_idname = "bim.booleans_mark_as_manual"
bl_label = "Mark Booleans as Manual"
bl_options = {"REGISTER", "UNDO"}
bl_description = (
"\nMark all booleans in object's current representations as manual.\n"
"Manual booleans will be preserved until they are removed explicitly"
)
mark_as_manual: bpy.props.BoolProperty(name="Mark as Manual", default=True)
@classmethod
def poll(cls, context):
obj = context.active_object
if (
obj
and tool.Ifc.get_entity(obj)
and hasattr(obj.data, "BIMMeshProperties")
and obj.data.BIMMeshProperties.ifc_definition_id
):
return True
cls.poll_message_set("Need to select IFC element with representation")
return False
def execute(self, context):
obj = context.active_object
element = tool.Ifc.get_entity(obj)
representation = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
booleans = tool.Model.get_booleans(representation=representation)
if self.mark_as_manual:
tool.Model.mark_manual_booleans(element, booleans)
else:
tool.Model.unmark_manual_booleans(element, booleans)
self.report({"INFO"}, f"{len(booleans)} were marked as {'manual' if self.mark_as_manual else 'automatic'}")
blenderbim.bim.handler.refresh_ui_data()
return {"FINISHED"}
@@ -111,13 +111,21 @@ class BIM_PT_booleans(Panel):
if context.active_object.data.BIMMeshProperties.ifc_definition_id:
row = layout.row(align=True)
row.label(text=f"{BooleansData.data['total_booleans']} Booleans Found")
row.operator("bim.add_boolean", text="Apply Boolean", icon="ADD")
total_booleans = BooleansData.data["total_booleans"]
manual_booleans = BooleansData.data["manual_booleans"]
row.label(text=f"{len(total_booleans)} Booleans Found ({len(manual_booleans)} Manual)")
row.operator("bim.add_boolean", text="", icon="ADD")
show_boolean_button = row.row(align=True)
show_boolean_button.operator("bim.show_booleans", text="", icon="HIDE_OFF")
show_boolean_button.enabled = BooleansData.data["total_booleans"] > 0
show_boolean_button.enabled = len(total_booleans) > 0
row.operator("bim.hide_booleans", text="", icon="HIDE_ON")
booleans_are_manual = len(manual_booleans) == len(total_booleans)
op = row.operator(
"bim.booleans_mark_as_manual", text="", icon="PINNED" if booleans_are_manual else "UNPINNED"
)
op.mark_as_manual = not booleans_are_manual
elif context.active_object.data.BIMMeshProperties.ifc_boolean_id:
upsteam_obj = context.active_object.data.BIMMeshProperties.obj
upstream_obj_ifc_id = upsteam_obj.BIMObjectProperties.ifc_definition_id
+11 -9
View File
@@ -474,12 +474,13 @@ class Model(blenderbim.core.tool.Model):
return {"thickness": thickness, "offset": offset, "direction_sense": direction_sense}
@classmethod
def get_booleans(cls, element):
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if not body:
return []
def get_booleans(cls, element=None, representation=None):
if representation is None:
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if not representation:
return []
booleans = []
items = list(body.Items)
items = list(representation.Items)
while items:
item = items.pop()
if item.is_a("IfcBooleanResult"):
@@ -488,14 +489,15 @@ class Model(blenderbim.core.tool.Model):
return booleans
@classmethod
def get_manual_booleans(cls, element):
def get_manual_booleans(cls, element, representation=None):
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
if not pset:
return []
boolean_ids = json.loads(pset["Data"])
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if not body:
return []
if representation is None:
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if not representation:
return []
booleans = [b for b in cls.get_booleans(element) if b.id() in boolean_ids]
return booleans