mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
Generating a space now is based on the default collection
This commit is contained in:
@@ -290,7 +290,7 @@ class BIM_OT_add_part_to_object(bpy.types.Operator, Operator):
|
|||||||
part_class=self.part_class,
|
part_class=self.part_class,
|
||||||
part_name=self.part_name,
|
part_name=self.part_name,
|
||||||
)
|
)
|
||||||
tool.Spatial.load_container_manager()
|
blenderbim.core.spatial.import_spatial_decomposition(tool.Spatial)
|
||||||
|
|
||||||
|
|
||||||
class BIM_OT_break_link_to_other_aggregates(bpy.types.Operator, Operator):
|
class BIM_OT_break_link_to_other_aggregates(bpy.types.Operator, Operator):
|
||||||
|
|||||||
@@ -18,11 +18,8 @@
|
|||||||
|
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
|
||||||
import ifcopenshell.util.element
|
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
import blenderbim.core.spatial as core
|
import blenderbim.core.spatial as core
|
||||||
import blenderbim.core.type
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateSpace(bpy.types.Operator, tool.Ifc.Operator):
|
class GenerateSpace(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -35,37 +32,15 @@ class GenerateSpace(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
"select the right space collection and run the operator"
|
"select the right space collection and run the operator"
|
||||||
)
|
)
|
||||||
|
|
||||||
# @classmethod
|
|
||||||
# def poll(cls, context):
|
|
||||||
# print(context)
|
|
||||||
# collection = context.view_layer.active_layer_collection.collection
|
|
||||||
# collection_obj = collection.BIMCollectionProperties.obj
|
|
||||||
# active_obj = context.active_object
|
|
||||||
# element = tool.Ifc.get_entity(active_obj)
|
|
||||||
# return tool.Ifc.get_entity(collection_obj) and not element.is_a("IfcWall")
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
# This works as a 2.5 extruded polygon based on a cutting plane. Note
|
# This works as a 2.5 extruded polygon based on a cutting plane. Note
|
||||||
# that rooms exclude walls (i.e. not to wall midpoint or exterior /
|
# that rooms exclude walls (i.e. not to wall midpoint or exterior /
|
||||||
# exterior edge.
|
# exterior edge.
|
||||||
|
|
||||||
def msg_no_collection(self, context):
|
try:
|
||||||
self.layout.label(text="NO ACTIVE COLLECTION. PLEASE SELECT A SPATIAL COLLECTION OBJECT OR A WALL")
|
core.generate_space(tool.Ifc, tool.Model, tool.Root, tool.Spatial, tool.Type)
|
||||||
|
except core.NoDefaultContainer:
|
||||||
def msg_no_active_storey(self, context):
|
return self.report({"ERROR"}, "Please set a default container to create the space in.")
|
||||||
self.layout.label(text="NO ACTIVE STOREY. PLEASE SELECT A SPATIAL COLLECTION OBJECT")
|
|
||||||
|
|
||||||
collection = context.view_layer.active_layer_collection.collection
|
|
||||||
collection_obj = collection.BIMCollectionProperties.obj
|
|
||||||
if not collection_obj:
|
|
||||||
context.window_manager.popup_menu(msg_no_collection, title="Error", icon="ERROR")
|
|
||||||
return
|
|
||||||
spatial_element = tool.Ifc.get_entity(collection_obj)
|
|
||||||
if not spatial_element or not spatial_element.is_a("IfcBuildingStorey"):
|
|
||||||
context.window_manager.popup_menu(msg_no_active_storey, title="Error", icon="ERROR")
|
|
||||||
return
|
|
||||||
|
|
||||||
core.generate_space(tool.Ifc, tool.Spatial, tool.Model, tool.Type)
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
|
class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -74,13 +49,6 @@ class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
bl_description = "Generate spaces from selected walls. The active object must be a wall"
|
bl_description = "Generate spaces from selected walls. The active object must be a wall"
|
||||||
|
|
||||||
# @classmethod
|
|
||||||
# def poll(cls, context):
|
|
||||||
# active_obj = context.active_object
|
|
||||||
# element = tool.Ifc.get_entity(active_obj)
|
|
||||||
# if element:
|
|
||||||
# return context.selected_objects and element.is_a("IfcWall")
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
# This only works based on a 2D plan only considering the standard
|
# This only works based on a 2D plan only considering the standard
|
||||||
# walls (i.e. prismatic) in the active object storey.
|
# walls (i.e. prismatic) in the active object storey.
|
||||||
|
|||||||
@@ -20,11 +20,11 @@
|
|||||||
import os
|
import os
|
||||||
import bpy
|
import bpy
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
from blenderbim.bim.helper import prop_with_search
|
|
||||||
from blenderbim.bim.module.model.data import AuthoringData
|
from blenderbim.bim.module.model.data import AuthoringData
|
||||||
from bpy.types import WorkSpaceTool
|
from bpy.types import WorkSpaceTool
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
import blenderbim.bim.handler
|
import blenderbim.bim.handler
|
||||||
|
import blenderbim.core.spatial
|
||||||
|
|
||||||
|
|
||||||
# declaring it here to avoid circular import problems
|
# declaring it here to avoid circular import problems
|
||||||
@@ -160,7 +160,10 @@ class Hotkey(bpy.types.Operator, Operator):
|
|||||||
if element and bpy.context.selected_objects and element.is_a("IfcWall"):
|
if element and bpy.context.selected_objects and element.is_a("IfcWall"):
|
||||||
bpy.ops.bim.generate_spaces_from_walls()
|
bpy.ops.bim.generate_spaces_from_walls()
|
||||||
else:
|
else:
|
||||||
bpy.ops.bim.generate_space()
|
try:
|
||||||
|
blenderbim.core.spatial.generate_space(tool.Ifc, tool.Model, tool.Root, tool.Spatial, tool.Type)
|
||||||
|
except blenderbim.core.spatial.NoDefaultContainer:
|
||||||
|
return self.report({"ERROR"}, "Please set a default container to create the space in.")
|
||||||
|
|
||||||
def hotkey_S_B(self):
|
def hotkey_S_B(self):
|
||||||
bpy.ops.bim.add_boundary()
|
bpy.ops.bim.add_boundary()
|
||||||
|
|||||||
@@ -94,8 +94,6 @@ def create_project(ifc: tool.Ifc, project: tool.Project, spatial: tool.Spatial,
|
|||||||
if default_container := spatial.guess_default_container():
|
if default_container := spatial.guess_default_container():
|
||||||
spatial.set_default_container(default_container)
|
spatial.set_default_container(default_container)
|
||||||
|
|
||||||
project.create_project_collections()
|
|
||||||
|
|
||||||
if template:
|
if template:
|
||||||
project.append_all_types_from_template(template)
|
project.append_all_types_from_template(template)
|
||||||
|
|
||||||
|
|||||||
@@ -149,8 +149,10 @@ def select_decomposed_elements(spatial):
|
|||||||
spatial.select_products(spatial.get_decomposed_elements(container))
|
spatial.select_products(spatial.get_decomposed_elements(container))
|
||||||
|
|
||||||
|
|
||||||
# HERE STARTS SPATIAL TOOL
|
def generate_space(ifc, model, root, spatial, type):
|
||||||
def generate_space(ifc, spatial, model, Type):
|
if not root.get_default_container():
|
||||||
|
raise NoDefaultContainer()
|
||||||
|
|
||||||
active_obj = spatial.get_active_obj()
|
active_obj = spatial.get_active_obj()
|
||||||
selected_objects = spatial.get_selected_objects()
|
selected_objects = spatial.get_selected_objects()
|
||||||
element = None
|
element = None
|
||||||
@@ -163,18 +165,17 @@ def generate_space(ifc, spatial, model, Type):
|
|||||||
relating_type = None
|
relating_type = None
|
||||||
|
|
||||||
if selected_objects and active_obj:
|
if selected_objects and active_obj:
|
||||||
x, y, z, h, mat = spatial.get_x_y_z_h_mat_from_active_obj(active_obj) ##mat
|
x, y, z, h, mat = spatial.get_x_y_z_h_mat_from_active_obj(active_obj)
|
||||||
element = ifc.get_entity(active_obj)
|
element = ifc.get_entity(active_obj)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
x, y, z, h, mat = spatial.get_x_y_z_h_mat_from_cursor() ##mat
|
x, y, z, h, mat = spatial.get_x_y_z_h_mat_from_cursor()
|
||||||
|
|
||||||
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
space_polygon = spatial.get_space_polygon_from_context_visible_objects(x, y)
|
||||||
|
|
||||||
if not space_polygon:
|
if not space_polygon:
|
||||||
return
|
return
|
||||||
|
|
||||||
bm = spatial.get_bmesh_from_polygon(space_polygon, h=h) ##mat
|
bm = spatial.get_bmesh_from_polygon(space_polygon, h=h)
|
||||||
|
|
||||||
mesh = spatial.get_named_mesh_from_bmesh(name="Space", bmesh=bm)
|
mesh = spatial.get_named_mesh_from_bmesh(name="Space", bmesh=bm)
|
||||||
|
|
||||||
@@ -189,14 +190,15 @@ def generate_space(ifc, spatial, model, Type):
|
|||||||
|
|
||||||
obj = spatial.get_named_obj_from_mesh(name, mesh)
|
obj = spatial.get_named_obj_from_mesh(name, mesh)
|
||||||
spatial.set_obj_origin_to_cursor_position_and_zero_elevation(obj)
|
spatial.set_obj_origin_to_cursor_position_and_zero_elevation(obj)
|
||||||
spatial.traslate_obj_to_z_location(obj, z)
|
spatial.translate_obj_to_z_location(obj, z)
|
||||||
spatial.link_obj_to_active_collection(obj)
|
|
||||||
spatial.assign_ifcspace_class_to_obj(obj)
|
spatial.assign_ifcspace_class_to_obj(obj)
|
||||||
|
|
||||||
element = ifc.get_entity(obj)
|
element = ifc.get_entity(obj)
|
||||||
|
|
||||||
if relating_type:
|
if relating_type:
|
||||||
spatial.assign_relating_type_to_element(ifc, Type, element, relating_type)
|
spatial.assign_relating_type_to_element(ifc, type, element, relating_type)
|
||||||
|
|
||||||
|
spatial.import_spatial_decomposition()
|
||||||
|
|
||||||
|
|
||||||
def generate_spaces_from_walls(ifc, spatial, collector):
|
def generate_spaces_from_walls(ifc, spatial, collector):
|
||||||
@@ -215,7 +217,7 @@ def generate_spaces_from_walls(ifc, spatial, collector):
|
|||||||
obj = spatial.get_named_obj_from_bmesh(name, bmesh=bm)
|
obj = spatial.get_named_obj_from_bmesh(name, bmesh=bm)
|
||||||
|
|
||||||
spatial.set_obj_origin_to_bboxcenter_and_zero_elevation(obj)
|
spatial.set_obj_origin_to_bboxcenter_and_zero_elevation(obj)
|
||||||
spatial.traslate_obj_to_z_location(obj, z)
|
spatial.translate_obj_to_z_location(obj, z)
|
||||||
|
|
||||||
spatial.link_obj_to_active_collection(obj)
|
spatial.link_obj_to_active_collection(obj)
|
||||||
spatial.assign_ifcspace_class_to_obj(obj)
|
spatial.assign_ifcspace_class_to_obj(obj)
|
||||||
@@ -241,3 +243,7 @@ def toggle_hide_spaces(ifc, spatial):
|
|||||||
|
|
||||||
def set_default_container(spatial: tool.Spatial, container: ifcopenshell.entity_instance):
|
def set_default_container(spatial: tool.Spatial, container: ifcopenshell.entity_instance):
|
||||||
spatial.set_default_container(container)
|
spatial.set_default_container(container)
|
||||||
|
|
||||||
|
|
||||||
|
class NoDefaultContainer(Exception):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -593,7 +593,6 @@ class Owner:
|
|||||||
class Project:
|
class Project:
|
||||||
def append_all_types_from_template(cls, template): pass
|
def append_all_types_from_template(cls, template): pass
|
||||||
def create_empty(cls, name): pass
|
def create_empty(cls, name): pass
|
||||||
def create_project_collections(cls): pass
|
|
||||||
def load_default_thumbnails(cls): pass
|
def load_default_thumbnails(cls): pass
|
||||||
def run_aggregate_assign_object(cls, relating_obj=None, related_obj=None): pass
|
def run_aggregate_assign_object(cls, relating_obj=None, related_obj=None): pass
|
||||||
def run_context_add_context(cls, context_type=None, context_identifier=None, target_view=None, parent=None): pass
|
def run_context_add_context(cls, context_type=None, context_identifier=None, target_view=None, parent=None): pass
|
||||||
@@ -891,7 +890,7 @@ class Spatial:
|
|||||||
def get_active_obj_z(cls): pass
|
def get_active_obj_z(cls): pass
|
||||||
def get_active_obj_height(cls): pass
|
def get_active_obj_height(cls): pass
|
||||||
def get_relating_type_id(cls): pass
|
def get_relating_type_id(cls): pass
|
||||||
def traslate_obj_to_z_location(cls, obj): pass
|
def translate_obj_to_z_location(cls, obj): pass
|
||||||
def link_obj_to_active_collection(cls, obj): pass
|
def link_obj_to_active_collection(cls, obj): pass
|
||||||
def get_2d_vertices_from_obj(cls, obj): pass
|
def get_2d_vertices_from_obj(cls, obj): pass
|
||||||
def get_scaled_2d_vertices(cls, points): pass
|
def get_scaled_2d_vertices(cls, points): pass
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
tool.Blender.remove_data_block(obj.data)
|
tool.Blender.remove_data_block(obj.data)
|
||||||
|
|
||||||
if is_spatial:
|
if is_spatial:
|
||||||
blenderbim.core.spatial.load_container_manager(tool.Spatial)
|
blenderbim.core.spatial.import_spatial_decomposition(tool.Spatial)
|
||||||
try:
|
try:
|
||||||
obj.name
|
obj.name
|
||||||
bpy.data.objects.remove(obj)
|
bpy.data.objects.remove(obj)
|
||||||
|
|||||||
@@ -49,11 +49,6 @@ class Project(blenderbim.core.tool.Project):
|
|||||||
def create_empty(cls, name):
|
def create_empty(cls, name):
|
||||||
return bpy.data.objects.new(name, None)
|
return bpy.data.objects.new(name, None)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def create_project_collections(cls):
|
|
||||||
tool.Loader.create_project_collection("Views")
|
|
||||||
tool.Loader.create_project_collection("Types")
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_default_thumbnails(cls):
|
def load_default_thumbnails(cls):
|
||||||
if tool.Ifc.get().by_type("IfcElementType"):
|
if tool.Ifc.get().by_type("IfcElementType"):
|
||||||
|
|||||||
@@ -23,13 +23,12 @@ import ifcopenshell.util.representation
|
|||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import ifcopenshell.util.placement
|
import ifcopenshell.util.placement
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
|
import blenderbim.core.root
|
||||||
import blenderbim.core.aggregate
|
import blenderbim.core.aggregate
|
||||||
import blenderbim.core.geometry
|
import blenderbim.core.geometry
|
||||||
import blenderbim.core.material
|
import blenderbim.core.material
|
||||||
import blenderbim.core.style
|
import blenderbim.core.style
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
from mathutils import Vector
|
|
||||||
from blenderbim.bim.module.model.opening import FilledOpeningGenerator
|
|
||||||
from typing import Union, Optional, Any
|
from typing import Union, Optional, Any
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -359,9 +359,9 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_boundary_lines_from_context_visible_objects(cls):
|
def get_boundary_lines_from_context_visible_objects(cls):
|
||||||
calculation_rl = bpy.context.scene.BIMModelProperties.rl3
|
calculation_rl = bpy.context.scene.BIMModelProperties.rl3
|
||||||
collection = bpy.context.view_layer.active_layer_collection.collection
|
container = tool.Root.get_default_container()
|
||||||
collection_obj = collection.BIMCollectionProperties.obj
|
container_obj = tool.Ifc.get_object(container)
|
||||||
cut_point = collection_obj.matrix_world.translation.copy() + Vector((0, 0, calculation_rl))
|
cut_point = container_obj.matrix_world.translation.copy() + Vector((0, 0, calculation_rl))
|
||||||
cut_normal = Vector((0, 0, 1))
|
cut_normal = Vector((0, 0, 1))
|
||||||
boundary_lines = []
|
boundary_lines = []
|
||||||
|
|
||||||
@@ -461,10 +461,10 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_x_y_z_h_mat_from_cursor(cls):
|
def get_x_y_z_h_mat_from_cursor(cls):
|
||||||
collection = bpy.context.view_layer.active_layer_collection.collection
|
x, y, z = bpy.context.scene.cursor.location.xyz
|
||||||
collection_obj = collection.BIMCollectionProperties.obj
|
if container := tool.Root.get_default_container():
|
||||||
x, y = bpy.context.scene.cursor.location.xy
|
if container_obj := tool.Ifc.get_object(container):
|
||||||
z = collection_obj.matrix_world.translation.z
|
z = container_obj.matrix_world.translation.z
|
||||||
mat = Matrix()
|
mat = Matrix()
|
||||||
h = 3
|
h = 3
|
||||||
return x, y, z, h, mat
|
return x, y, z, h, mat
|
||||||
@@ -614,7 +614,6 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_transformed_mesh_from_local_to_global(cls, mesh):
|
def get_transformed_mesh_from_local_to_global(cls, mesh):
|
||||||
active_obj = cls.get_active_obj()
|
active_obj = cls.get_active_obj()
|
||||||
element = tool.Ifc.get_entity(active_obj)
|
|
||||||
mat = active_obj.matrix_world
|
mat = active_obj.matrix_world
|
||||||
mesh.transform(mat.inverted())
|
mesh.transform(mat.inverted())
|
||||||
mesh.update()
|
mesh.update()
|
||||||
@@ -667,8 +666,6 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
mat = obj.matrix_world
|
mat = obj.matrix_world
|
||||||
inverted = mat.inverted()
|
inverted = mat.inverted()
|
||||||
|
|
||||||
collection = bpy.context.view_layer.active_layer_collection.collection
|
|
||||||
collection_obj = collection.BIMCollectionProperties.obj
|
|
||||||
x, y = bpy.context.scene.cursor.location.xy
|
x, y = bpy.context.scene.cursor.location.xy
|
||||||
z = 0
|
z = 0
|
||||||
|
|
||||||
@@ -706,7 +703,7 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
return relating_type_id
|
return relating_type_id
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def traslate_obj_to_z_location(cls, obj, z):
|
def translate_obj_to_z_location(cls, obj, z):
|
||||||
if z != 0:
|
if z != 0:
|
||||||
obj.location = obj.location + Vector((0, 0, z))
|
obj.location = obj.location + Vector((0, 0, z))
|
||||||
|
|
||||||
@@ -754,9 +751,7 @@ class Spatial(blenderbim.core.tool.Spatial):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_body_representation(cls, obj):
|
def get_body_representation(cls, obj):
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
model = tool.Ifc.get()
|
return ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
||||||
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
|
||||||
return body
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def assign_ifcspace_class_to_obj(cls, obj):
|
def assign_ifcspace_class_to_obj(cls, obj):
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ class TestCreateProject:
|
|||||||
|
|
||||||
project.set_context("body").should_be_called()
|
project.set_context("body").should_be_called()
|
||||||
project.set_active_spatial_element("storey").should_be_called()
|
project.set_active_spatial_element("storey").should_be_called()
|
||||||
project.create_project_collections().should_be_called()
|
|
||||||
|
|
||||||
project.load_default_thumbnails().should_be_called()
|
project.load_default_thumbnails().should_be_called()
|
||||||
project.set_default_context().should_be_called()
|
project.set_default_context().should_be_called()
|
||||||
@@ -127,7 +126,6 @@ class TestCreateProject:
|
|||||||
|
|
||||||
project.set_context("body").should_be_called()
|
project.set_context("body").should_be_called()
|
||||||
project.set_active_spatial_element("storey").should_be_called()
|
project.set_active_spatial_element("storey").should_be_called()
|
||||||
project.create_project_collections().should_be_called()
|
|
||||||
|
|
||||||
project.append_all_types_from_template("template").should_be_called()
|
project.append_all_types_from_template("template").should_be_called()
|
||||||
|
|
||||||
@@ -170,7 +168,6 @@ class TestCreateProject:
|
|||||||
|
|
||||||
project.set_context("body").should_be_called()
|
project.set_context("body").should_be_called()
|
||||||
project.set_active_spatial_element("storey").should_be_called()
|
project.set_active_spatial_element("storey").should_be_called()
|
||||||
project.create_project_collections().should_be_called()
|
|
||||||
|
|
||||||
project.load_default_thumbnails().should_be_called()
|
project.load_default_thumbnails().should_be_called()
|
||||||
project.set_default_context().should_be_called()
|
project.set_default_context().should_be_called()
|
||||||
|
|||||||
Reference in New Issue
Block a user