mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 16:19:55 +00:00
Copying parametric geometry from any source now attempts to preserve parametric geometry when possible.
This commit is contained in:
@@ -212,7 +212,10 @@ class UpdateRepresentation(bpy.types.Operator):
|
|||||||
}
|
}
|
||||||
|
|
||||||
if not self.ifc_representation_class:
|
if not self.ifc_representation_class:
|
||||||
self.auto_detect_ifc_representation_class(product, old_representation, representation_data)
|
representation_data["ifc_representation_class"] = tool.Geometry.get_ifc_representation_class(
|
||||||
|
product, old_representation
|
||||||
|
)
|
||||||
|
representation_data["profile_set_usage"] = tool.Geometry.get_profile_set_usage(product)
|
||||||
|
|
||||||
new_representation = ifcopenshell.api.run("geometry.add_representation", self.file, **representation_data)
|
new_representation = ifcopenshell.api.run("geometry.add_representation", self.file, **representation_data)
|
||||||
|
|
||||||
@@ -248,28 +251,6 @@ class UpdateRepresentation(bpy.types.Operator):
|
|||||||
if obj.data.BIMMeshProperties.ifc_parameters:
|
if obj.data.BIMMeshProperties.ifc_parameters:
|
||||||
bpy.ops.bim.get_representation_ifc_parameters()
|
bpy.ops.bim.get_representation_ifc_parameters()
|
||||||
|
|
||||||
def auto_detect_ifc_representation_class(self, element, representation, data):
|
|
||||||
material = ifcopenshell.util.element.get_material(element)
|
|
||||||
|
|
||||||
if material and material.is_a("IfcMaterialProfileSetUsage"):
|
|
||||||
data["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcMaterialProfileSetUsage"
|
|
||||||
data["profile_set_usage"] = material
|
|
||||||
return
|
|
||||||
|
|
||||||
extruded_areas = [e for e in self.file.traverse(representation) if e.is_a() == "IfcExtrudedAreaSolid"]
|
|
||||||
|
|
||||||
if len(extruded_areas) != 1:
|
|
||||||
return # It's too complex for us to derive topologically right now
|
|
||||||
|
|
||||||
profile_def = extruded_areas[0].SweptArea
|
|
||||||
|
|
||||||
if profile_def.is_a() == "IfcRectangleProfileDef":
|
|
||||||
data["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcRectangleProfileDef"
|
|
||||||
elif profile_def.is_a() == "IfcCircleProfileDef":
|
|
||||||
data["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcCircleProfileDef"
|
|
||||||
else:
|
|
||||||
data["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids"
|
|
||||||
|
|
||||||
|
|
||||||
class UpdateParametricRepresentation(bpy.types.Operator):
|
class UpdateParametricRepresentation(bpy.types.Operator):
|
||||||
bl_idname = "bim.update_parametric_representation"
|
bl_idname = "bim.update_parametric_representation"
|
||||||
@@ -337,7 +318,9 @@ class CopyRepresentation(bpy.types.Operator, Operator):
|
|||||||
return
|
return
|
||||||
bm = bmesh.new()
|
bm = bmesh.new()
|
||||||
bm.from_mesh(context.active_object.data)
|
bm.from_mesh(context.active_object.data)
|
||||||
geometric_context = tool.Root.get_object_context(context.active_object)
|
geometric_context = tool.Root.get_representation_context(
|
||||||
|
tool.Root.get_object_representation(context.active_object)
|
||||||
|
)
|
||||||
for obj in context.selected_objects:
|
for obj in context.selected_objects:
|
||||||
if obj == context.active_object:
|
if obj == context.active_object:
|
||||||
continue
|
continue
|
||||||
@@ -467,7 +450,7 @@ class OverrideDuplicateMove(bpy.types.Operator):
|
|||||||
obj.select_set(False)
|
obj.select_set(False)
|
||||||
new_obj.select_set(True)
|
new_obj.select_set(True)
|
||||||
# This is the only difference
|
# This is the only difference
|
||||||
blenderbim.core.root.copy_class(tool.Ifc, tool.Collector, tool.Root, obj=new_obj)
|
blenderbim.core.root.copy_class(tool.Ifc, tool.Collector, tool.Geometry, tool.Root, obj=new_obj)
|
||||||
bpy.ops.transform.translate("INVOKE_DEFAULT")
|
bpy.ops.transform.translate("INVOKE_DEFAULT")
|
||||||
blenderbim.bim.handler.purge_module_data()
|
blenderbim.bim.handler.purge_module_data()
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ class DumbWallSplitter:
|
|||||||
def duplicate_wall(self):
|
def duplicate_wall(self):
|
||||||
new = self.wall.copy()
|
new = self.wall.copy()
|
||||||
self.wall.users_collection[0].objects.link(new)
|
self.wall.users_collection[0].objects.link(new)
|
||||||
blenderbim.core.root.copy_class(tool.Ifc, tool.Collector, tool.Root, obj=new)
|
blenderbim.core.root.copy_class(tool.Ifc, tool.Collector, tool.Geometry, tool.Root, obj=new)
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def snap_end_face_to_point(self, wall, which_end):
|
def snap_end_face_to_point(self, wall, which_end):
|
||||||
|
|||||||
@@ -356,5 +356,5 @@ class CopyClass(bpy.types.Operator, Operator):
|
|||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
objects = [bpy.data.objects.get(self.obj)] if self.obj else context.selected_objects
|
objects = [bpy.data.objects.get(self.obj)] if self.obj else context.selected_objects
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
core.copy_class(tool.Ifc, tool.Collector, tool.Root, obj=obj)
|
core.copy_class(tool.Ifc, tool.Collector, tool.Geometry, tool.Root, obj=obj)
|
||||||
blenderbim.bim.handler.purge_module_data()
|
blenderbim.bim.handler.purge_module_data()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
def copy_class(ifc, collector, root, obj=None):
|
def copy_class(ifc, collector, geometry, root, obj=None):
|
||||||
element = ifc.get_entity(obj)
|
element = ifc.get_entity(obj)
|
||||||
if not element:
|
if not element:
|
||||||
return
|
return
|
||||||
@@ -27,7 +27,14 @@ def copy_class(ifc, collector, root, obj=None):
|
|||||||
if relating_type and root.does_type_have_representations(relating_type):
|
if relating_type and root.does_type_have_representations(relating_type):
|
||||||
ifc.run("type.map_type_representations", related_object=element, relating_type=relating_type)
|
ifc.run("type.map_type_representations", related_object=element, relating_type=relating_type)
|
||||||
else:
|
else:
|
||||||
root.run_geometry_add_representation(obj=obj, context=root.get_object_context(obj))
|
representation = root.get_object_representation(obj)
|
||||||
|
if representation:
|
||||||
|
root.run_geometry_add_representation(
|
||||||
|
obj=obj,
|
||||||
|
context=root.get_representation_context(representation),
|
||||||
|
ifc_representation_class=geometry.get_ifc_representation_class(element, representation),
|
||||||
|
profile_set_usage=geometry.get_profile_set_usage(element),
|
||||||
|
)
|
||||||
collector.assign(obj)
|
collector.assign(obj)
|
||||||
if root.is_opening_element(element):
|
if root.is_opening_element(element):
|
||||||
root.add_dynamic_opening_voids(element, obj)
|
root.add_dynamic_opening_voids(element, obj)
|
||||||
|
|||||||
@@ -63,8 +63,10 @@ class Geometry:
|
|||||||
def does_object_have_mesh_with_faces(cls, obj): pass
|
def does_object_have_mesh_with_faces(cls, obj): pass
|
||||||
def duplicate_object_data(cls, obj): pass
|
def duplicate_object_data(cls, obj): pass
|
||||||
def get_cartesian_point_coordinate_offset(cls, obj): pass
|
def get_cartesian_point_coordinate_offset(cls, obj): pass
|
||||||
|
def get_ifc_representation_class(cls, element, representation): pass
|
||||||
def get_object_data(cls, obj): pass
|
def get_object_data(cls, obj): pass
|
||||||
def get_object_materials_without_styles(cls, obj): pass
|
def get_object_materials_without_styles(cls, obj): pass
|
||||||
|
def get_profile_set_usage(cls, element): pass
|
||||||
def get_representation_data(cls, representation): pass
|
def get_representation_data(cls, representation): pass
|
||||||
def get_representation_name(cls, representation): pass
|
def get_representation_name(cls, representation): pass
|
||||||
def get_total_representation_items(cls, obj): pass
|
def get_total_representation_items(cls, obj): pass
|
||||||
@@ -148,9 +150,10 @@ class Root:
|
|||||||
def add_dynamic_opening_voids(cls, element, obj): pass
|
def add_dynamic_opening_voids(cls, element, obj): pass
|
||||||
def does_type_have_representations(cls, element): pass
|
def does_type_have_representations(cls, element): pass
|
||||||
def get_element_type(cls, element): pass
|
def get_element_type(cls, element): pass
|
||||||
def get_object_context(cls, obj): pass
|
def get_object_representation(cls, obj): pass
|
||||||
|
def get_representation_context(cls, representation): pass
|
||||||
def is_opening_element(cls, element): pass
|
def is_opening_element(cls, element): pass
|
||||||
def run_geometry_add_representation(cls, obj=None, context=None): pass
|
def run_geometry_add_representation(cls, obj=None, context=None, ifc_representation_class=None, profile_set_usage=None): pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
|
|||||||
@@ -61,24 +61,6 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
obj.data = obj.data.copy()
|
obj.data = obj.data.copy()
|
||||||
return obj.data
|
return obj.data
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_object_data(cls, obj):
|
|
||||||
return obj.data
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_object_materials_without_styles(cls, obj):
|
|
||||||
return [
|
|
||||||
s.material for s in obj.material_slots if s.material and not s.material.BIMMaterialProperties.ifc_style_id
|
|
||||||
]
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_representation_data(cls, representation):
|
|
||||||
return bpy.data.meshes.get(cls.get_representation_name(representation))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_representation_name(cls, representation):
|
|
||||||
return f"{representation.ContextOfItems.id()}/{representation.id()}"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_cartesian_point_coordinate_offset(cls, obj):
|
def get_cartesian_point_coordinate_offset(cls, obj):
|
||||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||||
@@ -91,6 +73,50 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_ifc_representation_class(cls, element, representation):
|
||||||
|
material = ifcopenshell.util.element.get_material(element)
|
||||||
|
if material and material.is_a("IfcMaterialProfileSetUsage"):
|
||||||
|
return "IfcExtrudedAreaSolid/IfcMaterialProfileSetUsage"
|
||||||
|
|
||||||
|
extruded_areas = [e for e in tool.Ifc.get().traverse(representation) if e.is_a() == "IfcExtrudedAreaSolid"]
|
||||||
|
|
||||||
|
if len(extruded_areas) != 1:
|
||||||
|
return # It's too complex for us to derive topologically right now
|
||||||
|
|
||||||
|
profile_def = extruded_areas[0].SweptArea
|
||||||
|
|
||||||
|
if profile_def.is_a() == "IfcRectangleProfileDef":
|
||||||
|
return "IfcExtrudedAreaSolid/IfcRectangleProfileDef"
|
||||||
|
elif profile_def.is_a() == "IfcCircleProfileDef":
|
||||||
|
return "IfcExtrudedAreaSolid/IfcCircleProfileDef"
|
||||||
|
return "IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_object_data(cls, obj):
|
||||||
|
return obj.data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_object_materials_without_styles(cls, obj):
|
||||||
|
return [
|
||||||
|
s.material for s in obj.material_slots if s.material and not s.material.BIMMaterialProperties.ifc_style_id
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_profile_set_usage(cls, element):
|
||||||
|
material = ifcopenshell.util.element.get_material(element)
|
||||||
|
if material:
|
||||||
|
if material.is_a("IfcMaterialProfileSetUsage"):
|
||||||
|
return material
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_representation_data(cls, representation):
|
||||||
|
return bpy.data.meshes.get(cls.get_representation_name(representation))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_representation_name(cls, representation):
|
||||||
|
return f"{representation.ContextOfItems.id()}/{representation.id()}"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_total_representation_items(cls, obj):
|
def get_total_representation_items(cls, obj):
|
||||||
return max(1, len(obj.material_slots))
|
return max(1, len(obj.material_slots))
|
||||||
|
|||||||
@@ -49,16 +49,29 @@ class Root(blenderbim.core.tool.Root):
|
|||||||
return ifcopenshell.util.element.get_type(element)
|
return ifcopenshell.util.element.get_type(element)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_object_context(cls, obj):
|
def get_object_representation(cls, obj):
|
||||||
if obj.data and obj.data.BIMMeshProperties.ifc_definition_id:
|
if obj.data and obj.data.BIMMeshProperties.ifc_definition_id:
|
||||||
return tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id).ContextOfItems
|
return tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_representation_context(cls, representation):
|
||||||
|
return representation.ContextOfItems
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_opening_element(cls, element):
|
def is_opening_element(cls, element):
|
||||||
return element.is_a("IfcOpeningElement")
|
return element.is_a("IfcOpeningElement")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run_geometry_add_representation(cls, obj=None, context=None):
|
def run_geometry_add_representation(
|
||||||
|
cls, obj=None, context=None, ifc_representation_class=None, profile_set_usage=None
|
||||||
|
):
|
||||||
return blenderbim.core.geometry.add_representation(
|
return blenderbim.core.geometry.add_representation(
|
||||||
tool.Ifc, tool.Geometry, tool.Style, tool.Surveyor, obj=obj, context=context
|
tool.Ifc,
|
||||||
|
tool.Geometry,
|
||||||
|
tool.Style,
|
||||||
|
tool.Surveyor,
|
||||||
|
obj=obj,
|
||||||
|
context=context,
|
||||||
|
ifc_representation_class=ifc_representation_class,
|
||||||
|
profile_set_usage=profile_set_usage,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run_root_copy_class(cls, obj=None):
|
def run_root_copy_class(cls, obj=None):
|
||||||
return blenderbim.core.root.copy_class(tool.Ifc, tool.Collector, tool.Root, obj=obj)
|
return blenderbim.core.root.copy_class(tool.Ifc, tool.Collector, tool.Geometry, tool.Root, obj=obj)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run_spatial_assign_container(cls, structure_obj=None, element_obj=None):
|
def run_spatial_assign_container(cls, structure_obj=None, element_obj=None):
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Scenario: Switch representation - existing Blender modifiers must be purged
|
|||||||
And I press "bim.switch_representation(obj='IfcWall/Cube', ifc_definition_id={representation})"
|
And I press "bim.switch_representation(obj='IfcWall/Cube', ifc_definition_id={representation})"
|
||||||
Then the object "IfcWall/Cube" has no modifiers
|
Then the object "IfcWall/Cube" has no modifiers
|
||||||
|
|
||||||
Scenario: Update representation
|
Scenario: Update representation - updating a tessellation
|
||||||
Given an empty IFC project
|
Given an empty IFC project
|
||||||
And I add a cube
|
And I add a cube
|
||||||
And the object "Cube" is selected
|
And the object "Cube" is selected
|
||||||
@@ -53,6 +53,63 @@ Scenario: Update representation
|
|||||||
And I press "bim.update_representation(obj='IfcWall/Cube')"
|
And I press "bim.update_representation(obj='IfcWall/Cube')"
|
||||||
Then the object "IfcWall/Cube" has a "Tessellation" representation of "Model/Body/MODEL_VIEW"
|
Then the object "IfcWall/Cube" has a "Tessellation" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
|
Scenario: Update representation - updating a layered extrusion
|
||||||
|
Given an empty IFC project
|
||||||
|
And I add a cube
|
||||||
|
And the object "Cube" is selected
|
||||||
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||||
|
And I press "bim.assign_class"
|
||||||
|
And I add an empty
|
||||||
|
And the object "Empty" is selected
|
||||||
|
And I set "scene.BIMRootProperties.ifc_product" to "IfcElementType"
|
||||||
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||||
|
And I press "bim.assign_class"
|
||||||
|
And I press "bim.add_default_material"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.material_type" to "IfcMaterialLayerSet"
|
||||||
|
And I press "bim.assign_material"
|
||||||
|
And I press "bim.enable_editing_assigned_material"
|
||||||
|
And the variable "layer_set" is "{ifc}.by_type("IfcMaterialLayerSet")[0].id()"
|
||||||
|
And I press "bim.add_layer(layer_set={layer_set})"
|
||||||
|
And the variable "layer" is "{ifc}.by_type("IfcMaterialLayer")[0].id()"
|
||||||
|
And I press "bim.enable_editing_material_set_item(material_set_item={layer})"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.material_set_item_attributes[0].float_value" to "0.1"
|
||||||
|
And I press "bim.edit_material_set_item(material_set_item={layer})"
|
||||||
|
And I press "bim.edit_assigned_material(material_set={layer_set})"
|
||||||
|
And the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
|
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
|
When I press "bim.update_representation(obj='IfcWall/Cube')"
|
||||||
|
Then the object "IfcWall/Cube" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
|
Scenario: Update representation - updating a profiled extrusion
|
||||||
|
Given an empty IFC project
|
||||||
|
And I add a cube
|
||||||
|
And the object "Cube" is selected
|
||||||
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||||
|
And I press "bim.assign_class"
|
||||||
|
And I add an empty
|
||||||
|
And the object "Empty" is selected
|
||||||
|
And I set "scene.BIMRootProperties.ifc_product" to "IfcElementType"
|
||||||
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||||
|
And I press "bim.assign_class"
|
||||||
|
And I press "bim.add_default_material"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.material_type" to "IfcMaterialProfileSet"
|
||||||
|
And I press "bim.assign_material"
|
||||||
|
And I press "bim.enable_editing_assigned_material"
|
||||||
|
And the variable "profile_set" is "{ifc}.by_type("IfcMaterialProfileSet")[0].id()"
|
||||||
|
And I press "bim.add_profile(profile_set={profile_set})"
|
||||||
|
And the variable "profile" is "{ifc}.by_type("IfcMaterialProfile")[0].id()"
|
||||||
|
And I press "bim.enable_editing_material_set_item(material_set_item={profile})"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.profile_classes" to "IfcParameterizedProfileDef"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.parameterized_profile_classes" to "IfcCircleProfileDef"
|
||||||
|
And I press "bim.assign_parameterized_profile(ifc_class='IfcCircleProfileDef', material_profile={profile})"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.material_set_item_profile_attributes[2].float_value" to "0.2"
|
||||||
|
And I press "bim.edit_material_set_item(material_set_item={profile})"
|
||||||
|
And I press "bim.edit_assigned_material(material_set={profile_set})"
|
||||||
|
And the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
|
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
|
When I press "bim.update_representation(obj='IfcWall/Cube')"
|
||||||
|
Then the object "IfcWall/Cube" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
Scenario: Copy representation
|
Scenario: Copy representation
|
||||||
Given an empty IFC project
|
Given an empty IFC project
|
||||||
And I add a cube
|
And I add a cube
|
||||||
@@ -126,3 +183,64 @@ Scenario: Override duplicate move - copying a type instance with a representatio
|
|||||||
When I press "object.duplicate_move"
|
When I press "object.duplicate_move"
|
||||||
Then the object "IfcWall/Instance.001" exists
|
Then the object "IfcWall/Instance.001" exists
|
||||||
And the object "IfcWall/Instance.001" has a "MappedRepresentation" representation of "Model/Body/MODEL_VIEW"
|
And the object "IfcWall/Instance.001" has a "MappedRepresentation" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
|
Scenario: Override duplicate move - copying a layered extrusion
|
||||||
|
Given an empty IFC project
|
||||||
|
And I add a cube
|
||||||
|
And the object "Cube" is selected
|
||||||
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||||
|
And I press "bim.assign_class"
|
||||||
|
And I add an empty
|
||||||
|
And the object "Empty" is selected
|
||||||
|
And I set "scene.BIMRootProperties.ifc_product" to "IfcElementType"
|
||||||
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||||
|
And I press "bim.assign_class"
|
||||||
|
And I press "bim.add_default_material"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.material_type" to "IfcMaterialLayerSet"
|
||||||
|
And I press "bim.assign_material"
|
||||||
|
And I press "bim.enable_editing_assigned_material"
|
||||||
|
And the variable "layer_set" is "{ifc}.by_type("IfcMaterialLayerSet")[0].id()"
|
||||||
|
And I press "bim.add_layer(layer_set={layer_set})"
|
||||||
|
And the variable "layer" is "{ifc}.by_type("IfcMaterialLayer")[0].id()"
|
||||||
|
And I press "bim.enable_editing_material_set_item(material_set_item={layer})"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.material_set_item_attributes[0].float_value" to "0.1"
|
||||||
|
And I press "bim.edit_material_set_item(material_set_item={layer})"
|
||||||
|
And I press "bim.edit_assigned_material(material_set={layer_set})"
|
||||||
|
And the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
|
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
|
And the object "IfcWall/Cube" is selected
|
||||||
|
When I press "object.duplicate_move"
|
||||||
|
Then the object "IfcWall/Cube.001" exists
|
||||||
|
Then the object "IfcWall/Cube.001" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
|
Scenario: Override duplicate move - copying a profiled extrusion
|
||||||
|
Given an empty IFC project
|
||||||
|
And I add a cube
|
||||||
|
And the object "Cube" is selected
|
||||||
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||||
|
And I press "bim.assign_class"
|
||||||
|
And I add an empty
|
||||||
|
And the object "Empty" is selected
|
||||||
|
And I set "scene.BIMRootProperties.ifc_product" to "IfcElementType"
|
||||||
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||||
|
And I press "bim.assign_class"
|
||||||
|
And I press "bim.add_default_material"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.material_type" to "IfcMaterialProfileSet"
|
||||||
|
And I press "bim.assign_material"
|
||||||
|
And I press "bim.enable_editing_assigned_material"
|
||||||
|
And the variable "profile_set" is "{ifc}.by_type("IfcMaterialProfileSet")[0].id()"
|
||||||
|
And I press "bim.add_profile(profile_set={profile_set})"
|
||||||
|
And the variable "profile" is "{ifc}.by_type("IfcMaterialProfile")[0].id()"
|
||||||
|
And I press "bim.enable_editing_material_set_item(material_set_item={profile})"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.profile_classes" to "IfcParameterizedProfileDef"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.parameterized_profile_classes" to "IfcCircleProfileDef"
|
||||||
|
And I press "bim.assign_parameterized_profile(ifc_class='IfcCircleProfileDef', material_profile={profile})"
|
||||||
|
And I set "active_object.BIMObjectMaterialProperties.material_set_item_profile_attributes[2].float_value" to "0.2"
|
||||||
|
And I press "bim.edit_material_set_item(material_set_item={profile})"
|
||||||
|
And I press "bim.edit_assigned_material(material_set={profile_set})"
|
||||||
|
And the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
|
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
|
And the object "IfcWall/Cube" is selected
|
||||||
|
When I press "object.duplicate_move"
|
||||||
|
Then the object "IfcWall/Cube.001" exists
|
||||||
|
Then the object "IfcWall/Cube.001" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Scenario: Assign type - assign to an empty type
|
|||||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||||
And I press "bim.assign_class"
|
And I press "bim.assign_class"
|
||||||
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
And I press "bim.assign_type(relating_type={type}, related_object="IfcWall/Cube")"
|
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
Then the object "IfcWall/Cube" has a "Tessellation" representation of "Model/Body/MODEL_VIEW"
|
Then the object "IfcWall/Cube" has a "Tessellation" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
Scenario: Assign type - assign to a type with representation maps
|
Scenario: Assign type - assign to a type with representation maps
|
||||||
@@ -28,7 +28,7 @@ Scenario: Assign type - assign to a type with representation maps
|
|||||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||||
And I press "bim.assign_class"
|
And I press "bim.assign_class"
|
||||||
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
And I press "bim.assign_type(relating_type={type}, related_object="IfcWall/Cube")"
|
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
Then the object "IfcWall/Cube" has a "MappedRepresentation" representation of "Model/Body/MODEL_VIEW"
|
Then the object "IfcWall/Cube" has a "MappedRepresentation" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
Scenario: Assign type - assign to a type with a material layer set
|
Scenario: Assign type - assign to a type with a material layer set
|
||||||
@@ -54,7 +54,7 @@ Scenario: Assign type - assign to a type with a material layer set
|
|||||||
And I press "bim.edit_material_set_item(material_set_item={layer})"
|
And I press "bim.edit_material_set_item(material_set_item={layer})"
|
||||||
And I press "bim.edit_assigned_material(material_set={layer_set})"
|
And I press "bim.edit_assigned_material(material_set={layer_set})"
|
||||||
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
And I press "bim.assign_type(relating_type={type}, related_object="IfcWall/Cube")"
|
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
Then the object "IfcWall/Cube" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
Then the object "IfcWall/Cube" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
Scenario: Assign type - assign to a type with a material profile set
|
Scenario: Assign type - assign to a type with a material profile set
|
||||||
@@ -83,5 +83,5 @@ Scenario: Assign type - assign to a type with a material profile set
|
|||||||
And I press "bim.edit_material_set_item(material_set_item={profile})"
|
And I press "bim.edit_material_set_item(material_set_item={profile})"
|
||||||
And I press "bim.edit_assigned_material(material_set={profile_set})"
|
And I press "bim.edit_assigned_material(material_set={profile_set})"
|
||||||
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
And I press "bim.assign_type(relating_type={type}, related_object="IfcWall/Cube")"
|
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
Then the object "IfcWall/Cube" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
Then the object "IfcWall/Cube" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|||||||
@@ -18,13 +18,13 @@
|
|||||||
|
|
||||||
import blenderbim.core.root as subject
|
import blenderbim.core.root as subject
|
||||||
import test.core.test_geometry
|
import test.core.test_geometry
|
||||||
from test.core.bootstrap import ifc, collector, root
|
from test.core.bootstrap import ifc, collector, geometry, root
|
||||||
|
|
||||||
|
|
||||||
class TestCopyClass:
|
class TestCopyClass:
|
||||||
def test_doing_nothing_if_not_an_ifc_element(self, ifc, collector, root):
|
def test_doing_nothing_if_not_an_ifc_element(self, ifc, collector, root):
|
||||||
ifc.get_entity("obj").should_be_called().will_return(None)
|
ifc.get_entity("obj").should_be_called().will_return(None)
|
||||||
subject.copy_class(ifc, collector, root, obj="obj")
|
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||||
|
|
||||||
def test_copy_with_new_geometry_derived_from_the_type(self, ifc, collector, root):
|
def test_copy_with_new_geometry_derived_from_the_type(self, ifc, collector, root):
|
||||||
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||||
@@ -35,31 +35,43 @@ class TestCopyClass:
|
|||||||
ifc.run("type.map_type_representations", related_object="element", relating_type="type").should_be_called()
|
ifc.run("type.map_type_representations", related_object="element", relating_type="type").should_be_called()
|
||||||
collector.assign("obj").should_be_called()
|
collector.assign("obj").should_be_called()
|
||||||
root.is_opening_element("element").should_be_called().will_return(False)
|
root.is_opening_element("element").should_be_called().will_return(False)
|
||||||
subject.copy_class(ifc, collector, root, obj="obj")
|
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||||
|
|
||||||
def test_copy_with_new_geometry_added_afresh_for_speed(
|
def test_copy_with_new_geometry_added_afresh_for_speed(self, ifc, collector, geometry, root):
|
||||||
self,
|
|
||||||
ifc,
|
|
||||||
collector,
|
|
||||||
root,
|
|
||||||
):
|
|
||||||
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||||
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
||||||
ifc.link("element", "obj").should_be_called()
|
ifc.link("element", "obj").should_be_called()
|
||||||
root.get_element_type("element").should_be_called().will_return("type")
|
root.get_element_type("element").should_be_called().will_return("type")
|
||||||
root.does_type_have_representations("type").should_be_called().will_return(False)
|
root.does_type_have_representations("type").should_be_called().will_return(False)
|
||||||
root.get_object_context("obj").should_be_called().will_return("context")
|
|
||||||
root.run_geometry_add_representation(obj="obj", context="context").should_be_called()
|
root.get_object_representation("obj").should_be_called().will_return("representation")
|
||||||
|
root.get_representation_context("representation").should_be_called().will_return("context")
|
||||||
|
geometry.get_ifc_representation_class("element", "representation").should_be_called().will_return(
|
||||||
|
"ifc_representation_class"
|
||||||
|
)
|
||||||
|
geometry.get_profile_set_usage("element").should_be_called().will_return("profile_set_usage")
|
||||||
|
root.run_geometry_add_representation(
|
||||||
|
obj="obj",
|
||||||
|
context="context",
|
||||||
|
ifc_representation_class="ifc_representation_class",
|
||||||
|
profile_set_usage="profile_set_usage",
|
||||||
|
).should_be_called()
|
||||||
collector.assign("obj").should_be_called()
|
collector.assign("obj").should_be_called()
|
||||||
root.is_opening_element("element").should_be_called().will_return(False)
|
root.is_opening_element("element").should_be_called().will_return(False)
|
||||||
subject.copy_class(ifc, collector, root, obj="obj")
|
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||||
|
|
||||||
def test_copied_openings_have_dynamic_voids_added(
|
def test_copy_with_no_new_geometry(self, ifc, collector, geometry, root):
|
||||||
self,
|
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||||
ifc,
|
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
||||||
collector,
|
ifc.link("element", "obj").should_be_called()
|
||||||
root,
|
root.get_element_type("element").should_be_called().will_return("type")
|
||||||
):
|
root.does_type_have_representations("type").should_be_called().will_return(False)
|
||||||
|
root.get_object_representation("obj").should_be_called().will_return(None)
|
||||||
|
collector.assign("obj").should_be_called()
|
||||||
|
root.is_opening_element("element").should_be_called().will_return(False)
|
||||||
|
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||||
|
|
||||||
|
def test_copied_openings_have_dynamic_voids_added(self, ifc, collector, root):
|
||||||
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||||
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
||||||
ifc.link("element", "obj").should_be_called()
|
ifc.link("element", "obj").should_be_called()
|
||||||
@@ -69,4 +81,4 @@ class TestCopyClass:
|
|||||||
collector.assign("obj").should_be_called()
|
collector.assign("obj").should_be_called()
|
||||||
root.is_opening_element("element").should_be_called().will_return(True)
|
root.is_opening_element("element").should_be_called().will_return(True)
|
||||||
root.add_dynamic_opening_voids("element", "obj").should_be_called()
|
root.add_dynamic_opening_voids("element", "obj").should_be_called()
|
||||||
subject.copy_class(ifc, collector, root, obj="obj")
|
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||||
|
|||||||
@@ -20,20 +20,20 @@ import bpy
|
|||||||
import math
|
import math
|
||||||
import numpy
|
import numpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import test.bim.bootstrap
|
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
|
from test.bim.bootstrap import NewFile
|
||||||
from blenderbim.tool.geometry import Geometry as subject
|
from blenderbim.tool.geometry import Geometry as subject
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
|
||||||
|
|
||||||
class TestImplementsTool(test.bim.bootstrap.NewFile):
|
class TestImplementsTool(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
assert isinstance(subject(), blenderbim.core.tool.Geometry)
|
assert isinstance(subject(), blenderbim.core.tool.Geometry)
|
||||||
|
|
||||||
|
|
||||||
class TestChangeObjectData(test.bim.bootstrap.NewFile):
|
class TestChangeObjectData(NewFile):
|
||||||
def test_change_single_object_data(self):
|
def test_change_single_object_data(self):
|
||||||
data1 = bpy.data.meshes.new("Mesh")
|
data1 = bpy.data.meshes.new("Mesh")
|
||||||
data2 = bpy.data.meshes.new("Mesh")
|
data2 = bpy.data.meshes.new("Mesh")
|
||||||
@@ -53,7 +53,7 @@ class TestChangeObjectData(test.bim.bootstrap.NewFile):
|
|||||||
assert obj2.data == data2
|
assert obj2.data == data2
|
||||||
|
|
||||||
|
|
||||||
class TestClearModifiers(test.bim.bootstrap.NewFile):
|
class TestClearModifiers(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||||
obj.modifiers.new("IfcOpeningElement", "BOOLEAN")
|
obj.modifiers.new("IfcOpeningElement", "BOOLEAN")
|
||||||
@@ -61,7 +61,7 @@ class TestClearModifiers(test.bim.bootstrap.NewFile):
|
|||||||
assert len(obj.modifiers) == 0
|
assert len(obj.modifiers) == 0
|
||||||
|
|
||||||
|
|
||||||
class TestCreateDynamicVoids(test.bim.bootstrap.NewFile):
|
class TestCreateDynamicVoids(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
tool.Ifc.set(ifc)
|
tool.Ifc.set(ifc)
|
||||||
@@ -82,7 +82,7 @@ class TestCreateDynamicVoids(test.bim.bootstrap.NewFile):
|
|||||||
assert modifier.use_self is True
|
assert modifier.use_self is True
|
||||||
|
|
||||||
|
|
||||||
class TestDoesObjectHaveMeshWithFaces(test.bim.bootstrap.NewFile):
|
class TestDoesObjectHaveMeshWithFaces(NewFile):
|
||||||
def test_empties_return_false(self):
|
def test_empties_return_false(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
assert subject.does_object_have_mesh_with_faces(obj) is False
|
assert subject.does_object_have_mesh_with_faces(obj) is False
|
||||||
@@ -101,7 +101,7 @@ class TestDoesObjectHaveMeshWithFaces(test.bim.bootstrap.NewFile):
|
|||||||
assert subject.does_object_have_mesh_with_faces(obj) is True
|
assert subject.does_object_have_mesh_with_faces(obj) is True
|
||||||
|
|
||||||
|
|
||||||
class TestDuplicateObjectData(test.bim.bootstrap.NewFile):
|
class TestDuplicateObjectData(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
data = bpy.data.meshes.new("Mesh")
|
data = bpy.data.meshes.new("Mesh")
|
||||||
obj = bpy.data.objects.new("Object", data)
|
obj = bpy.data.objects.new("Object", data)
|
||||||
@@ -110,14 +110,14 @@ class TestDuplicateObjectData(test.bim.bootstrap.NewFile):
|
|||||||
assert isinstance(obj.data, bpy.types.Mesh)
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
|
|
||||||
|
|
||||||
class TestGetObjectData(test.bim.bootstrap.NewFile):
|
class TestGetObjectData(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
data = bpy.data.meshes.new("Mesh")
|
data = bpy.data.meshes.new("Mesh")
|
||||||
obj = bpy.data.objects.new("Object", data)
|
obj = bpy.data.objects.new("Object", data)
|
||||||
assert subject.get_object_data(obj) == obj.data
|
assert subject.get_object_data(obj) == obj.data
|
||||||
|
|
||||||
|
|
||||||
class TestGetObjectMaterialsWithoutStyles(test.bim.bootstrap.NewFile):
|
class TestGetObjectMaterialsWithoutStyles(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
material1 = bpy.data.materials.new("Material")
|
material1 = bpy.data.materials.new("Material")
|
||||||
material2 = bpy.data.materials.new("Material")
|
material2 = bpy.data.materials.new("Material")
|
||||||
@@ -130,7 +130,7 @@ class TestGetObjectMaterialsWithoutStyles(test.bim.bootstrap.NewFile):
|
|||||||
assert subject.get_object_materials_without_styles(obj) == [material1, material2]
|
assert subject.get_object_materials_without_styles(obj) == [material1, material2]
|
||||||
|
|
||||||
|
|
||||||
class TestGetRepresentationData(test.bim.bootstrap.NewFile):
|
class TestGetRepresentationData(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
context = ifc.createIfcGeometricRepresentationContext()
|
context = ifc.createIfcGeometricRepresentationContext()
|
||||||
@@ -140,7 +140,7 @@ class TestGetRepresentationData(test.bim.bootstrap.NewFile):
|
|||||||
assert subject.get_representation_data(representation) == data
|
assert subject.get_representation_data(representation) == data
|
||||||
|
|
||||||
|
|
||||||
class TestGetRepresentationName(test.bim.bootstrap.NewFile):
|
class TestGetRepresentationName(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
context = ifc.createIfcGeometricRepresentationContext()
|
context = ifc.createIfcGeometricRepresentationContext()
|
||||||
@@ -149,7 +149,7 @@ class TestGetRepresentationName(test.bim.bootstrap.NewFile):
|
|||||||
assert subject.get_representation_name(representation) == f"{context.id()}/{representation.id()}"
|
assert subject.get_representation_name(representation) == f"{context.id()}/{representation.id()}"
|
||||||
|
|
||||||
|
|
||||||
class TestGetCartesianPointCoordinateOffset(test.bim.bootstrap.NewFile):
|
class TestGetCartesianPointCoordinateOffset(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
obj.BIMObjectProperties.blender_offset_type = "CARTESIAN_POINT"
|
obj.BIMObjectProperties.blender_offset_type = "CARTESIAN_POINT"
|
||||||
@@ -177,7 +177,7 @@ class TestGetCartesianPointCoordinateOffset(test.bim.bootstrap.NewFile):
|
|||||||
assert subject.get_cartesian_point_coordinate_offset(obj) is None
|
assert subject.get_cartesian_point_coordinate_offset(obj) is None
|
||||||
|
|
||||||
|
|
||||||
class TestGetTotalRepresentationItems(test.bim.bootstrap.NewFile):
|
class TestGetTotalRepresentationItems(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
material1 = bpy.data.materials.new("Material")
|
material1 = bpy.data.materials.new("Material")
|
||||||
material2 = bpy.data.materials.new("Material")
|
material2 = bpy.data.materials.new("Material")
|
||||||
@@ -187,7 +187,7 @@ class TestGetTotalRepresentationItems(test.bim.bootstrap.NewFile):
|
|||||||
assert subject.get_total_representation_items(obj) == 2
|
assert subject.get_total_representation_items(obj) == 2
|
||||||
|
|
||||||
|
|
||||||
class TestImportRepresentation(test.bim.bootstrap.NewFile):
|
class TestImportRepresentation(NewFile):
|
||||||
def test_importing_a_normal_shape(self):
|
def test_importing_a_normal_shape(self):
|
||||||
ifc = ifcopenshell.open("test/files/basic.ifc")
|
ifc = ifcopenshell.open("test/files/basic.ifc")
|
||||||
tool.Ifc.set(ifc)
|
tool.Ifc.set(ifc)
|
||||||
@@ -213,7 +213,7 @@ class TestImportRepresentation(test.bim.bootstrap.NewFile):
|
|||||||
assert len(mesh.edges) == 4
|
assert len(mesh.edges) == 4
|
||||||
|
|
||||||
|
|
||||||
class TestIsBodyRepresentation(test.bim.bootstrap.NewFile):
|
class TestIsBodyRepresentation(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
context = ifc.createIfcGeometricRepresentationContext()
|
context = ifc.createIfcGeometricRepresentationContext()
|
||||||
@@ -225,7 +225,7 @@ class TestIsBodyRepresentation(test.bim.bootstrap.NewFile):
|
|||||||
assert subject.is_body_representation(representation) is False
|
assert subject.is_body_representation(representation) is False
|
||||||
|
|
||||||
|
|
||||||
class TestLink(test.bim.bootstrap.NewFile):
|
class TestLink(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
element = ifc.createIfcShapeRepresentation()
|
element = ifc.createIfcShapeRepresentation()
|
||||||
@@ -234,14 +234,14 @@ class TestLink(test.bim.bootstrap.NewFile):
|
|||||||
assert obj.BIMMeshProperties.ifc_definition_id == element.id()
|
assert obj.BIMMeshProperties.ifc_definition_id == element.id()
|
||||||
|
|
||||||
|
|
||||||
class TestRenameObjectData(test.bim.bootstrap.NewFile):
|
class TestRenameObjectData(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.meshes.new("Mesh")
|
obj = bpy.data.meshes.new("Mesh")
|
||||||
subject.rename_object(obj, "name")
|
subject.rename_object(obj, "name")
|
||||||
assert obj.name == "name"
|
assert obj.name == "name"
|
||||||
|
|
||||||
|
|
||||||
class TestResolveMappedRepresentation(test.bim.bootstrap.NewFile):
|
class TestResolveMappedRepresentation(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
mapped_representation = ifc.createIfcShapeRepresentation()
|
mapped_representation = ifc.createIfcShapeRepresentation()
|
||||||
@@ -258,19 +258,72 @@ class TestResolveMappedRepresentation(test.bim.bootstrap.NewFile):
|
|||||||
assert subject.resolve_mapped_representation(representation) == representation
|
assert subject.resolve_mapped_representation(representation) == representation
|
||||||
|
|
||||||
|
|
||||||
class TestShouldForceFacetedBrep(test.bim.bootstrap.NewFile):
|
class TestShouldForceFacetedBrep(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
result = bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep
|
result = bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep
|
||||||
assert subject.should_force_faceted_brep() is result
|
assert subject.should_force_faceted_brep() is result
|
||||||
|
|
||||||
|
|
||||||
class TestShouldForceTriangulation(test.bim.bootstrap.NewFile):
|
class TestShouldForceTriangulation(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
result = bpy.context.scene.BIMGeometryProperties.should_force_triangulation
|
result = bpy.context.scene.BIMGeometryProperties.should_force_triangulation
|
||||||
assert subject.should_force_triangulation() is result
|
assert subject.should_force_triangulation() is result
|
||||||
|
|
||||||
|
|
||||||
class TestShouldUsePresentationStyleAssignment(test.bim.bootstrap.NewFile):
|
class TestShouldUsePresentationStyleAssignment(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
result = bpy.context.scene.BIMGeometryProperties.should_use_presentation_style_assignment
|
result = bpy.context.scene.BIMGeometryProperties.should_use_presentation_style_assignment
|
||||||
assert subject.should_use_presentation_style_assignment() is result
|
assert subject.should_use_presentation_style_assignment() is result
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetProfileSetUsage(NewFile):
|
||||||
|
def test_getting_a_profile_set_usage(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
element = ifc.createIfcColumn()
|
||||||
|
assert subject.get_profile_set_usage(element) is None
|
||||||
|
usage = ifc.createIfcMaterialProfileSetUsage()
|
||||||
|
ifc.createIfcRelAssociatesMaterial(RelatingMaterial=usage, RelatedObjects=[element])
|
||||||
|
assert subject.get_profile_set_usage(element) == usage
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetIfcRepresentationClass(NewFile):
|
||||||
|
def test_detecting_profile_set_representations(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
element = ifc.createIfcColumn()
|
||||||
|
ifc.createIfcRelAssociatesMaterial(
|
||||||
|
RelatingMaterial=ifc.createIfcMaterialProfileSetUsage(), RelatedObjects=[element]
|
||||||
|
)
|
||||||
|
representation = ifc.createIfcShapeRepresentation()
|
||||||
|
assert (
|
||||||
|
subject.get_ifc_representation_class(element, representation)
|
||||||
|
== "IfcExtrudedAreaSolid/IfcMaterialProfileSetUsage"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_detecting_rectangular_extrusions(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
element = ifc.createIfcColumn()
|
||||||
|
representation = ifc.createIfcShapeRepresentation(
|
||||||
|
Items=[ifc.createIfcExtrudedAreaSolid(SweptArea=ifc.createIfcRectangleProfileDef())]
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
subject.get_ifc_representation_class(element, representation)
|
||||||
|
== "IfcExtrudedAreaSolid/IfcRectangleProfileDef"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_detecting_circle_extrusions(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
element = ifc.createIfcColumn()
|
||||||
|
representation = ifc.createIfcShapeRepresentation(
|
||||||
|
Items=[ifc.createIfcExtrudedAreaSolid(SweptArea=ifc.createIfcCircleProfileDef())]
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
subject.get_ifc_representation_class(element, representation) == "IfcExtrudedAreaSolid/IfcCircleProfileDef"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_returning_null_for_non_parametric_representations(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
assert subject.get_ifc_representation_class(ifc.createIfcColumn(), ifc.createIfcShapeRepresentation()) is None
|
||||||
|
|||||||
@@ -74,15 +74,23 @@ class TestGetElementType(NewFile):
|
|||||||
assert subject.get_element_type(element) == type
|
assert subject.get_element_type(element) == type
|
||||||
|
|
||||||
|
|
||||||
class TestGetElementType(NewFile):
|
class TestGetObjectRepresentation(NewFile):
|
||||||
|
def test_run(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
representation = ifc.createIfcShapeRepresentation()
|
||||||
|
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||||
|
obj.data.BIMMeshProperties.ifc_definition_id = representation.id()
|
||||||
|
assert subject.get_object_representation(obj) == representation
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetRepresentationContext(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
tool.Ifc.set(ifc)
|
tool.Ifc.set(ifc)
|
||||||
context = ifc.createIfcGeometricRepresentationContext()
|
context = ifc.createIfcGeometricRepresentationContext()
|
||||||
representation = ifc.createIfcShapeRepresentation(ContextOfItems=context)
|
representation = ifc.createIfcShapeRepresentation(ContextOfItems=context)
|
||||||
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
assert subject.get_representation_context(representation) == context
|
||||||
obj.data.BIMMeshProperties.ifc_definition_id = representation.id()
|
|
||||||
assert subject.get_object_context(obj) == context
|
|
||||||
|
|
||||||
|
|
||||||
class TestIsOpeningElement(NewFile):
|
class TestIsOpeningElement(NewFile):
|
||||||
|
|||||||
Reference in New Issue
Block a user