mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 11:24:19 +00:00
See #1806. New fillings inherit their voids from existing occurrences if possible.
This commit is contained in:
@@ -123,11 +123,45 @@ class AddFilledOpening(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
def generate_opening_from_filling(self, filling, filling_obj, voided_obj):
|
||||
filling_type = ifcopenshell.util.element.get_type(filling)
|
||||
if filling_type:
|
||||
for filling_occurrence in ifcopenshell.util.element.get_types(filling_type):
|
||||
if filling_occurrence == filling or not filling_occurence.FillsVoids:
|
||||
continue
|
||||
return self.generate_opening_from_existing_filling_occurrence(filling_occurrence, filling_obj)
|
||||
|
||||
profile = ifcopenshell.util.representation.get_representation(filling, "Model", "Profile", "ELEVATION_VIEW")
|
||||
if profile:
|
||||
return self.generate_opening_from_filling_profile(filling_obj, voided_obj, profile)
|
||||
return self.generate_opening_from_filling_box(filling_obj, voided_obj)
|
||||
|
||||
def generate_opening_from_existing_filling_occurrence(self, filling_occurrence, filling_obj):
|
||||
for rel in getattr(filling_occurrence, "FillsVoids", []) or []:
|
||||
settings = ifcopenshell.geom.settings()
|
||||
|
||||
shape = ifcopenshell.geom.create_shape(settings, rel.RelatingOpeningElement)
|
||||
verts = shape.geometry.verts
|
||||
faces = shape.geometry.faces
|
||||
grouped_verts = [[verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
|
||||
grouped_faces = [[faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
|
||||
|
||||
bm = bmesh.new()
|
||||
bm.verts.index_update()
|
||||
bm.faces.index_update()
|
||||
new_verts = [bm.verts.new(v) for v in grouped_verts]
|
||||
new_faces = [bm.faces.new((new_verts[f[0]], new_verts[f[1]], new_verts[f[2]])) for f in grouped_faces]
|
||||
|
||||
bm.verts.index_update()
|
||||
bm.faces.index_update()
|
||||
|
||||
mesh = bpy.data.meshes.new(name="Opening")
|
||||
bm.to_mesh(mesh)
|
||||
bm.free()
|
||||
|
||||
obj = bpy.data.objects.new("Opening", mesh)
|
||||
obj.matrix_world = filling_obj.matrix_world
|
||||
return obj
|
||||
|
||||
def generate_opening_from_filling_profile(self, filling_obj, voided_obj, profile):
|
||||
settings = ifcopenshell.geom.settings()
|
||||
settings.set(settings.INCLUDE_CURVES, True)
|
||||
|
||||
@@ -126,19 +126,13 @@ class SelectSimilarType(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
related_object = bpy.data.objects.get(self.related_object) if self.related_object else context.active_object
|
||||
oprops = related_object.BIMObjectProperties
|
||||
product = self.file.by_id(oprops.ifc_definition_id)
|
||||
declaration = IfcStore.get_schema().declaration_by_name(product.is_a())
|
||||
if ifcopenshell.util.schema.is_a(declaration, "IfcElementType"):
|
||||
related_objects = ifcopenshell.api.run(
|
||||
"type.get_related_objects", self.file, **{"relating_type": self.file.by_id(oprops.ifc_definition_id)}
|
||||
)
|
||||
else:
|
||||
related_objects = ifcopenshell.api.run(
|
||||
"type.get_related_objects", self.file, **{"related_object": self.file.by_id(oprops.ifc_definition_id)}
|
||||
)
|
||||
relating_type = ifcopenshell.util.element.get_type(tool.Ifc.get_entity(related_object))
|
||||
if not relating_type:
|
||||
return {"FINISHED"}
|
||||
related_objects = ifcopenshell.util.element.get_types(relating_type)
|
||||
for obj in context.visible_objects:
|
||||
if obj.BIMObjectProperties.ifc_definition_id in related_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if element and element in related_objects:
|
||||
obj.select_set(True)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -148,3 +148,26 @@ Scenario: Select type objects
|
||||
When the object "IfcWallType/Empty" is selected
|
||||
And I press "bim.select_type_objects"
|
||||
Then the object "IfcWall/Cube" is selected
|
||||
|
||||
Scenario: Select similar type
|
||||
Given an empty IFC project
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
And I add an empty
|
||||
And the object "Empty" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_product" to "IfcElementType"
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||
And I press "bim.assign_class"
|
||||
And the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube.001')"
|
||||
When the object "IfcWall/Cube" is selected
|
||||
And I press "bim.select_similar_type"
|
||||
Then the object "IfcWall/Cube" is selected
|
||||
And the object "IfcWall/Cube.001" is selected
|
||||
|
||||
Reference in New Issue
Block a user