Make remove opening more accessible in UI and refactor

This commit is contained in:
Dion Moult
2022-10-10 11:45:40 +11:00
parent 5d5ab3dafd
commit a5517071cc
4 changed files with 88 additions and 86 deletions
@@ -384,8 +384,7 @@ class OverrideDeleteTrait:
bpy.ops.bim.remove_opening(opening_id=element.id())
def remove_filling(self, element):
obj = IfcStore.get_element(element.id())
bpy.ops.bim.remove_filling(obj=obj.name)
bpy.ops.bim.remove_filling(filling=element.id())
def remove_port(self, port):
blenderbim.core.system.remove_port(tool.Ifc, tool.System, port=port)
@@ -22,6 +22,50 @@ import blenderbim.tool as tool
def refresh():
BooleansData.is_loaded = False
VoidsData.is_loaded = False
class VoidsData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"active_opening": cls.active_opening(), "openings": cls.openings(), "fillings": cls.fillings()}
cls.is_loaded = True
@classmethod
def active_opening(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
if element and element.is_a("IfcOpeningElement"):
return element.id()
@classmethod
def openings(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
if not element:
return []
results = []
for rel in getattr(element, "HasOpenings", []) or []:
has_fillings = []
opening = rel.RelatedOpeningElement
for rel2 in getattr(opening, "HasFillings", []) or []:
filling = rel2.RelatedBuildingElement
has_fillings.append({"id": filling.id(), "Name": filling.Name or "Unnamed"})
results.append({"id": opening.id(), "Name": opening.Name or "Unnamed", "HasFillings": has_fillings})
return results
@classmethod
def fillings(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
if not element:
return []
results = []
for rel in getattr(element, "HasFillings", []) or []:
filling = rel.RelatedBuildingElement
results.append({"id": filling.id(), "Name": filling.Name or "Unnamed"})
return results
class BooleansData:
@@ -22,7 +22,6 @@ import ifcopenshell.util.representation
import blenderbim.tool as tool
import blenderbim.core.geometry
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.void.data import Data
class AddOpening(bpy.types.Operator, tool.Ifc.Operator):
@@ -89,7 +88,6 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator):
is_global=True,
should_sync_changes_first=False,
)
Data.load(tool.Ifc.get(), element1.id())
if not has_visible_openings:
tool.Ifc.unlink(obj=obj2)
@@ -128,7 +126,6 @@ class RemoveOpening(bpy.types.Operator, tool.Ifc.Operator):
)
tool.Geometry.clear_cache(element)
Data.load(tool.Ifc.get(), obj.BIMObjectProperties.ifc_definition_id)
return {"FINISHED"}
@@ -153,37 +150,23 @@ class AddFilling(bpy.types.Operator):
if not element_id or not opening_id or element_id == opening_id:
return {"FINISHED"}
ifcopenshell.api.run(
"void.add_filling",
self.file,
**{
"opening": self.file.by_id(opening_id),
"element": self.file.by_id(element_id),
},
"void.add_filling", self.file, opening=self.file.by_id(opening_id), element=self.file.by_id(element_id)
)
Data.load(self.file, element_id)
return {"FINISHED"}
class RemoveFilling(bpy.types.Operator):
class RemoveFilling(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_filling"
bl_label = "Remove Filling"
bl_options = {"REGISTER", "UNDO"}
obj: bpy.props.StringProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
filling: bpy.props.IntProperty()
def _execute(self, context):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
if not obj:
return {"FINISHED"}
element = tool.Ifc.get_entity(obj)
if not element:
return {"FINISHED"}
for rel in element.FillsVoids:
filling = tool.Ifc.get().by_id(self.filling)
filling_obj = tool.Ifc.get_object(filling)
for rel in filling.FillsVoids:
bpy.ops.bim.remove_opening(opening_id=rel.RelatingOpeningElement.id())
ifcopenshell.api.run("void.remove_filling", tool.Ifc.get(), element=element)
Data.load(tool.Ifc.get(), element.id())
ifcopenshell.api.run("void.remove_filling", tool.Ifc.get(), element=filling)
return {"FINISHED"}
+36 -60
View File
@@ -17,10 +17,9 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy
import blenderbim.tool as tool
from bpy.types import Panel
from ifcopenshell.api.void.data import Data
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.void.data import BooleansData
from blenderbim.bim.module.void.data import BooleansData, VoidsData
class BIM_PT_voids(Panel):
@@ -34,71 +33,48 @@ class BIM_PT_voids(Panel):
@classmethod
def poll(cls, context):
if not context.active_object:
if not tool.Ifc.get_entity(context.active_object):
return False
if not IfcStore.get_element(context.active_object.BIMObjectProperties.ifc_definition_id):
return False
return IfcStore.get_file()
return True
def draw(self, context):
props = context.active_object.BIMObjectProperties
file = IfcStore.get_file()
if props.ifc_definition_id not in Data.products:
Data.load(file, props.ifc_definition_id)
active_object_is_an_opening = file.by_id(props.ifc_definition_id).is_a("IfcOpeningElement")
row = self.layout.row(align=True)
if len(context.selected_objects) == 2:
op = row.operator("bim.add_opening", icon="ADD", text="Add Opening")
opening_id = None
obj_name = None
for obj in context.selected_objects:
if obj.BIMObjectProperties.ifc_definition_id in Data.openings:
opening_id = obj.BIMObjectProperties.ifc_definition_id
elif obj.BIMObjectProperties.ifc_definition_id in Data.fillings:
opening_id = Data.fillings[obj.BIMObjectProperties.ifc_definition_id]["FillsVoid"]
else:
obj_name = obj.name
if opening_id and obj_name:
op = row.operator("bim.remove_opening", icon="X", text="Remove Opening").opening_id = opening_id
if not VoidsData.is_loaded:
VoidsData.load()
opening_ids = Data.products[props.ifc_definition_id]
if not opening_ids and not active_object_is_an_opening:
props = context.active_object.BIMObjectProperties
if len(context.selected_objects) == 2:
row = self.layout.row(align=True)
row.label(text="No Openings", icon="SELECT_SUBTRACT")
for opening_id in opening_ids:
opening = Data.openings[opening_id]
if opening["HasFillings"]:
for filling_id in opening["HasFillings"]:
filling = Data.fillings.get(filling_id)
if filling is None:
continue
row = self.layout.row(align=True)
row.label(text=opening["Name"], icon="SELECT_SUBTRACT")
row.label(text=filling["Name"], icon="SELECT_INTERSECT")
else:
row = self.layout.row(align=True)
row.label(text=opening["Name"], icon="SELECT_SUBTRACT")
op = row.operator("bim.remove_opening", icon="X", text="").opening_id = opening_id
if props.ifc_definition_id in Data.openings:
for filling_id in Data.openings[props.ifc_definition_id]["HasFillings"]:
filling = Data.fillings.get(filling_id)
if filling is None:
continue
op = row.operator("bim.add_opening", icon="ADD", text="Add Opening")
if VoidsData.data["active_opening"]:
row = self.layout.row()
op = row.operator("bim.remove_opening", icon="X", text="Remove Opening")
op.opening_id = VoidsData.data["active_opening"]
if not VoidsData.data["fillings"]:
row = self.layout.row()
row.label(text="No Fillings", icon="SELECT_INTERSECT")
for filling in VoidsData.data["fillings"]:
row = self.layout.row(align=True)
row.label(text=filling["Name"], icon="SELECT_INTERSECT")
op = row.operator("bim.remove_filling", icon="X", text="")
op.obj = IfcStore.get_element(filling_id).name
if active_object_is_an_opening:
pass
elif props.ifc_definition_id not in Data.fillings:
row = self.layout.row(align=True)
row.prop(context.scene.VoidProperties, "desired_opening", text="", icon="SELECT_INTERSECT")
row.operator("bim.add_filling", icon="ADD", text="")
row.operator("bim.remove_filling", icon="X", text="").filling = filling["id"]
else:
opening = Data.openings[Data.fillings[props.ifc_definition_id]["FillsVoid"]]
row = self.layout.row(align=True)
row.label(text=opening["Name"], icon="SELECT_INTERSECT")
row.operator("bim.remove_filling", icon="X", text="")
if not VoidsData.data["openings"]:
row = self.layout.row()
row.label(text="No Openings", icon="SELECT_SUBTRACT")
for opening in VoidsData.data["openings"]:
if opening["HasFillings"]:
for filling in opening["HasFillings"]:
row = self.layout.row(align=True)
row.label(text=opening["Name"], icon="SELECT_SUBTRACT")
row.label(text=filling["Name"], icon="SELECT_INTERSECT")
else:
row = self.layout.row(align=True)
row.label(text=opening["Name"], icon="SELECT_SUBTRACT")
row.operator("bim.remove_opening", icon="X", text="").opening_id = opening["id"]
class BIM_PT_booleans(Panel):