mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 14:07:43 +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.added_data = {}
|
||||||
self.native_elements = set()
|
self.native_elements = set()
|
||||||
self.native_data = {}
|
self.native_data = {}
|
||||||
|
self.progress = 0
|
||||||
|
|
||||||
self.material_creator = MaterialCreator(ifc_import_settings, self)
|
self.material_creator = MaterialCreator(ifc_import_settings, self)
|
||||||
|
|
||||||
@@ -205,7 +206,6 @@ class IfcImporter:
|
|||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
bpy.context.window_manager.progress_begin(0, 100)
|
bpy.context.window_manager.progress_begin(0, 100)
|
||||||
self.progress = 0
|
|
||||||
self.profile_code("Starting import process")
|
self.profile_code("Starting import process")
|
||||||
self.load_file()
|
self.load_file()
|
||||||
self.profile_code("Loading file")
|
self.profile_code("Loading file")
|
||||||
|
|||||||
@@ -39,8 +39,11 @@ classes = (
|
|||||||
opening.AddElementOpening,
|
opening.AddElementOpening,
|
||||||
opening.AddPotentialHalfSpaceSolid,
|
opening.AddPotentialHalfSpaceSolid,
|
||||||
opening.AddPotentialOpening,
|
opening.AddPotentialOpening,
|
||||||
|
opening.HideBooleans,
|
||||||
|
opening.HideOpenings,
|
||||||
opening.RemoveBooleans,
|
opening.RemoveBooleans,
|
||||||
opening.ShowBooleans,
|
opening.ShowBooleans,
|
||||||
|
opening.ShowOpenings,
|
||||||
profile.ChangeCardinalPoint,
|
profile.ChangeCardinalPoint,
|
||||||
profile.ChangeProfileDepth,
|
profile.ChangeProfileDepth,
|
||||||
profile.ExtendProfile,
|
profile.ExtendProfile,
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ def load_post(*args):
|
|||||||
product.regenerate_profile_usage,
|
product.regenerate_profile_usage,
|
||||||
)
|
)
|
||||||
|
|
||||||
IfcStore.add_element_listener(opening.element_listener)
|
|
||||||
IfcStore.add_element_listener(wall.element_listener)
|
IfcStore.add_element_listener(wall.element_listener)
|
||||||
IfcStore.add_element_listener(profile.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
|
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):
|
class AddElementOpening(bpy.types.Operator):
|
||||||
bl_idname = "bim.add_element_opening"
|
bl_idname = "bim.add_element_opening"
|
||||||
bl_label = "Add Element Opening"
|
bl_label = "Add Element Opening"
|
||||||
@@ -391,6 +347,20 @@ class ShowBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
|
|||||||
return obj
|
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):
|
class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
|
||||||
bl_idname = "bim.remove_booleans"
|
bl_idname = "bim.remove_booleans"
|
||||||
bl_label = "Remove Booleans"
|
bl_label = "Remove Booleans"
|
||||||
@@ -427,6 +397,45 @@ class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
|
|||||||
return {"FINISHED"}
|
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:
|
class DecorationsHandler:
|
||||||
installed = None
|
installed = None
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
|
from blenderbim.bim import import_ifc
|
||||||
|
|
||||||
|
|
||||||
class Model(blenderbim.core.tool.Model):
|
class Model(blenderbim.core.tool.Model):
|
||||||
@@ -46,3 +47,25 @@ class Model(blenderbim.core.tool.Model):
|
|||||||
item = item.FirstOperand
|
item = item.FirstOperand
|
||||||
else:
|
else:
|
||||||
break
|
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 = import_ifc.IfcImporter(ifc_import_settings)
|
||||||
ifc_importer.file = tool.Ifc.get()
|
ifc_importer.file = tool.Ifc.get()
|
||||||
ifc_importer.calculate_unit_scale()
|
ifc_importer.calculate_unit_scale()
|
||||||
|
ifc_importer.process_context_filter()
|
||||||
ports = set(ports)
|
ports = set(ports)
|
||||||
ports -= ifc_importer.create_products(ports)
|
ports -= ifc_importer.create_products(ports)
|
||||||
for port in ports or []:
|
for port in ports or []:
|
||||||
|
|||||||
Reference in New Issue
Block a user