mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Implement show and hide openings and hide booleans operator
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 []:
|
||||
|
||||
Reference in New Issue
Block a user