mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
Basic show and remove representation boolean operators
This commit is contained in:
@@ -39,6 +39,8 @@ classes = (
|
||||
opening.AddElementOpening,
|
||||
opening.AddPotentialHalfSpaceSolid,
|
||||
opening.AddPotentialOpening,
|
||||
opening.RemoveBooleans,
|
||||
opening.ShowBooleans,
|
||||
profile.ChangeCardinalPoint,
|
||||
profile.ChangeProfileDepth,
|
||||
profile.ExtendProfile,
|
||||
|
||||
@@ -27,7 +27,7 @@ import blenderbim.tool as tool
|
||||
import blenderbim.core.geometry
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from math import pi
|
||||
from mathutils import Vector
|
||||
from mathutils import Vector, Matrix
|
||||
from bpy.types import Operator
|
||||
from bpy.types import SpaceView3D
|
||||
from bpy.props import FloatProperty
|
||||
@@ -328,6 +328,105 @@ class AddBoolean(Operator, tool.Ifc.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ShowBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
|
||||
bl_idname = "bim.show_booleans"
|
||||
bl_label = "Show Booleans"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
obj = context.active_object
|
||||
if (
|
||||
not obj.data
|
||||
or not hasattr(obj.data, "BIMMeshProperties")
|
||||
or not obj.data.BIMMeshProperties.ifc_definition_id
|
||||
):
|
||||
return {"FINISHED"}
|
||||
representation = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||
booleans = []
|
||||
for item in representation.Items:
|
||||
booleans.extend(self.get_booleans(item))
|
||||
for boolean in booleans:
|
||||
if boolean.is_a() == "IfcHalfSpaceSolid":
|
||||
if boolean.BaseSurface.is_a("IfcPlane"):
|
||||
boolean_obj = self.create_half_space_solid()
|
||||
position = boolean.BaseSurface.Position
|
||||
position = Matrix(ifcopenshell.util.placement.get_axis2placement(position).tolist())
|
||||
boolean_obj.matrix_world = position
|
||||
boolean_obj.data.BIMMeshProperties.ifc_boolean_id = boolean.id()
|
||||
boolean_obj.data.BIMMeshProperties.obj = obj
|
||||
return {"FINISHED"}
|
||||
|
||||
def get_booleans(self, item):
|
||||
results = []
|
||||
if item.is_a("IfcBooleanResult"):
|
||||
results.extend(self.get_booleans(item.FirstOperand))
|
||||
results.append(item.SecondOperand)
|
||||
return results
|
||||
|
||||
def create_half_space_solid(self):
|
||||
props = bpy.context.scene.BIMModelProperties
|
||||
bm = bmesh.new()
|
||||
bmesh.ops.create_grid(bm, size=0.5)
|
||||
bm.verts.ensure_lookup_table()
|
||||
bm.edges.ensure_lookup_table()
|
||||
bm.faces.ensure_lookup_table()
|
||||
mesh = bpy.data.meshes.new(name="Dumb Opening")
|
||||
bm.to_mesh(mesh)
|
||||
bm.free()
|
||||
obj = object_data_add(bpy.context, mesh, operator=self)
|
||||
obj.name = "HalfSpaceSolid"
|
||||
|
||||
has_deleted_opening = True
|
||||
while has_deleted_opening:
|
||||
has_deleted_opening = False
|
||||
for i, opening in enumerate(props.openings):
|
||||
if not opening.obj:
|
||||
props.openings.remove(i)
|
||||
has_deleted_opening = True
|
||||
|
||||
new = props.openings.add()
|
||||
new.obj = obj
|
||||
|
||||
DecorationsHandler.install(bpy.context)
|
||||
return obj
|
||||
|
||||
|
||||
class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper):
|
||||
bl_idname = "bim.remove_booleans"
|
||||
bl_label = "Remove Booleans"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
for obj in context.selected_objects:
|
||||
if (
|
||||
not obj.data
|
||||
or not hasattr(obj.data, "BIMMeshProperties")
|
||||
or not obj.data.BIMMeshProperties.ifc_boolean_id
|
||||
):
|
||||
continue
|
||||
try:
|
||||
boolean = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_boolean_id)
|
||||
except:
|
||||
continue
|
||||
ifcopenshell.api.run("geometry.remove_boolean", tool.Ifc.get(), item=boolean)
|
||||
if obj.data.BIMMeshProperties.obj:
|
||||
upstream_obj = obj.data.BIMMeshProperties.obj
|
||||
element = tool.Ifc.get_entity(upstream_obj)
|
||||
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
||||
if body:
|
||||
blenderbim.core.geometry.switch_representation(
|
||||
tool.Geometry,
|
||||
obj=upstream_obj,
|
||||
representation=body,
|
||||
should_reload=True,
|
||||
enable_dynamic_voids=False,
|
||||
is_global=True,
|
||||
should_sync_changes_first=False,
|
||||
)
|
||||
bpy.data.objects.remove(obj)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DecorationsHandler:
|
||||
installed = None
|
||||
|
||||
|
||||
@@ -367,6 +367,8 @@ class BIMMaterialProperties(PropertyGroup):
|
||||
|
||||
class BIMMeshProperties(PropertyGroup):
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
ifc_boolean_id: IntProperty(name="IFC Boolean ID")
|
||||
obj: bpy.props.PointerProperty(type=bpy.types.Object)
|
||||
is_native: BoolProperty(name="Is Native", default=False)
|
||||
is_swept_solid: BoolProperty(name="Is Swept Solid")
|
||||
is_parametric: BoolProperty(name="Is Parametric", default=False)
|
||||
|
||||
@@ -42,7 +42,7 @@ class Model(blenderbim.core.tool.Model):
|
||||
while True:
|
||||
if item.is_a("IfcExtrudedAreaSolid"):
|
||||
return item
|
||||
elif item.is_a("IfcBooleanClippingResult"):
|
||||
elif item.is_a("IfcBooleanResult"):
|
||||
item = item.FirstOperand
|
||||
else:
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user