mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 02:47:48 +00:00
WIP implement add / remove fills. See #1222.
This commit is contained in:
@@ -471,7 +471,7 @@ class IfcImporter:
|
||||
self.profile_code("Create presentation layers")
|
||||
self.add_project_to_scene()
|
||||
self.profile_code("Add project to scene")
|
||||
if self.ifc_import_settings.should_clean_mesh and len(self.file.by_type("IfcElement")) < 10000:
|
||||
if self.ifc_import_settings.should_clean_mesh and len(self.file.by_type("IfcElement")) < 1000:
|
||||
self.clean_mesh()
|
||||
self.profile_code("Mesh cleaning")
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import bpy
|
||||
from . import ui, operator
|
||||
from . import ui, prop, operator
|
||||
|
||||
classes = (
|
||||
operator.AddOpening,
|
||||
operator.RemoveOpening,
|
||||
operator.AddFilling,
|
||||
operator.RemoveFilling,
|
||||
prop.VoidProperties,
|
||||
ui.BIM_PT_voids,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
pass
|
||||
bpy.types.Scene.VoidProperties = bpy.props.PointerProperty(type=prop.VoidProperties)
|
||||
|
||||
|
||||
def unregister():
|
||||
pass
|
||||
del bpy.types.Scene.VoidProperties
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
class Usecase:
|
||||
def __init__(self, file, settings=None):
|
||||
self.file = file
|
||||
self.settings = {"opening": None, "element": None}
|
||||
for key, value in settings.items():
|
||||
self.settings[key] = value
|
||||
|
||||
def execute(self):
|
||||
self.file.create_entity("IfcRelFillsElement", **{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"RelatingOpeningElement": self.settings["opening"],
|
||||
"RelatedBuildingElement": self.settings["element"]
|
||||
})
|
||||
@@ -8,11 +8,12 @@ class Data:
|
||||
|
||||
@classmethod
|
||||
def load(cls, product_id):
|
||||
print('loading', product_id)
|
||||
file = IfcStore.get_file()
|
||||
if not file:
|
||||
return
|
||||
cls.products[product_id] = set()
|
||||
if product_id in cls.fillings:
|
||||
del cls.fillings[product_id]
|
||||
product = file.by_id(product_id)
|
||||
for rel in file.by_type("IfcRelVoidsElement"):
|
||||
building_element = rel.RelatingBuildingElement
|
||||
@@ -25,10 +26,15 @@ class Data:
|
||||
for rel in file.by_type("IfcRelFillsElement"):
|
||||
opening = rel.RelatingOpeningElement
|
||||
opening_id = int(opening.id())
|
||||
if opening_id not in cls.openings:
|
||||
continue
|
||||
filling = rel.RelatedBuildingElement
|
||||
filling_id = int(filling.id())
|
||||
|
||||
if filling_id == product_id and opening_id not in cls.openings:
|
||||
cls.openings[opening_id] = {"Name": opening.Name, "HasFillings": set()}
|
||||
|
||||
if opening_id not in cls.openings:
|
||||
continue
|
||||
|
||||
cls.fillings[filling_id] = {"Name": filling.Name, "FillsVoid": opening_id}
|
||||
cls.openings[opening_id]["HasFillings"].add(filling_id)
|
||||
return # See bug #1224
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import bpy
|
||||
import blenderbim.bim.module.void.add_opening as add_opening
|
||||
import blenderbim.bim.module.void.remove_opening as remove_opening
|
||||
import blenderbim.bim.module.void.add_filling as add_filling
|
||||
import blenderbim.bim.module.void.remove_filling as remove_filling
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.void.data import Data
|
||||
from blenderbim.bim.module.context.data import Data as ContextData
|
||||
@@ -30,10 +32,13 @@ class AddOpening(bpy.types.Operator):
|
||||
|
||||
self.file = IfcStore.get_file()
|
||||
element_id = obj.BIMObjectProperties.ifc_definition_id
|
||||
add_opening.Usecase(self.file, {
|
||||
"opening": self.file.by_id(opening.BIMObjectProperties.ifc_definition_id),
|
||||
"element": self.file.by_id(element_id)
|
||||
}).execute()
|
||||
add_opening.Usecase(
|
||||
self.file,
|
||||
{
|
||||
"opening": self.file.by_id(opening.BIMObjectProperties.ifc_definition_id),
|
||||
"element": self.file.by_id(element_id),
|
||||
},
|
||||
).execute()
|
||||
Data.load(element_id)
|
||||
|
||||
has_modifier = False
|
||||
@@ -72,3 +77,40 @@ class RemoveOpening(bpy.types.Operator):
|
||||
remove_opening.Usecase(self.file, {"opening": self.file.by_id(self.opening_id)}).execute()
|
||||
Data.load(obj.BIMObjectProperties.ifc_definition_id)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddFilling(bpy.types.Operator):
|
||||
bl_idname = "bim.add_filling"
|
||||
bl_label = "Add Filling"
|
||||
opening: bpy.props.StringProperty()
|
||||
obj: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
|
||||
opening = bpy.data.objects.get(self.opening) if self.opening else context.scene.VoidProperties.desired_opening
|
||||
self.file = IfcStore.get_file()
|
||||
element_id = obj.BIMObjectProperties.ifc_definition_id
|
||||
add_filling.Usecase(
|
||||
self.file,
|
||||
{
|
||||
"opening": self.file.by_id(opening.BIMObjectProperties.ifc_definition_id),
|
||||
"element": self.file.by_id(element_id),
|
||||
},
|
||||
).execute()
|
||||
Data.load(element_id)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemoveFilling(bpy.types.Operator):
|
||||
bl_idname = "bim.remove_filling"
|
||||
bl_label = "Remove Filling"
|
||||
obj: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
|
||||
self.file = IfcStore.get_file()
|
||||
remove_filling.Usecase(
|
||||
self.file, {"element": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)}
|
||||
).execute()
|
||||
Data.load(obj.BIMObjectProperties.ifc_definition_id)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import bpy
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import PointerProperty
|
||||
|
||||
|
||||
class VoidProperties(PropertyGroup):
|
||||
desired_opening: PointerProperty(name="Desired Opening To Fill", type=bpy.types.Object)
|
||||
@@ -0,0 +1,12 @@
|
||||
class Usecase:
|
||||
def __init__(self, file, settings=None):
|
||||
self.file = file
|
||||
self.settings = {"element": None}
|
||||
for key, value in settings.items():
|
||||
self.settings[key] = value
|
||||
|
||||
def execute(self):
|
||||
for rel in self.file.by_type("IfcRelFillsElement"):
|
||||
if rel.RelatedBuildingElement == self.settings["element"]:
|
||||
self.file.remove(rel)
|
||||
break
|
||||
@@ -18,7 +18,7 @@ class BIM_PT_voids(Panel):
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
if len(context.selected_objects) == 2:
|
||||
op = row.operator("bim.add_opening", icon="ADD", text="Add Selected")
|
||||
op = row.operator("bim.add_opening", icon="ADD", text="Add Opening")
|
||||
for obj in context.selected_objects:
|
||||
if "IfcOpeningElement" in obj.name or not obj.BIMObjectProperties.ifc_definition_id:
|
||||
op.opening = obj.name
|
||||
@@ -35,22 +35,36 @@ class BIM_PT_voids(Panel):
|
||||
else:
|
||||
obj_name = obj.name
|
||||
if opening_id and obj_name:
|
||||
op = row.operator("bim.remove_opening", icon="X", text="Remove Selected")
|
||||
op = row.operator("bim.remove_opening", icon="X", text="Remove Opening")
|
||||
op.opening_id = opening_id
|
||||
op.obj = obj_name
|
||||
else:
|
||||
row.label(text="Select an opening and an element to modify", icon="HELP")
|
||||
|
||||
for opening_id in Data.products[props.ifc_definition_id]:
|
||||
opening_ids = Data.products[props.ifc_definition_id]
|
||||
if not opening_ids:
|
||||
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[filling_id]
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=opening["Name"])
|
||||
row.label(text=filling["Name"])
|
||||
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"])
|
||||
row.label(text=opening["Name"], icon="SELECT_SUBTRACT")
|
||||
op = row.operator("bim.remove_opening", icon="X", text="")
|
||||
op.opening_id = opening_id
|
||||
|
||||
if 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="")
|
||||
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="")
|
||||
|
||||
Reference in New Issue
Block a user