mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user