Implement show and hide openings and hide booleans operator

This commit is contained in:
Dion Moult
2022-10-01 23:45:49 +10:00
parent 2ec41bf3a0
commit e4e9db0b3e
6 changed files with 81 additions and 46 deletions
+1 -1
View File
@@ -188,6 +188,7 @@ class IfcImporter:
self.added_data = {}
self.native_elements = set()
self.native_data = {}
self.progress = 0
self.material_creator = MaterialCreator(ifc_import_settings, self)
@@ -205,7 +206,6 @@ class IfcImporter:
def execute(self):
bpy.context.window_manager.progress_begin(0, 100)
self.progress = 0
self.profile_code("Starting import process")
self.load_file()
self.profile_code("Loading file")
@@ -39,8 +39,11 @@ classes = (
opening.AddElementOpening,
opening.AddPotentialHalfSpaceSolid,
opening.AddPotentialOpening,
opening.HideBooleans,
opening.HideOpenings,
opening.RemoveBooleans,
opening.ShowBooleans,
opening.ShowOpenings,
profile.ChangeCardinalPoint,
profile.ChangeProfileDepth,
profile.ExtendProfile,
@@ -56,7 +56,6 @@ def load_post(*args):
product.regenerate_profile_usage,
)
IfcStore.add_element_listener(opening.element_listener)
IfcStore.add_element_listener(wall.element_listener)
IfcStore.add_element_listener(profile.element_listener)
@@ -36,50 +36,6 @@ from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertForma
from gpu_extras.batch import batch_for_shader
def element_listener(element, obj):
blenderbim.bim.handler.subscribe_to(obj, "mode", mode_callback)
def mode_callback(obj, data):
for obj in set(bpy.context.selected_objects + [bpy.context.active_object]):
if (
obj.mode != "EDIT"
or not obj.data
or not isinstance(obj.data, (bpy.types.Mesh, bpy.types.Curve, bpy.types.TextCurve))
or not obj.BIMObjectProperties.ifc_definition_id
or not bpy.context.scene.BIMProjectProperties.is_authoring
):
return
product = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id)
if not product.is_a("IfcOpeningElement"):
return
for rel in product.VoidsElements:
building_element_obj = IfcStore.get_element(rel.RelatingBuildingElement.id())
if not building_element_obj:
continue
if [m for m in building_element_obj.modifiers if m.type == "BOOLEAN"]:
continue
representation = ifcopenshell.util.representation.get_representation(
rel.RelatingBuildingElement, "Model", "Body", "MODEL_VIEW"
)
if not representation:
continue
blenderbim.core.geometry.switch_representation(
tool.Geometry,
obj=building_element_obj,
representation=representation,
should_reload=True,
enable_dynamic_voids=True,
is_global=True,
should_sync_changes_first=False,
)
IfcStore.edited_objs.add(obj)
bm = bmesh.from_edit_mesh(obj.data)
bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 1, verts=bm.verts, edges=bm.edges)
bmesh.update_edit_mesh(obj.data)
bm.free()
class AddElementOpening(bpy.types.Operator):
bl_idname = "bim.add_element_opening"
bl_label = "Add Element Opening"
@@ -391,6 +347,20 @@ class ShowBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
return obj
class HideBooleans(Operator, tool.Ifc.Operator):
bl_idname = "bim.hide_booleans"
bl_label = "Hide Booleans"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = bpy.context.scene.BIMModelProperties
for opening in props.openings:
obj = opening.obj
if obj.data.BIMMeshProperties.ifc_boolean_id:
bpy.data.objects.remove(obj)
return {"FINISHED"}
class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
bl_idname = "bim.remove_booleans"
bl_label = "Remove Booleans"
@@ -427,6 +397,45 @@ class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
return {"FINISHED"}
class ShowOpenings(Operator, tool.Ifc.Operator):
bl_idname = "bim.show_openings"
bl_label = "Show Openings"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = bpy.context.scene.BIMModelProperties
for obj in context.selected_objects:
element = tool.Ifc.get_entity(obj)
if not element:
continue
openings = tool.Model.load_openings(element, [r.RelatedOpeningElement for r in element.HasOpenings])
for opening in openings:
new = props.openings.add()
new.obj = opening
DecorationsHandler.install(bpy.context)
return {"FINISHED"}
class HideOpenings(Operator, tool.Ifc.Operator):
bl_idname = "bim.hide_openings"
bl_label = "Hide Openings"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = bpy.context.scene.BIMModelProperties
for obj in context.selected_objects:
element = tool.Ifc.get_entity(obj)
if not element:
continue
openings = [r.RelatedOpeningElement for r in element.HasOpenings]
for opening in openings:
opening_obj = tool.Ifc.get_object(opening)
if opening_obj:
tool.Ifc.unlink(element=opening, obj=opening_obj)
bpy.data.objects.remove(opening_obj)
return {"FINISHED"}
class DecorationsHandler:
installed = None
+23
View File
@@ -19,6 +19,7 @@
import bpy
import blenderbim.core.tool
import blenderbim.tool as tool
from blenderbim.bim import import_ifc
class Model(blenderbim.core.tool.Model):
@@ -46,3 +47,25 @@ class Model(blenderbim.core.tool.Model):
item = item.FirstOperand
else:
break
@classmethod
def load_openings(cls, element, openings):
if not openings:
return
obj = tool.Ifc.get_object(element)
ifc_import_settings = import_ifc.IfcImportSettings.factory()
ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
ifc_importer.file = tool.Ifc.get()
ifc_importer.calculate_unit_scale()
ifc_importer.process_context_filter()
openings = set(openings)
openings -= ifc_importer.create_products(openings)
for opening in openings or []:
if tool.Ifc.get_object(opening):
continue
opening_obj = ifc_importer.create_product(opening)
if obj:
opening_obj.parent = obj
opening_obj.matrix_parent_inverse = obj.matrix_world.inverted()
ifc_importer.place_objects_in_collections()
return ifc_importer.added_data.values()
+1
View File
@@ -89,6 +89,7 @@ class System(blenderbim.core.tool.System):
ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
ifc_importer.file = tool.Ifc.get()
ifc_importer.calculate_unit_scale()
ifc_importer.process_context_filter()
ports = set(ports)
ports -= ifc_importer.create_products(ports)
for port in ports or []: