diff --git a/src/blenderbim/blenderbim/bim/module/model/__init__.py b/src/blenderbim/blenderbim/bim/module/model/__init__.py
index bdb5f5fe01..8220be3df9 100644
--- a/src/blenderbim/blenderbim/bim/module/model/__init__.py
+++ b/src/blenderbim/blenderbim/bim/module/model/__init__.py
@@ -106,6 +106,7 @@ classes = (
slab.SetArcIndex,
space.GenerateSpace,
space.GenerateSpacesFromWalls,
+ space.GenerateFlooringCoveringsFromWalls,
space.ToggleSpaceVisibility,
mep.FitFlowSegments,
mep.RegenerateDistributionElement,
diff --git a/src/blenderbim/blenderbim/bim/module/model/space.py b/src/blenderbim/blenderbim/bim/module/model/space.py
index 2af8ae020c..efbcd9bdca 100644
--- a/src/blenderbim/blenderbim/bim/module/model/space.py
+++ b/src/blenderbim/blenderbim/bim/module/model/space.py
@@ -23,6 +23,7 @@ import shapely
import ifcopenshell
import ifcopenshell.util.element
import blenderbim.tool as tool
+import blenderbim.core.spatial as core
import blenderbim.core.type
from math import pi
from mathutils import Vector, Matrix
@@ -230,182 +231,29 @@ class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context):
# This only works based on a 2D plan only considering the standard
# walls (i.e. prismatic) in the active object storey.
- # In order to run, the active objct must be a wall and
- # have to be selected walls
- props = context.scene.BIMModelProperties
+ # In order to run, the active object must be a wall and
+ # there must be selected walls
+ core.generate_spaces_from_walls(tool.Ifc, tool.Spatial, tool.Collector)
+
+class GenerateFlooringCoveringsFromWalls(bpy.types.Operator, tool.Ifc.Operator):
+ bl_idname = "bim.generate_flooring_coverings_from_walls"
+ bl_label = "Generate Flooring Coverings From Walls"
+ bl_options = {"REGISTER", "UNDO"}
+ bl_description = "Generate flooring coverings from selected walls. The active object must be a wall"
+
+ @classmethod
+ def poll(cls, context):
active_obj = bpy.context.active_object
-
- if not active_obj:
- self.report({"ERROR"}, "No active object. Please select a wall")
- return
-
element = tool.Ifc.get_entity(active_obj)
- if element and not element.is_a("IfcWall"):
- return self.report({"ERROR"}, "The active object is not a wall. Please select a wall.")
-
- container = ifcopenshell.util.element.get_container(element)
- if not container:
- self.report({"ERROR"}, "The wall is not contained.")
-
- if not bpy.context.selected_objects:
- self.report({"ERROR"}, "No selected objects found. Please select walls.")
- return
-
- x, y, z = active_obj.matrix_world.translation.xyz
- mat = active_obj.matrix_world
- h = active_obj.dimensions.z
- selected_objects = bpy.context.selected_objects
-
- boundary_elements = self.get_boundary_elements(selected_objects)
-
- polys = self.get_polygons(boundary_elements)
-
- converted_tolerance = self.get_converted_tolerance(tolerance=0.03)
-
- union = shapely.ops.unary_union(polys).buffer(converted_tolerance, cap_style=2, join_style=2)
-
- union = self.get_purged_inner_holes_poly(union_geom=union, min_area=self.get_converted_tolerance(tolerance=3))
-
- for i, linear_ring in enumerate(union.interiors):
- poly = Polygon(linear_ring)
- poly = poly.buffer(converted_tolerance, single_sided=True, cap_style=2, join_style=2)
-
- bm = self.get_bmesh_from_polygon(poly, mat, h)
-
- name = "Space" + str(i)
- mesh = bpy.data.meshes.new(name=name)
- bm.to_mesh(mesh)
- bm.free()
-
- obj = bpy.data.objects.new(name, mesh)
- obj.matrix_world = mat
-
- self.set_obj_origin_to_bboxcenter(obj)
-
- if z != 0:
- obj.location = obj.location + Vector((0, 0, z))
-
- context.view_layer.active_layer_collection.collection.objects.link(obj)
- bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcSpace")
- container_obj = tool.Ifc.get_object(container)
- blenderbim.core.spatial.assign_container(
- tool.Ifc, tool.Collector, tool.Spatial, structure_obj=container_obj, element_obj=obj
- )
-
- def get_boundary_elements(self, selected_objects):
- boundary_elements = []
- for obj in selected_objects:
- subelement = tool.Ifc.get_entity(obj)
- if subelement.is_a("IfcWall") or subelement.is_a("IfcColumn"):
- boundary_elements.append(subelement)
- return boundary_elements
-
- def get_polygons(self, boundary_elements):
- polys = []
- for boundary_element in boundary_elements:
- obj = tool.Ifc.get_object(boundary_element)
- if not obj:
- continue
- points = []
- base = self.get_obj_base_points(obj)
- for index in ["low_left", "low_right", "high_right", "high_left"]:
- point = base[index]
- points.append(point)
-
- polys.append(Polygon(points))
- return polys
-
- def get_obj_base_points(self, obj):
- x_values = [(obj.matrix_world @ Vector(v)).x for v in obj.bound_box]
- y_values = [(obj.matrix_world @ Vector(v)).y for v in obj.bound_box]
- return {
- "low_left": (x_values[0], y_values[0]),
- "high_left": (x_values[3], y_values[3]),
- "low_right": (x_values[4], y_values[4]),
- "high_right": (x_values[7], y_values[7]),
- }
-
- def get_converted_tolerance(self, tolerance):
- model = tool.Ifc.get()
- project_unit = ifcopenshell.util.unit.get_project_unit(model, "LENGTHUNIT")
- prefix = getattr(project_unit, "Prefix", None)
-
- converted_tolerance = ifcopenshell.util.unit.convert(
- value=tolerance,
- from_prefix=None,
- from_unit="METRE",
- to_prefix=prefix,
- to_unit=project_unit.Name,
- )
- return tolerance
-
- def get_purged_inner_holes_poly(self, union_geom, min_area):
- interiors_list = []
-
- if union_geom.geom_type == "MultiPolygon":
- for poly in union_geom.geoms:
- interiors_list = self.get_poly_valid_interior_list(
- poly=poly, min_area=min_area, interiors_list=interiors_list
- )
-
- new_poly = Polygon(poly.exterior.coords, holes=interiors_list)
-
- if union_geom.geom_type == "Polygon":
- interiors_list = self.get_poly_valid_interior_list(
- poly=union_geom, min_area=min_area, interiors_list=interiors_list
- )
- new_poly = Polygon(union_geom.exterior.coords, holes=interiors_list)
-
- return new_poly
-
- def get_poly_valid_interior_list(self, poly, min_area, interiors_list):
- for interior in poly.interiors:
- p = Polygon(interior)
- if p.area >= min_area:
- interiors_list.append(interior)
- return interiors_list
-
- def get_bmesh_from_polygon(self, poly, mat, h):
- bm = bmesh.new()
- bm.verts.index_update()
- bm.edges.index_update()
-
- mat_invert = mat.inverted()
-
- new_verts = [bm.verts.new(mat_invert @ Vector([v[0], v[1], 0])) for v in poly.exterior.coords[0:-1]]
- [bm.edges.new((new_verts[i], new_verts[i + 1])) for i in range(len(new_verts) - 1)]
- bm.edges.new((new_verts[len(new_verts) - 1], new_verts[0]))
-
- bm.verts.index_update()
- bm.edges.index_update()
-
- bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=1e-5)
- bmesh.ops.triangle_fill(bm, edges=bm.edges)
- bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 5, verts=bm.verts, edges=bm.edges)
-
- extrusion = bmesh.ops.extrude_face_region(bm, geom=bm.faces)
- extruded_verts = [g for g in extrusion["geom"] if isinstance(g, bmesh.types.BMVert)]
- bmesh.ops.translate(bm, vec=[0.0, 0.0, h], verts=extruded_verts)
-
- bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
-
- return bm
-
- def set_obj_origin_to_bboxcenter(self, obj):
- mat = obj.matrix_world
- inverted = mat.inverted()
- local_bbox_center = 0.125 * sum((Vector(b) for b in obj.bound_box), Vector())
- global_bbox_center = mat @ local_bbox_center
-
- oldLoc = obj.location
- newLoc = global_bbox_center
- diff = newLoc - oldLoc
- for vert in obj.data.vertices:
- aux_vector = mat @ vert.co
- aux_vector = aux_vector - diff
- vert.co = inverted @ aux_vector
- obj.location = newLoc
+ if element:
+ return context.selected_objects and element.is_a("IfcWall")
+ def _execute(self, context):
+ # This only works based on a 2D plan only considering the standard
+ # walls (i.e. prismatic) in the active object storey.
+ # In order to run, the active object must be a wall and
+ # there must be selected walls
+ core.generate_flooring_coverings_from_walls(tool.Ifc, tool.Spatial, tool.Collector)
class ToggleSpaceVisibility(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.toggle_space_visibility"
@@ -414,26 +262,6 @@ class ToggleSpaceVisibility(bpy.types.Operator, tool.Ifc.Operator):
bl_description = "Change the space visibility"
def execute(cls, context):
- model = tool.Ifc.get()
+ core.toggle_space_visibility(tool.Ifc, tool.Spatial)
+ return {"FINISHED"}
- spaces = model.by_type("IfcSpace")
-
- if not spaces:
- print(spaces)
- return {"FINISHED"}
-
- first_obj = tool.Ifc.get_object(spaces[0])
-
- if bpy.data.objects[first_obj.name].display_type == "TEXTURED":
- for space in spaces:
- obj = tool.Ifc.get_object(space)
- bpy.data.objects[obj.name].show_wire = True
- bpy.data.objects[obj.name].display_type = "WIRE"
- return {"FINISHED"}
-
- elif bpy.data.objects[first_obj.name].display_type == "WIRE":
- for space in spaces:
- obj = tool.Ifc.get_object(space)
- bpy.data.objects[obj.name].show_wire = False
- bpy.data.objects[obj.name].display_type = "TEXTURED"
- return {"FINISHED"}
diff --git a/src/blenderbim/blenderbim/core/spatial.py b/src/blenderbim/blenderbim/core/spatial.py
index fb75dd2671..7864ad0845 100644
--- a/src/blenderbim/blenderbim/core/spatial.py
+++ b/src/blenderbim/blenderbim/core/spatial.py
@@ -17,6 +17,8 @@
# along with BlenderBIM Add-on. If not, see .
import blenderbim.core
+import bpy
+import ifcopenshell
def reference_structure(ifc, spatial, structure=None, element=None):
@@ -120,3 +122,67 @@ def select_decomposed_elements(spatial):
container = spatial.get_active_container()
if container:
spatial.select_products(spatial.get_decomposed_elements(container))
+
+#HERE STARTS SPATIAL TOOL
+
+def generate_spaces_from_walls(ifc, spatial, collector):
+ #props = bpy.context.scene.BIMModelProperties
+ container, active_obj = spatial.get_container_and_active_obj()
+
+ if not active_obj:
+ self.report({"ERROR"}, "No active object. Please select a wall")
+ return
+
+ element = ifc.get_entity(active_obj)
+ if element and not element.is_a("IfcWall"):
+ return self.report({"ERROR"}, "The active object is not a wall. Please select a wall.")
+
+ if not container:
+ self.report({"ERROR"}, "The wall is not contained.")
+
+ if not bpy.context.selected_objects:
+ self.report({"ERROR"}, "No selected objects found. Please select walls.")
+ return
+
+ x, y, z = active_obj.matrix_world.translation.xyz
+ mat = active_obj.matrix_world
+ h = active_obj.dimensions.z
+ selected_objects = bpy.context.selected_objects
+
+ union = spatial.get_union_shape_from_selected_objects(selected_objects)
+
+ for i, linear_ring in enumerate(union.interiors):
+ poly = spatial.get_buffered_poly_from_linear_ring(linear_ring)
+
+ bm = spatial.get_bmesh_from_polygon(poly, mat, h)
+
+ name = "Space" + str(i)
+ mesh = bpy.data.meshes.new(name=name)
+ bm.to_mesh(mesh)
+ bm.free()
+
+ obj = bpy.data.objects.new(name, mesh)
+ obj.matrix_world = mat
+
+ spatial.set_obj_origin_to_bboxcenter(obj)
+
+ if z != 0:
+ obj.location = obj.location + Vector((0, 0, z))
+
+ bpy.context.view_layer.active_layer_collection.collection.objects.link(obj)
+ bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcSpace")
+ container_obj = ifc.get_object(container)
+ blenderbim.core.spatial.assign_container(
+ ifc, collector, spatial, structure_obj=container_obj, element_obj=obj
+ )
+
+def generate_flooring_coverings_from_walls(ifc, spatial, collector):
+ pass
+
+def toggle_space_visibility(ifc, spatial):
+ model = ifc.get()
+ spaces = model.by_type("IfcSpace")
+ if not spaces:
+ return
+ spatial.toggle_spaces_visibility_wired_and_textured(spaces)
+
diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py
index f0f168a7ba..b249df13f3 100644
--- a/src/blenderbim/blenderbim/core/tool.py
+++ b/src/blenderbim/blenderbim/core/tool.py
@@ -810,6 +810,19 @@ class Spatial:
def set_active_object(cls, obj): pass
def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix): pass
def show_scene_objects(cls): pass
+ #HERE STARTS SPATIAL TOOL
+ def get_container_and_active_obj(cls): pass
+ def get_union_shape_from_selected_objects(cls, selected_objects): pass
+ def get_boundary_elements(cls, selected_objects): pass
+ def get_polygons(cls, boundary_elements): pass
+ def get_obj_base_points(cls, obj): pass
+ def get_converted_tolerance(cls, tolerance): pass
+ def get_purged_inner_holes_poly(cls, union_geom, min_area): pass
+ def get_poly_valid_interior_list(cls, poly, min_area, interiors_list): pass
+ def get_buffered_poly_from_linear_ring(cls, linear_ring): pass
+ def get_bmesh_from_polygon(cls, poly, mat, h): pass
+ def set_obj_origin_to_bboxcenter(cls, obj): pass
+ def toggle_spaces_visibility_wired_and_textured(cls, spaces): pass
@interface
diff --git a/src/blenderbim/blenderbim/tool/spatial.py b/src/blenderbim/blenderbim/tool/spatial.py
index 5c3b6b895a..c6865c9c1d 100644
--- a/src/blenderbim/blenderbim/tool/spatial.py
+++ b/src/blenderbim/blenderbim/tool/spatial.py
@@ -17,13 +17,17 @@
# along with BlenderBIM Add-on. If not, see .
import bpy
+import bmesh
+import shapely
import ifcopenshell
import blenderbim.core.tool
import blenderbim.core.root
import blenderbim.core.spatial
import blenderbim.tool as tool
import json
-
+from math import pi
+from mathutils import Vector, Matrix
+from shapely import Polygon, MultiPolygon
class Spatial(blenderbim.core.tool.Spatial):
@classmethod
@@ -262,3 +266,168 @@ class Spatial(blenderbim.core.tool.Spatial):
contracted_containers = json.loads(props.contracted_containers)
contracted_containers.remove(container.id())
props.contracted_containers = json.dumps(contracted_containers)
+
+#HERE STARTS SPATIAL TOOL
+
+ @classmethod
+ def get_container_and_active_obj(cls):
+ active_obj = bpy.context.active_object
+ element = tool.Ifc.get_entity(active_obj)
+ container = ifcopenshell.util.element.get_container(element)
+ return container, active_obj
+
+ @classmethod
+ def get_union_shape_from_selected_objects(cls, selected_objects):
+ boundary_elements = cls.get_boundary_elements(selected_objects)
+ polys = cls.get_polygons(boundary_elements)
+ converted_tolerance = cls.get_converted_tolerance(tolerance=0.03)
+ union = shapely.ops.unary_union(polys).buffer(converted_tolerance, cap_style=2, join_style=2)
+ union = cls.get_purged_inner_holes_poly(union_geom=union, min_area=cls.get_converted_tolerance(tolerance=3))
+
+ return union
+
+ @classmethod
+ def get_boundary_elements(cls, selected_objects):
+ boundary_elements = []
+ for obj in selected_objects:
+ subelement = tool.Ifc.get_entity(obj)
+ if subelement.is_a("IfcWall") or subelement.is_a("IfcColumn"):
+ boundary_elements.append(subelement)
+ return boundary_elements
+
+ @classmethod
+ def get_polygons(cls, boundary_elements):
+ polys = []
+ for boundary_element in boundary_elements:
+ obj = tool.Ifc.get_object(boundary_element)
+ if not obj:
+ continue
+ points = []
+ base = cls.get_obj_base_points(obj)
+ for index in ["low_left", "low_right", "high_right", "high_left"]:
+ point = base[index]
+ points.append(point)
+
+ polys.append(Polygon(points))
+ return polys
+
+ @classmethod
+ def get_obj_base_points(cls, obj):
+ x_values = [(obj.matrix_world @ Vector(v)).x for v in obj.bound_box]
+ y_values = [(obj.matrix_world @ Vector(v)).y for v in obj.bound_box]
+ return {
+ "low_left": (x_values[0], y_values[0]),
+ "high_left": (x_values[3], y_values[3]),
+ "low_right": (x_values[4], y_values[4]),
+ "high_right": (x_values[7], y_values[7]),
+ }
+
+ @classmethod
+ def get_converted_tolerance(cls, tolerance):
+ model = tool.Ifc.get()
+ project_unit = ifcopenshell.util.unit.get_project_unit(model, "LENGTHUNIT")
+ prefix = getattr(project_unit, "Prefix", None)
+
+ converted_tolerance = ifcopenshell.util.unit.convert(
+ value=tolerance,
+ from_prefix=None,
+ from_unit="METRE",
+ to_prefix=prefix,
+ to_unit=project_unit.Name,
+ )
+ return tolerance
+
+ @classmethod
+ def get_purged_inner_holes_poly(cls, union_geom, min_area):
+ interiors_list = []
+
+ if union_geom.geom_type == "MultiPolygon":
+ for poly in union_geom.geoms:
+ interiors_list = cls.get_poly_valid_interior_list(
+ poly=poly, min_area=min_area, interiors_list=interiors_list
+ )
+
+ new_poly = Polygon(poly.exterior.coords, holes=interiors_list)
+
+ if union_geom.geom_type == "Polygon":
+ interiors_list = cls.get_poly_valid_interior_list(
+ poly=union_geom, min_area=min_area, interiors_list=interiors_list
+ )
+ new_poly = Polygon(union_geom.exterior.coords, holes=interiors_list)
+
+ return new_poly
+
+ @classmethod
+ def get_poly_valid_interior_list(cls, poly, min_area, interiors_list):
+ for interior in poly.interiors:
+ p = Polygon(interior)
+ if p.area >= min_area:
+ interiors_list.append(interior)
+ return interiors_list
+
+ @classmethod
+ def get_buffered_poly_from_linear_ring(cls, linear_ring):
+ poly = Polygon(linear_ring)
+ converted_tolerance = cls.get_converted_tolerance(tolerance=0.03)
+ poly = poly.buffer(converted_tolerance, single_sided=True, cap_style=2, join_style=2)
+ return poly
+
+ @classmethod
+ def get_bmesh_from_polygon(cls, poly, mat, h):
+ bm = bmesh.new()
+ bm.verts.index_update()
+ bm.edges.index_update()
+
+ mat_invert = mat.inverted()
+
+ new_verts = [bm.verts.new(mat_invert @ Vector([v[0], v[1], 0])) for v in poly.exterior.coords[0:-1]]
+ [bm.edges.new((new_verts[i], new_verts[i + 1])) for i in range(len(new_verts) - 1)]
+ bm.edges.new((new_verts[len(new_verts) - 1], new_verts[0]))
+
+ bm.verts.index_update()
+ bm.edges.index_update()
+
+ bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=1e-5)
+ bmesh.ops.triangle_fill(bm, edges=bm.edges)
+ bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 5, verts=bm.verts, edges=bm.edges)
+
+ extrusion = bmesh.ops.extrude_face_region(bm, geom=bm.faces)
+ extruded_verts = [g for g in extrusion["geom"] if isinstance(g, bmesh.types.BMVert)]
+ bmesh.ops.translate(bm, vec=[0.0, 0.0, h], verts=extruded_verts)
+
+ bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
+
+ return bm
+
+ @classmethod
+ def set_obj_origin_to_bboxcenter(cls, obj):
+ mat = obj.matrix_world
+ inverted = mat.inverted()
+ local_bbox_center = 0.125 * sum((Vector(b) for b in obj.bound_box), Vector())
+ global_bbox_center = mat @ local_bbox_center
+
+ oldLoc = obj.location
+ newLoc = global_bbox_center
+ diff = newLoc - oldLoc
+ for vert in obj.data.vertices:
+ aux_vector = mat @ vert.co
+ aux_vector = aux_vector - diff
+ vert.co = inverted @ aux_vector
+ obj.location = newLoc
+
+ @classmethod
+ def toggle_spaces_visibility_wired_and_textured(cls, spaces):
+ first_obj = tool.Ifc.get_object(spaces[0])
+ if bpy.data.objects[first_obj.name].display_type == "TEXTURED":
+ for space in spaces:
+ obj = tool.Ifc.get_object(space)
+ bpy.data.objects[obj.name].show_wire = True
+ bpy.data.objects[obj.name].display_type = "WIRE"
+ return
+
+ elif bpy.data.objects[first_obj.name].display_type == "WIRE":
+ for space in spaces:
+ obj = tool.Ifc.get_object(space)
+ bpy.data.objects[obj.name].show_wire = False
+ bpy.data.objects[obj.name].display_type = "TEXTURED"
+ return
diff --git a/src/blenderbim/test/bim/feature/spatial.feature b/src/blenderbim/test/bim/feature/spatial.feature
index acdf6ee292..4e0d84d88c 100644
--- a/src/blenderbim/test/bim/feature/spatial.feature
+++ b/src/blenderbim/test/bim/feature/spatial.feature
@@ -1,6 +1,6 @@
@spatial
Feature: Spatial
- Covers spatial containment management.
+ Covers spatial containment management and spatial tool.
Scenario: Enable editing container
Given an empty IFC project
@@ -21,8 +21,7 @@ Scenario: Assign container
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 press "bim.assign_class(ifc_class='IfcWall', predefined_type='SOLIDWALL')"
And the object "IfcWall/Cube" is selected
And I press "bim.enable_editing_container"
And the variable "site" is "tool.Ifc.get().by_type('IfcSite')[0].id()"
@@ -33,8 +32,7 @@ Scenario: Copy to container
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 press "bim.assign_class(ifc_class='IfcWall', predefined_type='SOLIDWALL')"
And the object "IfcWall/Cube" is selected
And I press "bim.enable_editing_container"
When I set "scene.BIMSpatialProperties.containers[0].is_selected" to "True"
@@ -45,8 +43,7 @@ Scenario: Reference structure
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 press "bim.assign_class(ifc_class='IfcWall', predefined_type='SOLIDWALL')"
And the object "IfcWall/Cube" is selected
And I press "bim.enable_editing_container"
When I set "scene.BIMSpatialProperties.containers[0].is_selected" to "True"
@@ -57,8 +54,7 @@ Scenario: Dereference structure
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 press "bim.assign_class(ifc_class='IfcWall', predefined_type='SOLIDWALL')"
And the object "IfcWall/Cube" is selected
And I press "bim.enable_editing_container"
When I set "scene.BIMSpatialProperties.containers[0].is_selected" to "True"
@@ -70,8 +66,7 @@ Scenario: Select container
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 press "bim.assign_class(ifc_class='IfcWall', predefined_type='SOLIDWALL')"
And the object "IfcWall/Cube" is selected
And I press "bim.enable_editing_container"
And the variable "site" is "tool.Ifc.get().by_type('IfcSite')[0].id()"
@@ -83,11 +78,47 @@ Scenario: Select similar container
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 press "bim.assign_class(ifc_class='IfcWall', predefined_type='SOLIDWALL')"
And the object "IfcWall/Cube" is selected
And I press "bim.enable_editing_container"
And the variable "site" is "tool.Ifc.get().by_type('IfcSite')[0].id()"
And I press "bim.assign_container(structure={site})"
When I press "bim.select_similar_container"
Then nothing happens
+
+#HERE STARTS TESTS FOR SPATIAL TOOL
+
+Scenario: Execute generate space from cursor position
+ Given an empty IFC project
+ When I press "bim.generate_space"
+ Then nothing happens
+
+Scenario: Execute generate spaces from walls
+ Given an empty IFC project
+ And I load the demo construction library
+ And I set "scene.BIMModelProperties.ifc_class" to "IfcWallType"
+ And the variable "element_type" is "[e for e in {ifc}.by_type('IfcWallType') if e.Name == 'WAL100'][0].id()"
+ And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
+ And I press "bim.add_constr_type_instance"
+ And the object "IfcWall/Wall" is selected
+ When I press "bim.generate_spaces_from_walls"
+ Then nothing happens
+
+Scenario: Execute generate flooring coverings from walls
+ Given an empty IFC project
+ And I load the demo construction library
+ And I set "scene.BIMModelProperties.ifc_class" to "IfcWallType"
+ And the variable "element_type" is "[e for e in {ifc}.by_type('IfcWallType') if e.Name == 'WAL100'][0].id()"
+ And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
+ And I press "bim.add_constr_type_instance"
+ And the object "IfcWall/Wall" is selected
+ When I press "bim.generate_flooring_coverings_from_walls"
+ Then nothing happens
+
+Scenario: Execute toggle space visibility
+ Given an empty IFC project
+ And I add a cube
+ And the object "Cube" is selected
+ And I press "bim.assign_class(ifc_class='IfcSpace', predefined_type='SPACE')"
+ When I press "bim.toggle_space_visibility"
+ Then nothing happens