type.assign_type - support batching #4474

This commit is contained in:
Andrej730
2024-04-10 17:18:37 +05:00
parent ba4eb2a891
commit df4943205a
34 changed files with 308 additions and 162 deletions
@@ -111,7 +111,7 @@ class FilledOpeningGenerator:
# Equivalent to "side Z" for a wall axis, so that stuff like skylights appear on the top. # Equivalent to "side Z" for a wall axis, so that stuff like skylights appear on the top.
local_position_on_voided_obj.z = layers["offset"] + layers["thickness"] local_position_on_voided_obj.z = layers["offset"] + layers["thickness"]
new_matrix.translation.xyz = voided_obj.matrix_world @ local_position_on_voided_obj new_matrix.translation.xyz = voided_obj.matrix_world @ local_position_on_voided_obj
rotation_matrix = Matrix.Rotation(radians(-90), 4, 'X') rotation_matrix = Matrix.Rotation(radians(-90), 4, "X")
new_matrix @= rotation_matrix new_matrix @= rotation_matrix
filling_obj.matrix_world = new_matrix filling_obj.matrix_world = new_matrix
@@ -188,7 +188,13 @@ class FilledOpeningGenerator:
) )
def regenerate_from_type(self, usecase_path, ifc_file, settings): def regenerate_from_type(self, usecase_path, ifc_file, settings):
filling = settings["related_object"] relating_type = settings["relating_type"]
for related_object in settings["related_objects"]:
self._regenerate_from_type(related_object)
def _regenerate_from_type(self, related_object: ifcopenshell.entity_instance) -> None:
filling = related_object
if not getattr(filling, "FillsVoids", None): if not getattr(filling, "FillsVoids", None):
return return
@@ -96,7 +96,7 @@ class DumbProfileGenerator:
should_add_representation=False, should_add_representation=False,
context=self.body_context, context=self.body_context,
) )
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=self.relating_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type)
material = ifcopenshell.util.element.get_material(element) material = ifcopenshell.util.element.get_material(element)
material.CardinalPoint = self.cardinal_point material.CardinalPoint = self.cardinal_point
@@ -211,11 +211,18 @@ class DumbProfileRegenerator:
return results return results
def regenerate_from_type(self, usecase_path, ifc_file, settings): def regenerate_from_type(self, usecase_path, ifc_file, settings):
obj = tool.Ifc.get_object(settings["related_object"]) relating_type = settings["relating_type"]
if not obj or not obj.data or not obj.data.BIMMeshProperties.ifc_definition_id:
new_material = ifcopenshell.util.element.get_material(relating_type)
if not new_material or not new_material.is_a("IfcMaterialLayerSet"):
return return
new_material = ifcopenshell.util.element.get_material(settings["relating_type"])
if not new_material or not new_material.is_a("IfcMaterialProfileSet"): for related_object in settings["related_objects"]:
self._regenerate_from_type(related_object)
def _regenerate_from_type(self, related_object: ifcopenshell.entity_instance) -> None:
obj = tool.Ifc.get_object(related_object)
if not obj or not obj.data or not obj.data.BIMMeshProperties.ifc_definition_id:
return return
DumbProfileRecalculator().recalculate([obj]) DumbProfileRecalculator().recalculate([obj])
@@ -35,6 +35,7 @@ from math import radians
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from blenderbim.bim.module.geometry.helper import Helper from blenderbim.bim.module.geometry.helper import Helper
from blenderbim.bim.module.model.decorator import ProfileDecorator from blenderbim.bim.module.model.decorator import ProfileDecorator
from typing import Optional
def calculate_quantities(usecase_path, ifc_file, settings): def calculate_quantities(usecase_path, ifc_file, settings):
@@ -177,7 +178,7 @@ class DumbSlabGenerator:
should_add_representation=False, should_add_representation=False,
context=self.body_context, context=self.body_context,
) )
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=self.relating_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type)
blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
representation = ifcopenshell.api.run( representation = ifcopenshell.api.run(
@@ -250,27 +251,38 @@ class DumbSlabPlaner:
self.change_thickness(element, total_thickness) self.change_thickness(element, total_thickness)
def regenerate_from_type(self, usecase_path, ifc_file, settings): def regenerate_from_type(self, usecase_path, ifc_file, settings):
obj = tool.Ifc.get_object(settings["related_object"]) relating_type = settings["relating_type"]
if not obj or not obj.data or not obj.data.BIMMeshProperties.ifc_definition_id:
return new_material = ifcopenshell.util.element.get_material(relating_type)
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
new_material = ifcopenshell.util.element.get_material(settings["relating_type"])
if not new_material or not new_material.is_a("IfcMaterialLayerSet"): if not new_material or not new_material.is_a("IfcMaterialLayerSet"):
return return
parametric = ifcopenshell.util.element.get_psets(settings["relating_type"]).get("EPset_Parametric") parametric = ifcopenshell.util.element.get_psets(settings["relating_type"]).get("EPset_Parametric")
layer_set_direction = None layer_set_direction = None
if parametric: if parametric:
layer_set_direction = parametric.get("LayerSetDirection", layer_set_direction) layer_set_direction = parametric.get("LayerSetDirection", layer_set_direction)
new_thickness = sum([l.LayerThickness for l in new_material.MaterialLayers]) new_thickness = sum([l.LayerThickness for l in new_material.MaterialLayers])
material = ifcopenshell.util.element.get_material(settings["related_object"])
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
for related_object in settings["related_objects"]:
self._regenerate_from_type(related_object, layer_set_direction, new_thickness)
def _regenerate_from_type(
self, related_object: ifcopenshell.entity_instance, layer_set_direction: Optional[str], new_thickness: float
) -> None:
obj = tool.Ifc.get_object(related_object)
if not obj or not obj.data or not obj.data.BIMMeshProperties.ifc_definition_id:
return
material = ifcopenshell.util.element.get_material(related_object)
if not material or not material.is_a("IfcMaterialLayerSetUsage"): if not material or not material.is_a("IfcMaterialLayerSetUsage"):
return return
if layer_set_direction: if layer_set_direction:
material.LayerSetDirection = layer_set_direction material.LayerSetDirection = layer_set_direction
if material.LayerSetDirection == "AXIS3": if material.LayerSetDirection == "AXIS3":
self.change_thickness(settings["related_object"], new_thickness) self.change_thickness(related_object, new_thickness)
def change_thickness(self, element, thickness): def change_thickness(self, element: ifcopenshell.entity_instance, thickness: float) -> None:
body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW") body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
obj = tool.Ifc.get_object(element) obj = tool.Ifc.get_object(element)
if not obj: if not obj:
@@ -37,6 +37,7 @@ from blenderbim.bim.ifc import IfcStore
from math import pi, sin, cos, degrees, radians from math import pi, sin, cos, degrees, radians
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from blenderbim.bim.module.model.opening import FilledOpeningGenerator from blenderbim.bim.module.model.opening import FilledOpeningGenerator
from typing import Optional
class JoinWall(bpy.types.Operator, tool.Ifc.Operator): class JoinWall(bpy.types.Operator, tool.Ifc.Operator):
@@ -608,7 +609,7 @@ class DumbWallGenerator:
should_add_representation=False, should_add_representation=False,
context=self.body_context, context=self.body_context,
) )
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=self.relating_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type)
if self.axis_context: if self.axis_context:
representation = ifcopenshell.api.run( representation = ifcopenshell.api.run(
"geometry.add_axis_representation", "geometry.add_axis_representation",
@@ -729,18 +730,29 @@ class DumbWallPlaner:
DumbWallRecalculator().recalculate([w for w in set(walls) if w]) DumbWallRecalculator().recalculate([w for w in set(walls) if w])
def regenerate_from_type(self, usecase_path, ifc_file, settings): def regenerate_from_type(self, usecase_path, ifc_file, settings):
obj = tool.Ifc.get_object(settings["related_object"]) relating_type = settings["relating_type"]
if not obj or not obj.data or not obj.data.BIMMeshProperties.ifc_definition_id:
return new_material = ifcopenshell.util.element.get_material(relating_type)
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
new_material = ifcopenshell.util.element.get_material(settings["relating_type"])
if not new_material or not new_material.is_a("IfcMaterialLayerSet"): if not new_material or not new_material.is_a("IfcMaterialLayerSet"):
return return
parametric = ifcopenshell.util.element.get_psets(settings["relating_type"]).get("EPset_Parametric")
parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric")
layer_set_direction = None layer_set_direction = None
if parametric: if parametric:
layer_set_direction = parametric.get("LayerSetDirection", layer_set_direction) layer_set_direction = parametric.get("LayerSetDirection", layer_set_direction)
material = ifcopenshell.util.element.get_material(settings["related_object"])
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
for related_object in settings["related_objects"]:
self._regenerate_from_type(related_object, layer_set_direction)
def _regenerate_from_type(
self, related_object: ifcopenshell.entity_instance, layer_set_direction: Optional[str]
) -> None:
obj = tool.Ifc.get_object(related_object)
if not obj or not obj.data or not obj.data.BIMMeshProperties.ifc_definition_id:
return
material = ifcopenshell.util.element.get_material(related_object)
if not material or not material.is_a("IfcMaterialLayerSetUsage"): if not material or not material.is_a("IfcMaterialLayerSetUsage"):
return return
if layer_set_direction: if layer_set_direction:
+1 -1
View File
@@ -20,7 +20,7 @@ import blenderbim.core.geometry
def assign_type(ifc, type_tool, element=None, type=None): def assign_type(ifc, type_tool, element=None, type=None):
ifc.run("type.assign_type", related_object=element, relating_type=type) ifc.run("type.assign_type", related_objects=[element], relating_type=type)
obj = ifc.get_object(element) obj = ifc.get_object(element)
if type_tool.has_material_usage(element): if type_tool.has_material_usage(element):
pass # for now, representation regeneration handled by API listeners pass # for now, representation regeneration handled by API listeners
+1 -1
View File
@@ -690,7 +690,7 @@ class Spatial(blenderbim.core.tool.Spatial):
instance_class = ifcopenshell.util.type.get_applicable_entities(ifc_class, tool.Ifc.get().schema)[0] instance_class = ifcopenshell.util.type.get_applicable_entities(ifc_class, tool.Ifc.get().schema)[0]
bpy.ops.bim.assign_class(obj=obj.name, ifc_class=instance_class) bpy.ops.bim.assign_class(obj=obj.name, ifc_class=instance_class)
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
tool.Ifc.run("type.assign_type", related_object=element, relating_type=relating_type) tool.Ifc.run("type.assign_type", related_objects=[element], relating_type=relating_type)
@classmethod @classmethod
def assign_relating_type_to_element(cls, ifc, Type, element, relating_type): def assign_relating_type_to_element(cls, ifc, Type, element, relating_type):
+2 -2
View File
@@ -22,7 +22,7 @@ from test.core.bootstrap import ifc, type
class TestAssignType: class TestAssignType:
def test_assigning_and_switching_to_an_existing_type_data(self, ifc, type): def test_assigning_and_switching_to_an_existing_type_data(self, ifc, type):
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called() ifc.run("type.assign_type", related_objects=["element"], relating_type="type").should_be_called()
type.has_material_usage("element").should_be_called().will_return(False) type.has_material_usage("element").should_be_called().will_return(False)
ifc.get_object("type").should_be_called().will_return("type_obj") ifc.get_object("type").should_be_called().will_return("type_obj")
type.get_object_data("type_obj").should_be_called().will_return("type_obj_data") type.get_object_data("type_obj").should_be_called().will_return("type_obj_data")
@@ -32,7 +32,7 @@ class TestAssignType:
subject.assign_type(ifc, type, element="element", type="type") subject.assign_type(ifc, type, element="element", type="type")
def test_assigning_and_not_changing_data_if_the_type_has_no_data(self, ifc, type): def test_assigning_and_not_changing_data_if_the_type_has_no_data(self, ifc, type):
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called() ifc.run("type.assign_type", related_objects=["element"], relating_type="type").should_be_called()
type.has_material_usage("element").should_be_called().will_return(False) type.has_material_usage("element").should_be_called().will_return(False)
ifc.get_object("type").should_be_called().will_return("type_obj") ifc.get_object("type").should_be_called().will_return("type_obj")
type.get_object_data("type_obj").should_be_called().will_return(None) type.get_object_data("type_obj").should_be_called().will_return(None)
+2 -2
View File
@@ -199,7 +199,7 @@ class TestGetElementType(NewFile):
ifc = tool.Ifc.get() ifc = tool.Ifc.get()
element = ifc.createIfcWall() element = ifc.createIfcWall()
type = ifc.createIfcWallType() type = ifc.createIfcWallType()
ifcopenshell.api.run("type.assign_type", ifc, related_object=element, relating_type=type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=type)
assert subject.get_element_type(element) == type assert subject.get_element_type(element) == type
@@ -209,7 +209,7 @@ class TestGetElementsOfType(NewFile):
ifc = tool.Ifc.get() ifc = tool.Ifc.get()
element = ifc.createIfcWall() element = ifc.createIfcWall()
type = ifc.createIfcWallType() type = ifc.createIfcWallType()
ifcopenshell.api.run("type.assign_type", ifc, related_object=element, relating_type=type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=type)
assert subject.get_elements_of_type(type) == (element,) assert subject.get_elements_of_type(type) == (element,)
+1 -1
View File
@@ -98,7 +98,7 @@ class TestGetElementType(NewFile):
ifc = tool.Ifc.get() ifc = tool.Ifc.get()
element = ifc.createIfcWall() element = ifc.createIfcWall()
type = ifc.createIfcWallType() type = ifc.createIfcWallType()
ifcopenshell.api.run("type.assign_type", ifc, related_object=element, relating_type=type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=type)
assert subject.get_element_type(element) == type assert subject.get_element_type(element) == type
+1 -1
View File
@@ -154,7 +154,7 @@ class TestGetTypeOccurrences(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
assert subject.get_type_occurrences(wall_type) == (wall,) assert subject.get_type_occurrences(wall_type) == (wall,)
@@ -648,7 +648,7 @@ efficient and implies that the type is interchangable (e.g. for maintenance).
# Assign our furniture occurrence to the type. # Assign our furniture occurrence to the type.
# That's it! The representation will automatically be mapped! # That's it! The representation will automatically be mapped!
run("type.assign_type", model, related_object=element, relating_type=element_type) run("type.assign_type", model, related_objects=[element], relating_type=element_type)
Material layer sets Material layer sets
------------------- -------------------
@@ -693,7 +693,7 @@ responsibility to make sure the geometry is correct.
ifcopenshell.api.run("geometry.edit_object_placement", model, product=wall) ifcopenshell.api.run("geometry.edit_object_placement", model, product=wall)
# The wall is a WAL01 wall type. The material layer set is inherited. # The wall is a WAL01 wall type. The material layer set is inherited.
ifcopenshell.api.run("type.assign_type", model, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[wall], relating_type=wall_type)
# It's now our responsibility to create a compatible representation. # It's now our responsibility to create a compatible representation.
# Notice how our thickness of 0.118 must equal .013 + .092 + .013 from our type # Notice how our thickness of 0.118 must equal .013 + .092 + .013 from our type
@@ -749,7 +749,7 @@ responsibility to make sure the geometry is correct.
ifcopenshell.api.run("geometry.edit_object_placement", model, product=beam) ifcopenshell.api.run("geometry.edit_object_placement", model, product=beam)
# The beam is a B1 beam type. The material profile set is inherited. # The beam is a B1 beam type. The material profile set is inherited.
ifcopenshell.api.run("type.assign_type", model, related_object=beam, relating_type=beam_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[beam], relating_type=beam_type)
# It's now our responsibility to create a compatible representation. # It's now our responsibility to create a compatible representation.
# Notice how we reuse our profile instead of creating a new profile. # Notice how we reuse our profile instead of creating a new profile.
@@ -73,6 +73,9 @@ ARGUMENTS_DEPRECATION = {
"nest.unassign_object": partial( "nest.unassign_object": partial(
batching_argument_deprecation, prev_argument="related_object", new_argument="related_objects" batching_argument_deprecation, prev_argument="related_object", new_argument="related_objects"
), ),
"type.assign_type": partial(
batching_argument_deprecation, prev_argument="related_object", new_argument="related_objects"
),
} }
@@ -85,8 +85,8 @@ class Usecase:
# automatically inherit the material from the type. # automatically inherit the material from the type.
bench1 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture") bench1 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
bench2 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture") bench2 = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
ifcopenshell.api.run("type.assign_type", model, related_object=bench1, relating_type=bench_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[bench1], relating_type=bench_type)
ifcopenshell.api.run("type.assign_type", model, related_object=bench2, relating_type=bench_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[bench2], relating_type=bench_type)
# If we have a concrete wall, we should use a layer set. Again, # If we have a concrete wall, we should use a layer set. Again,
# let's start with a wall type, not occurrences. # let's start with a wall type, not occurrences.
@@ -106,7 +106,7 @@ class Usecase:
# Let's imagine an occurrence of this wall type. # Let's imagine an occurrence of this wall type.
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", model, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[wall], relating_type=wall_type)
# Our wall occurrence needs to have a "set usage" which describes # Our wall occurrence needs to have a "set usage" which describes
# how the layers relate to a reference line (typically a 2D line # how the layers relate to a reference line (typically a 2D line
@@ -59,7 +59,7 @@ class Usecase:
# Let's imagine an occurrence of this wall type. # Let's imagine an occurrence of this wall type.
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", model, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[wall], relating_type=wall_type)
# Our wall occurrence needs to have a "set usage" which describes # Our wall occurrence needs to have a "set usage" which describes
# how the layers relate to a reference line (typically a 2D line # how the layers relate to a reference line (typically a 2D line
@@ -204,7 +204,7 @@ class Usecase:
"type.assign_type", "type.assign_type",
self.file, self.file,
should_run_listeners=False, should_run_listeners=False,
related_object=element, related_objects=[element],
relating_type=new_type, relating_type=new_type,
should_map_representations=False, should_map_representations=False,
) )
@@ -19,11 +19,18 @@
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element import ifcopenshell.util.element
from typing import Union
class Usecase: class Usecase:
def __init__(self, file, related_object=None, relating_type=None, should_map_representations=True): def __init__(
"""Assigns a type to an occurrence of an object self,
file: ifcopenshell.file,
related_objects: list[ifcopenshell.entity_instance],
relating_type: ifcopenshell.entity_instance,
should_map_representations=True,
):
"""Assigns a type to occurrences of an object
IFC supports the concept of occurrences and types. An occurrence is an IFC supports the concept of occurrences and types. An occurrence is an
actual physical product in the real world: like a wall, a chair, a door, actual physical product in the real world: like a wall, a chair, a door,
@@ -83,8 +90,8 @@ class Usecase:
as-built or dilapidation models, where existing conditions are as-built or dilapidation models, where existing conditions are
ambiguous, unknown or are so bespoke as to have no logical type. ambiguous, unknown or are so bespoke as to have no logical type.
:param related_object: The IfcElement occurrence. :param related_objects: The IfcElement occurrences.
:type related_object: ifcopenshell.entity_instance.entity_instance :type related_objects: list[ifcopenshell.entity_instance.entity_instance]
:param relating_type: The IfcElementType type. :param relating_type: The IfcElementType type.
:type relating_type: ifcopenshell.entity_instance.entity_instance :type relating_type: ifcopenshell.entity_instance.entity_instance
:param should_map_representations: If a type has a representation map, :param should_map_representations: If a type has a representation map,
@@ -93,7 +100,8 @@ class Usecase:
yourself. In this scenario, you may set this to False. yourself. In this scenario, you may set this to False.
:type should_map_representations: bool :type should_map_representations: bool
:return: The IfcRelDefinesByType relationship :return: The IfcRelDefinesByType relationship
:rtype: ifcopenshell.entity_instance.entity_instance or `None` if `related_objects` was empty list.
:rtype: Union[ifcopenshell.entity_instance.entity_instance, None]
Example: Example:
@@ -111,7 +119,7 @@ class Usecase:
# had a representation, the furniture occurrence will also now have # had a representation, the furniture occurrence will also now have
# the exact same representation. This is highly efficient as you # the exact same representation. This is highly efficient as you
# don't need to define the representation for every occurrence. # don't need to define the representation for every occurrence.
ifcopenshell.api.run("type.assign_type", model, related_object=furniture, relating_type=furniture_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[furniture], relating_type=furniture_type)
# Let's imagine a parametric material layer set # Let's imagine a parametric material layer set
wall_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWallType", name="WAL01") wall_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWallType", name="WAL01")
@@ -146,7 +154,7 @@ class Usecase:
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
# The wall is a WAL01 wall type. # The wall is a WAL01 wall type.
ifcopenshell.api.run("type.assign_type", model, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[wall], relating_type=wall_type)
# A bit of preparation, let's create some geometric contexts since # A bit of preparation, let's create some geometric contexts since
# we want to create some geometry for our wall. # we want to create some geometry for our wall.
@@ -167,81 +175,101 @@ class Usecase:
""" """
self.file = file self.file = file
self.settings = { self.settings = {
"related_object": related_object, "related_objects": related_objects,
"relating_type": relating_type, "relating_type": relating_type,
"should_map_representations": should_map_representations, "should_map_representations": should_map_representations,
} }
def execute(self): def execute(self) -> Union[ifcopenshell.entity_instance, None]:
if self.file.schema == "IFC2X3": if not self.settings["related_objects"]:
is_typed_by = None
is_defined_by = self.settings["related_object"].IsDefinedBy
for rel in is_defined_by:
if rel.is_a("IfcRelDefinesByType"):
is_typed_by = [rel]
break
types = self.settings["relating_type"].ObjectTypeOf
else:
is_typed_by = self.settings["related_object"].IsTypedBy
types = self.settings["relating_type"].Types
if types and is_typed_by == types:
return return
if is_typed_by: related_objects = set(self.settings["related_objects"])
related_objects = list(is_typed_by[0].RelatedObjects) relating_type = self.settings["relating_type"]
related_objects.remove(self.settings["related_object"])
if related_objects: ifc2x3 = self.file.schema == "IFC2X3"
is_typed_by[0].RelatedObjects = related_objects
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": is_typed_by[0]}) related_objects = set(self.settings["related_objects"])
relating_type = self.settings["relating_type"]
if ifc2x3:
types = next(iter(relating_type.ObjectTypeOf), None)
else:
types = next(iter(relating_type.Types), None)
previous_types_rels: set[ifcopenshell.entity_instance] = set()
objects_without_types: list[ifcopenshell.entity_instance] = []
objects_with_types: list[ifcopenshell.entity_instance] = []
# check if there is anything to change
for object in related_objects:
if ifc2x3:
object_rel = next((i for i in object.IsDefinedBy if i.is_a("IfcRelDefinesByType")), None)
else: else:
history = is_typed_by[0].OwnerHistory object_rel = next(iter(object.IsTypedBy), None)
self.file.remove(is_typed_by[0])
if object_rel is None:
objects_without_types.append(object)
continue
# either is_nested_by is None or product is part of different rel
if object_rel != types:
previous_types_rels.add(object_rel)
objects_with_types.append(object)
objects_to_change = objects_without_types + objects_with_types
# nothing to change
if not objects_to_change:
return types
# unassign from previous types
for is_typed_by in previous_types_rels:
cur_related_objects = set(is_typed_by.RelatedObjects) - related_objects
if cur_related_objects:
is_typed_by.RelatedObjects = list(cur_related_objects)
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": is_typed_by})
else:
history = is_typed_by.OwnerHistory
self.file.remove(is_typed_by)
if history: if history:
ifcopenshell.util.element.remove_deep2(self.file, history) ifcopenshell.util.element.remove_deep2(self.file, history)
# assign objects to a new type
if types: if types:
related_objects = list(types[0].RelatedObjects) types.RelatedObjects = list(set(types.RelatedObjects) | related_objects)
related_objects.append(self.settings["related_object"]) ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": types})
types[0].RelatedObjects = related_objects
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": types[0]})
else: else:
types = self.file.create_entity( types = self.file.create_entity(
"IfcRelDefinesByType", "IfcRelDefinesByType",
**{ **{
"GlobalId": ifcopenshell.guid.new(), "GlobalId": ifcopenshell.guid.new(),
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file), "OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
"RelatedObjects": [self.settings["related_object"]], "RelatedObjects": list(related_objects),
"RelatingType": self.settings["relating_type"], "RelatingType": relating_type,
} },
) )
if self.settings["should_map_representations"]: if self.settings["should_map_representations"]:
if getattr(self.settings["relating_type"], "RepresentationMaps", None): if getattr(relating_type, "RepresentationMaps", None):
ifcopenshell.api.run( for related_object in related_objects:
"type.map_type_representations", ifcopenshell.api.run(
self.file, "type.map_type_representations",
related_object=self.settings["related_object"], self.file,
relating_type=self.settings["relating_type"], related_object=related_object,
) relating_type=relating_type,
self.map_material_usages() )
self.map_material_usages(related_objects)
return types return types
def map_material_usages(self): def map_material_usages(self, related_objects: set[ifcopenshell.entity_instance]) -> None:
type_material = ifcopenshell.util.element.get_material(self.settings["relating_type"]) type_material = ifcopenshell.util.element.get_material(self.settings["relating_type"])
if not type_material: if not type_material:
return return
if type_material.is_a("IfcMaterialLayerSet"): ifc_class = type_material.is_a()
ifcopenshell.api.run( if ifc_class in ("IfcMaterialLayerSet", "IfcMaterialProfileSet"):
"material.assign_material", for related_object in related_objects:
self.file, ifcopenshell.api.run(
product=self.settings["related_object"], "material.assign_material",
type="IfcMaterialLayerSetUsage", self.file,
) product=related_object,
elif type_material.is_a("IfcMaterialProfileSet"): type=f"{ifc_class}Usage",
ifcopenshell.api.run( )
"material.assign_material",
self.file,
product=self.settings["related_object"],
type="IfcMaterialProfileSetUsage",
)
@@ -60,7 +60,7 @@ class Usecase:
# furniture type has no representation, so the furniture may also # furniture type has no representation, so the furniture may also
# have no representation, or any arbitrary representation that may # have no representation, or any arbitrary representation that may
# vary from occurrence to occurrence. # vary from occurrence to occurrence.
ifcopenshell.api.run("type.assign_type", model, related_object=furniture, relating_type=furniture_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[furniture], relating_type=furniture_type)
# A bit of preparation, let's create some geometric contexts since # A bit of preparation, let's create some geometric contexts since
# we want to create some geometry for our furniture type. # we want to create some geometry for our furniture type.
@@ -42,7 +42,7 @@ class Usecase:
furniture = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture") furniture = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
# Assign the furniture to the furniture type. # Assign the furniture to the furniture type.
ifcopenshell.api.run("type.assign_type", model, related_object=furniture, relating_type=furniture_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[furniture], relating_type=furniture_type)
# Change our mind. Maybe it's a different type? # Change our mind. Maybe it's a different type?
ifcopenshell.api.run("type.unassign_type", model, related_object=furniture) ifcopenshell.api.run("type.unassign_type", model, related_object=furniture)
@@ -47,7 +47,7 @@ class TestAssignRepresentation(test.bootstrap.IFC4):
def test_assigning_to_a_type_will_map_representations_to_instances(self): def test_assigning_to_a_type_will_map_representations_to_instances(self):
wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
walltype = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") walltype = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=wall, relating_type=walltype) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[wall], relating_type=walltype)
context = self.file.createIfcGeometricRepresentationContext() context = self.file.createIfcGeometricRepresentationContext()
rep = self.file.createIfcShapeRepresentation(ContextOfItems=context) rep = self.file.createIfcShapeRepresentation(ContextOfItems=context)
rep2 = self.file.createIfcShapeRepresentation(ContextOfItems=context) rep2 = self.file.createIfcShapeRepresentation(ContextOfItems=context)
@@ -69,7 +69,7 @@ class TestAssignRepresentation(test.bootstrap.IFC4):
ifcopenshell.api.run("geometry.assign_representation", self.file, product=walltype, representation=rep) ifcopenshell.api.run("geometry.assign_representation", self.file, product=walltype, representation=rep)
wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=wall, relating_type=walltype) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[wall], relating_type=walltype)
ifcopenshell.api.run("geometry.assign_representation", self.file, product=wall, representation=rep2) ifcopenshell.api.run("geometry.assign_representation", self.file, product=wall, representation=rep2)
assert wall.Representation.Representations[0].RepresentationType == "MappedRepresentation" assert wall.Representation.Representations[0].RepresentationType == "MappedRepresentation"
@@ -84,7 +84,7 @@ class TestAssignRepresentation(test.bootstrap.IFC4):
rep = self.file.createIfcShapeRepresentation(ContextOfItems=context) rep = self.file.createIfcShapeRepresentation(ContextOfItems=context)
walltype = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") walltype = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=wall, relating_type=walltype) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[wall], relating_type=walltype)
ifcopenshell.api.run("geometry.assign_representation", self.file, product=wall, representation=rep) ifcopenshell.api.run("geometry.assign_representation", self.file, product=wall, representation=rep)
assert wall.Representation.Representations[0].RepresentationType != "MappedRepresentation" assert wall.Representation.Representations[0].RepresentationType != "MappedRepresentation"
assert wall.Representation.Representations[0] == rep assert wall.Representation.Representations[0] == rep
@@ -48,7 +48,7 @@ class TestAssignMaterial(test.bootstrap.IFC4):
def test_assign_type_material_layer_set_and_element_layer_set_usage(self): def test_assign_type_material_layer_set_and_element_layer_set_usage(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file, name="CON01") material = ifcopenshell.api.run("material.add_material", self.file, name="CON01")
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialLayerSet") ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialLayerSet")
ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialLayerSetUsage") ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialLayerSetUsage")
@@ -69,7 +69,7 @@ class TestAssignMaterial(test.bootstrap.IFC4):
def test_assign_type_material_profile_set_and_element_profile_set_usage(self): def test_assign_type_material_profile_set_and_element_profile_set_usage(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file, name="CON01") material = ifcopenshell.api.run("material.add_material", self.file, name="CON01")
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialProfileSet") ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialProfileSet")
ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialProfileSetUsage") ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialProfileSetUsage")
@@ -62,7 +62,7 @@ class TestUnassignMaterial(test.bootstrap.IFC4):
def test_unassign_material_layer_set_usage_from_element(self): def test_unassign_material_layer_set_usage_from_element(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file, name="CON01") material = ifcopenshell.api.run("material.add_material", self.file, name="CON01")
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialLayerSet") ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialLayerSet")
ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialLayerSetUsage") ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialLayerSetUsage")
@@ -78,8 +78,8 @@ class TestUnassignMaterial(test.bootstrap.IFC4):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("type.assign_type", self.file, related_object=element2, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element2], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file, name="CON01") material = ifcopenshell.api.run("material.add_material", self.file, name="CON01")
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialLayerSet") ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialLayerSet")
rel = ifcopenshell.api.run( rel = ifcopenshell.api.run(
@@ -114,7 +114,7 @@ class TestUnassignMaterial(test.bootstrap.IFC4):
def test_unassign_material_profile_set_usage_from_element(self): def test_unassign_material_profile_set_usage_from_element(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file, name="CON01") material = ifcopenshell.api.run("material.add_material", self.file, name="CON01")
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialProfileSet") ifcopenshell.api.run("material.assign_material", self.file, product=element_type, type="IfcMaterialProfileSet")
ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialProfileSetUsage") ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialProfileSetUsage")
@@ -88,7 +88,7 @@ class TestAppendAsset(test.bootstrap.IFC4):
element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType")
element_type2 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") element_type2 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", library, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", library, name="Material") material = ifcopenshell.api.run("material.add_material", library, name="Material")
ifcopenshell.api.run("material.assign_material", library, product=element, material=material) ifcopenshell.api.run("material.assign_material", library, product=element, material=material)
ifcopenshell.api.run("material.assign_material", library, product=element_type, material=material) ifcopenshell.api.run("material.assign_material", library, product=element_type, material=material)
@@ -186,7 +186,7 @@ class TestAppendAsset(test.bootstrap.IFC4):
element_type.RepresentationMaps = [library.createIfcRepresentationMap(MappedRepresentation=mapped_rep)] element_type.RepresentationMaps = [library.createIfcRepresentationMap(MappedRepresentation=mapped_rep)]
element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", library, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element) ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element)
assert len(self.file.by_type("IfcStyledItem")) == 1 assert len(self.file.by_type("IfcStyledItem")) == 1
@@ -356,7 +356,7 @@ class TestAppendAsset(test.bootstrap.IFC4):
library = ifcopenshell.api.run("project.create_file") library = ifcopenshell.api.run("project.create_file")
element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", library, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element) ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element)
assert ifcopenshell.util.element.get_type(self.file.by_type("IfcWall")[0]).is_a("IfcWallType") assert ifcopenshell.util.element.get_type(self.file.by_type("IfcWall")[0]).is_a("IfcWallType")
@@ -366,9 +366,9 @@ class TestAppendAsset(test.bootstrap.IFC4):
element2 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element2 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
element3 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element3 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", library, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("type.assign_type", library, related_object=element2, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element2], relating_type=element_type)
ifcopenshell.api.run("type.assign_type", library, related_object=element3, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element3], relating_type=element_type)
ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element) ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element)
ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element2) ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element2)
assert len(ifcopenshell.util.element.get_types(self.file.by_type("IfcWallType")[0])) == 2 assert len(ifcopenshell.util.element.get_types(self.file.by_type("IfcWallType")[0])) == 2
@@ -387,7 +387,7 @@ class TestAppendAsset(test.bootstrap.IFC4):
element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType")
element_type2 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") element_type2 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", library, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", library, name="Material") material = ifcopenshell.api.run("material.add_material", library, name="Material")
ifcopenshell.api.run("material.assign_material", library, product=element, material=material) ifcopenshell.api.run("material.assign_material", library, product=element, material=material)
ifcopenshell.api.run("material.assign_material", library, product=element_type, material=material) ifcopenshell.api.run("material.assign_material", library, product=element_type, material=material)
@@ -419,7 +419,7 @@ class TestAppendAssetIFC2X3(test.bootstrap.IFC2X3):
library = ifcopenshell.api.run("project.create_file", version="IFC2X3") library = ifcopenshell.api.run("project.create_file", version="IFC2X3")
element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", library, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element) ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element)
assert ifcopenshell.util.element.get_type(self.file.by_type("IfcWall")[0]).is_a("IfcWallType") assert ifcopenshell.util.element.get_type(self.file.by_type("IfcWall")[0]).is_a("IfcWallType")
@@ -429,9 +429,9 @@ class TestAppendAssetIFC2X3(test.bootstrap.IFC2X3):
element2 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element2 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
element3 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall") element3 = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", library, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", library, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("type.assign_type", library, related_object=element2, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element2], relating_type=element_type)
ifcopenshell.api.run("type.assign_type", library, related_object=element3, relating_type=element_type) ifcopenshell.api.run("type.assign_type", library, related_objects=[element3], relating_type=element_type)
ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element) ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element)
ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element2) ifcopenshell.api.run("project.append_asset", self.file, library=library, element=element2)
assert len(ifcopenshell.util.element.get_types(self.file.by_type("IfcWallType")[0])) == 2 assert len(ifcopenshell.util.element.get_types(self.file.by_type("IfcWallType")[0])) == 2
@@ -210,7 +210,7 @@ class TestCopyClass(test.bootstrap.IFC4):
def test_copying_a_type_and_purging_type_relationships(self): def test_copying_a_type_and_purging_type_relationships(self):
type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=type)
new = ifcopenshell.api.run("root.copy_class", self.file, product=type) new = ifcopenshell.api.run("root.copy_class", self.file, product=type)
assert not new.Types assert not new.Types
@@ -54,9 +54,9 @@ class TestReassignClass(test.bootstrap.IFC4):
def test_reassign_class_for_type_occurrences(self): def test_reassign_class_for_type_occurrences(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element1, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element1], relating_type=element_type)
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element2, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element2], relating_type=element_type)
element_type = ifcopenshell.api.run( element_type = ifcopenshell.api.run(
"root.reassign_class", self.file, product=element_type, ifc_class="IfcSlabType" "root.reassign_class", self.file, product=element_type, ifc_class="IfcSlabType"
@@ -74,9 +74,9 @@ class TestReassignClass(test.bootstrap.IFC4):
def test_reassigning_type_class_and_its_occurrences_classes_if_entity_was_typed(self): def test_reassigning_type_class_and_its_occurrences_classes_if_entity_was_typed(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element1, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element1], relating_type=element_type)
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element2, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element2], relating_type=element_type)
element1 = ifcopenshell.api.run("root.reassign_class", self.file, product=element1, ifc_class="IfcSlab") element1 = ifcopenshell.api.run("root.reassign_class", self.file, product=element1, ifc_class="IfcSlab")
@@ -98,7 +98,7 @@ class TestRemoveProduct(test.bootstrap.IFC4):
context = ifcopenshell.api.run("context.add_context", self.file, context_type="Model") context = ifcopenshell.api.run("context.add_context", self.file, context_type="Model")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
rep_map = self.file.createIfcRepresentationMap( rep_map = self.file.createIfcRepresentationMap(
MappingOrigin=self.file.createIfcAxis2Placement3D(), MappingOrigin=self.file.createIfcAxis2Placement3D(),
MappedRepresentation=self.file.createIfcShapeRepresentation( MappedRepresentation=self.file.createIfcShapeRepresentation(
@@ -377,7 +377,7 @@ class TestRemoveProduct(test.bootstrap.IFC4):
def test_removing_all_type_relationships_of_an_element(self): def test_removing_all_type_relationships_of_an_element(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("root.remove_product", self.file, product=element) ifcopenshell.api.run("root.remove_product", self.file, product=element)
assert not self.file.by_type("IfcRelDefinesByType") assert not self.file.by_type("IfcRelDefinesByType")
assert self.file.by_type("IfcWallType") assert self.file.by_type("IfcWallType")
@@ -386,8 +386,8 @@ class TestRemoveProduct(test.bootstrap.IFC4):
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element1, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element1], relating_type=element_type)
ifcopenshell.api.run("type.assign_type", self.file, related_object=element2, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element2], relating_type=element_type)
ifcopenshell.api.run("root.remove_product", self.file, product=element_type) ifcopenshell.api.run("root.remove_product", self.file, product=element_type)
assert not self.file.by_type("IfcRelDefinesByType") assert not self.file.by_type("IfcRelDefinesByType")
assert self.file.by_type("IfcWall") assert self.file.by_type("IfcWall")
@@ -123,3 +123,11 @@ class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4):
ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element) ifcopenshell.api.run("nest.assign_object", self.file, related_objects=[subelement1], relating_object=element)
ifcopenshell.api.run("nest.unassign_object", self.file, related_object=subelement1) ifcopenshell.api.run("nest.unassign_object", self.file, related_object=subelement1)
assert ifcopenshell.util.element.get_nest(subelement1) is None assert ifcopenshell.util.element.get_nest(subelement1) is None
@deprecation_check
def test_assigning_a_type(self):
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
rel = ifcopenshell.api.run("type.assign_type", self.file, related_object=element1, relating_type=element_type)
assert ifcopenshell.util.element.get_type(element1) == element_type
assert rel.is_a("IfcRelDefinesByType")
@@ -0,0 +1,70 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.element
import pytest
class TestAssignType(test.bootstrap.IFC4):
def test_assigning_a_type(self):
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
rel = ifcopenshell.api.run(
"type.assign_type", self.file, related_objects=[element1, element2], relating_type=element_type
)
assert ifcopenshell.util.element.get_type(element1) == element_type
assert ifcopenshell.util.element.get_type(element2) == element_type
assert rel.is_a("IfcRelDefinesByType")
def test_doing_nothing_if_type_is_already_assigned(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
total_elements = len([e for e in self.file])
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
assert len([e for e in self.file]) == total_elements
def test_that_old_typing_relationships_are_updated_if_they_still_have_elements(self):
element_type1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element_type2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"type.assign_type", self.file, related_objects=[element1, element2], relating_type=element_type1
)
rel = element1.IsDefinedBy[0] if self.file.schema == "IFC2X3" else element1.IsTypedBy[0]
assert len(rel.RelatedObjects) == 2
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element1], relating_type=element_type2)
assert len(rel.RelatedObjects) == 1
def test_that_old_typing_relationships_are_purged_if_no_more_elements_are_nested(self):
element_type1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element_type2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element1], relating_type=element_type1)
rel_id = (element1.IsDefinedBy[0] if self.file.schema == "IFC2X3" else element1.IsTypedBy[0]).id()
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element1], relating_type=element_type2)
with pytest.raises(RuntimeError):
self.file.by_id(rel_id)
class TestAssignTypeIFC2X3(test.bootstrap.IFC2X3, TestAssignType):
pass
@@ -24,7 +24,7 @@ class TestMapTypeRepresentations(test.bootstrap.IFC4):
def test_doing_nothing_if_the_type_has_no_representation_maps(self): def test_doing_nothing_if_the_type_has_no_representation_maps(self):
element = self.file.createIfcWall() element = self.file.createIfcWall()
type = self.file.createIfcWallType() type = self.file.createIfcWallType()
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=type)
total_elements = len([e for e in self.file]) total_elements = len([e for e in self.file])
ifcopenshell.api.run("type.map_type_representations", self.file, related_object=element, relating_type=type) ifcopenshell.api.run("type.map_type_representations", self.file, related_object=element, relating_type=type)
assert len([e for e in self.file]) == total_elements assert len([e for e in self.file]) == total_elements
@@ -36,5 +36,5 @@ class TestGetBrickTypeIFC2X3(test.bootstrap.IFC2X3):
def test_run(self): def test_run(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcFlowController") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcFlowController")
type_element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcAirTerminalBoxType") type_element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcAirTerminalBoxType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=type_element) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=type_element)
assert subject.get_brick_type(element) == "https://brickschema.org/schema/Brick#TerminalUnit" assert subject.get_brick_type(element) == "https://brickschema.org/schema/Brick#TerminalUnit"
@@ -69,7 +69,7 @@ class TestGetReferences(test.bootstrap.IFC4):
project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("classification.add_classification", self.file, classification=classification) ifcopenshell.api.run("classification.add_classification", self.file, classification=classification)
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
@@ -98,7 +98,7 @@ class TestGetReferences(test.bootstrap.IFC4):
project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") project = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
ifcopenshell.api.run("classification.add_classification", self.file, classification=classification) ifcopenshell.api.run("classification.add_classification", self.file, classification=classification)
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", "classification.add_reference",
@@ -55,7 +55,7 @@ class TestGetPsetIFC4(test.bootstrap.IFC4):
def test_getting_inherited_psets(self): def test_getting_inherited_psets(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
type_element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") type_element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=type_element) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=type_element)
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=type_element, name="name") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=type_element, name="name")
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"a": 1, "x": 1}) ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"a": 1, "x": 1})
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name")
@@ -79,7 +79,7 @@ class TestGetPsetIFC4(test.bootstrap.IFC4):
def test_excluding_inherited_psets(self): def test_excluding_inherited_psets(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
type_element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") type_element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=type_element) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=type_element)
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=type_element, name="name") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=type_element, name="name")
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"a": 1, "x": 1}) ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"a": 1, "x": 1})
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name")
@@ -133,7 +133,7 @@ class TestGetPsetsIFC4(test.bootstrap.IFC4):
def test_getting_inherited_psets(self): def test_getting_inherited_psets(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
type_element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") type_element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=type_element) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=type_element)
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=type_element, name="name") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=type_element, name="name")
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"a": 1, "x": 1}) ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"a": 1, "x": 1})
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name")
@@ -263,14 +263,14 @@ class TestGetPredefinedTypeIFC4(test.bootstrap.IFC4):
def test_getting_an_inherited_predefined_type(self): def test_getting_an_inherited_predefined_type(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
element_type.PredefinedType = "PARTITIONING" element_type.PredefinedType = "PARTITIONING"
assert subject.get_predefined_type(element) == "PARTITIONING" assert subject.get_predefined_type(element) == "PARTITIONING"
def test_getting_an_inherited_userdefined_type_for_an_element_type(self): def test_getting_an_inherited_userdefined_type_for_an_element_type(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
element_type.PredefinedType = "USERDEFINED" element_type.PredefinedType = "USERDEFINED"
element_type.ElementType = "FOOBAR" element_type.ElementType = "FOOBAR"
assert subject.get_predefined_type(element) == "FOOBAR" assert subject.get_predefined_type(element) == "FOOBAR"
@@ -278,7 +278,7 @@ class TestGetPredefinedTypeIFC4(test.bootstrap.IFC4):
def test_getting_an_overriden_predefined_type(self): def test_getting_an_overriden_predefined_type(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
element_type.PredefinedType = "NOTDEFINED" element_type.PredefinedType = "NOTDEFINED"
element.PredefinedType = "PARTITIONING" element.PredefinedType = "PARTITIONING"
assert subject.get_predefined_type(element) == "PARTITIONING" assert subject.get_predefined_type(element) == "PARTITIONING"
@@ -286,7 +286,7 @@ class TestGetPredefinedTypeIFC4(test.bootstrap.IFC4):
def test_getting_an_inherited_userdefined_type_for_a_process_type(self): def test_getting_an_inherited_userdefined_type_for_a_process_type(self):
element = ifcopenshell.api.run("sequence.add_task", self.file) element = ifcopenshell.api.run("sequence.add_task", self.file)
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTaskType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcTaskType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
element_type.PredefinedType = "USERDEFINED" element_type.PredefinedType = "USERDEFINED"
element_type.ProcessType = "FOOBAR" element_type.ProcessType = "FOOBAR"
assert subject.get_predefined_type(element) == "FOOBAR" assert subject.get_predefined_type(element) == "FOOBAR"
@@ -296,7 +296,7 @@ class TestGetTypeIFC4(test.bootstrap.IFC4):
def test_getting_the_type_of_a_product(self): def test_getting_the_type_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
assert subject.get_type(element) == element_type assert subject.get_type(element) == element_type
assert subject.get_type(element_type) == element_type assert subject.get_type(element_type) == element_type
@@ -309,7 +309,7 @@ class TestGetTypes(test.bootstrap.IFC4):
def test_getting_the_type_of_a_product(self): def test_getting_the_type_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
assert subject.get_types(element_type) == (element,) assert subject.get_types(element_type) == (element,)
@@ -391,7 +391,7 @@ class TestGetMaterial(test.bootstrap.IFC4):
def test_getting_an_inherited_material_from_the_elements_type(self): def test_getting_an_inherited_material_from_the_elements_type(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file) material = ifcopenshell.api.run("material.add_material", self.file)
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material) ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material)
assert subject.get_material(element) == material assert subject.get_material(element) == material
@@ -399,7 +399,7 @@ class TestGetMaterial(test.bootstrap.IFC4):
def test_getting_an_overridden_material_from_the_elements_occurrence(self): def test_getting_an_overridden_material_from_the_elements_occurrence(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file) material = ifcopenshell.api.run("material.add_material", self.file)
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material) ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material)
material = ifcopenshell.api.run("material.add_material", self.file) material = ifcopenshell.api.run("material.add_material", self.file)
@@ -409,7 +409,7 @@ class TestGetMaterial(test.bootstrap.IFC4):
def test_getting_direct_materials_without_checking_inheritance(self): def test_getting_direct_materials_without_checking_inheritance(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file) material = ifcopenshell.api.run("material.add_material", self.file)
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material) ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material)
assert subject.get_material(element, should_inherit=False) is None assert subject.get_material(element, should_inherit=False) is None
@@ -493,7 +493,7 @@ class TestGetElementsByMaterial(test.bootstrap.IFC4):
def test_getting_elements_of_a_material_layer_set(self): def test_getting_elements_of_a_material_layer_set(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file) material = ifcopenshell.api.run("material.add_material", self.file)
material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialLayerSet") material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialLayerSet")
ifcopenshell.api.run("material.add_layer", self.file, layer_set=material_set, material=material) ifcopenshell.api.run("material.add_layer", self.file, layer_set=material_set, material=material)
@@ -507,7 +507,7 @@ class TestGetElementsByMaterial(test.bootstrap.IFC4):
def test_getting_elements_of_a_material_profile_set(self): def test_getting_elements_of_a_material_profile_set(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", self.file) material = ifcopenshell.api.run("material.add_material", self.file)
material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialProfileSet") material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialProfileSet")
ifcopenshell.api.run("material.add_profile", self.file, profile_set=material_set, material=material) ifcopenshell.api.run("material.add_profile", self.file, profile_set=material_set, material=material)
@@ -168,7 +168,7 @@ class TestFilterElements(test.bootstrap.IFC4):
def test_selecting_by_type(self): def test_selecting_by_type(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
assert subject.filter_elements(self.file, "IfcWall, type=Foo") == set() assert subject.filter_elements(self.file, "IfcWall, type=Foo") == set()
element_type.Name = "Foo" element_type.Name = "Foo"
assert subject.filter_elements(self.file, "IfcWall, type=Foo") == {element} assert subject.filter_elements(self.file, "IfcWall, type=Foo") == {element}
@@ -465,10 +465,10 @@ class TestSelector(test.bootstrap.IFC4):
def test_getting_occurrences_of_a_filtered_type(self): def test_getting_occurrences_of_a_filtered_type(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element2, relating_type=element_type2) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element2], relating_type=element_type2)
assert set(subject.Selector.parse(self.file, "* .IfcWallType")) == {element, element2} assert set(subject.Selector.parse(self.file, "* .IfcWallType")) == {element, element2}
def test_getting_decomposition_of_a_filtered_type(self): def test_getting_decomposition_of_a_filtered_type(self):
@@ -505,7 +505,7 @@ class TestSelector(test.bootstrap.IFC4):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element_type.Name = "Foo" element_type.Name = "Foo"
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=element_type)
assert set(subject.Selector.parse(self.file, '.IfcWall[type.Name="Foo"]')) == {element} assert set(subject.Selector.parse(self.file, '.IfcWall[type.Name="Foo"]')) == {element}
def test_selecting_via_a_material(self): def test_selecting_via_a_material(self):
+1 -1
View File
@@ -328,7 +328,7 @@ wall_types = []
for i in range(0, 4): for i in range(0, 4):
wall_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWallType", name=f"DEMO{i + 1}") wall_type = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWallType", name=f"DEMO{i + 1}")
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall", name=f"WALL {i + 1}") wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall", name=f"WALL {i + 1}")
ifcopenshell.api.run("type.assign_type", model, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", model, related_objects=[wall], relating_type=wall_type)
representation = ifcopenshell.api.run( representation = ifcopenshell.api.run(
"geometry.add_wall_representation", model, context=body, length=5, height=3, thickness=(i + 1) * 0.05 "geometry.add_wall_representation", model, context=body, length=5, height=3, thickness=(i + 1) * 0.05
) )
+8 -8
View File
@@ -168,7 +168,7 @@ class TestEntity:
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="X") wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="X")
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
facet = Entity(name="IFCWALL", predefinedType="X") facet = Entity(name="IFCWALL", predefinedType="X")
run("Inherited predefined types should pass", facet=facet, inst=wall, expected=True) run("Inherited predefined types should pass", facet=facet, inst=wall, expected=True)
@@ -177,7 +177,7 @@ class TestEntity:
wall_type = ifcopenshell.api.run( wall_type = ifcopenshell.api.run(
"root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="NOTDEFINED" "root.create_entity", ifc, ifc_class="IfcWallType", predefined_type="NOTDEFINED"
) )
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
facet = Entity(name="IFCWALL", predefinedType="X") facet = Entity(name="IFCWALL", predefinedType="X")
run("Overridden predefined types should pass", facet=facet, inst=wall, expected=True) run("Overridden predefined types should pass", facet=facet, inst=wall, expected=True)
@@ -637,7 +637,7 @@ class TestAttribute:
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
wall_type.Description = "Foobar" wall_type.Description = "Foobar"
facet = Attribute(name="Description", value="Foobar") facet = Attribute(name="Description", value="Foobar")
run("Attributes are not inherited by the occurrence", facet=facet, inst=wall, expected=False) run("Attributes are not inherited by the occurrence", facet=facet, inst=wall, expected=False)
@@ -808,7 +808,7 @@ class TestClassification:
# https://github.com/buildingSMART/IFC4.3.x-development/issues/475 # https://github.com/buildingSMART/IFC4.3.x-development/issues/475
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
ifcopenshell.api.run( ifcopenshell.api.run(
"classification.add_reference", ifc, product=wall, reference=ref11, classification=system_a "classification.add_reference", ifc, product=wall, reference=ref11, classification=system_a
) )
@@ -1209,7 +1209,7 @@ class TestProperty:
ifc = self.setup_ifc() ifc = self.setup_ifc()
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall_type, name="Foo_Bar") pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall_type, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"}) ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL") facet = Property(propertySet="Foo_Bar", baseName="Foo", dataType="IFCLABEL")
@@ -1219,7 +1219,7 @@ class TestProperty:
ifc = self.setup_ifc() ifc = self.setup_ifc()
wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") wall = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") wall_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[wall], relating_type=wall_type)
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall_type, name="Foo_Bar") pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall_type, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Baz"}) ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Baz"})
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall, name="Foo_Bar") pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall, name="Foo_Bar")
@@ -1374,7 +1374,7 @@ class TestMaterial:
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", ifc, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", ifc) material = ifcopenshell.api.run("material.add_material", ifc)
ifcopenshell.api.run("material.assign_material", ifc, product=element_type, material=material) ifcopenshell.api.run("material.assign_material", ifc, product=element_type, material=material)
material.Name = "Foo" material.Name = "Foo"
@@ -1384,7 +1384,7 @@ class TestMaterial:
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", ifc, related_object=element, relating_type=element_type) ifcopenshell.api.run("type.assign_type", ifc, related_objects=[element], relating_type=element_type)
material = ifcopenshell.api.run("material.add_material", ifc) material = ifcopenshell.api.run("material.add_material", ifc)
ifcopenshell.api.run("material.assign_material", ifc, product=element_type, material=material) ifcopenshell.api.run("material.assign_material", ifc, product=element_type, material=material)
material.Name = "Bar" material.Name = "Bar"