mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 10:33:20 +00:00
Make remove opening more accessible in UI and refactor
This commit is contained in:
@@ -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"}
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user