Load spatial tree after new / open project

This commit is contained in:
Dion Moult
2024-06-05 15:47:55 +10:00
parent 18b68353b1
commit 1565575e8b
12 changed files with 83 additions and 49 deletions
+1 -1
View File
@@ -142,7 +142,7 @@ classes = [
ui.BIM_PT_tabs,
# Project overview
ui.BIM_PT_tab_project_info,
ui.BIM_PT_tab_project_tree,
ui.BIM_PT_tab_spatial_decomposition,
ui.BIM_PT_tab_project_setup,
ui.BIM_PT_tab_geometry,
ui.BIM_PT_tab_stakeholders,
@@ -37,6 +37,7 @@ import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape
import blenderbim.tool as tool
import blenderbim.core.spatial
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
from itertools import chain, accumulate
from blenderbim.bim.ifc import IfcStore, IFC_CONNECTED_TYPE
@@ -301,6 +302,7 @@ class IfcImporter:
self.setup_viewport_camera()
self.setup_arrays()
self.profile_code("Setup arrays")
blenderbim.core.spatial.import_spatial_decomposition(tool.Spatial)
self.update_progress(100)
bpy.context.window_manager.progress_end()
@@ -36,6 +36,7 @@ import blenderbim.tool as tool
import blenderbim.core.project as core
import blenderbim.core.context
import blenderbim.core.owner
import blenderbim.core.spatial
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.ui import IFCFileSelector
from blenderbim.bim import import_ifc
@@ -122,6 +123,7 @@ class CreateProject(bpy.types.Operator):
for mat in bpy.data.materials:
bpy.data.materials.remove(mat)
core.create_project(tool.Ifc, tool.Project, schema=props.export_schema, template=template)
blenderbim.core.spatial.import_spatial_decomposition(tool.Spatial)
tool.Blender.register_toolbar()
def rollback(self, data):
@@ -30,7 +30,7 @@ classes = (
operator.EditContainerAttributes,
operator.EnableEditingContainer,
operator.ExpandContainer,
operator.LoadContainerManager,
operator.ImportSpatialDecomposition,
operator.ReferenceStructure,
operator.RemoveContainer,
operator.SelectContainer,
@@ -42,12 +42,12 @@ classes = (
prop.BIMSpatialProperties,
prop.BIMObjectSpatialProperties,
prop.BIMContainer,
prop.BIMProjectTreeProperties,
prop.BIMSpatialDecompositionProperties,
ui.BIM_PT_spatial,
ui.BIM_UL_containers,
ui.BIM_UL_containers_manager,
ui.BIM_UL_elements,
ui.BIM_PT_project_tree,
ui.BIM_PT_spatial_decomposition,
workspace.Hotkey,
)
@@ -57,7 +57,7 @@ def register():
bpy.utils.register_tool(workspace.SpatialTool, after={"bim.annotation_tool"}, separator=False, group=False)
bpy.types.Scene.BIMSpatialProperties = bpy.props.PointerProperty(type=prop.BIMSpatialProperties)
bpy.types.Object.BIMObjectSpatialProperties = bpy.props.PointerProperty(type=prop.BIMObjectSpatialProperties)
bpy.types.Scene.BIMProjectTreeProperties = bpy.props.PointerProperty(type=prop.BIMProjectTreeProperties)
bpy.types.Scene.BIMSpatialDecompositionProperties = bpy.props.PointerProperty(type=prop.BIMSpatialDecompositionProperties)
def unregister():
@@ -65,4 +65,4 @@ def unregister():
bpy.utils.unregister_tool(workspace.SpatialTool)
del bpy.types.Scene.BIMSpatialProperties
del bpy.types.Object.BIMObjectSpatialProperties
del bpy.types.Scene.BIMProjectTreeProperties
del bpy.types.Scene.BIMSpatialDecompositionProperties
@@ -23,7 +23,7 @@ import ifcopenshell.util.element
def refresh():
SpatialData.is_loaded = False
ProjectTreeData.is_loaded = False
SpatialDecompositionData.is_loaded = False
class SpatialData:
@@ -84,7 +84,7 @@ class SpatialData:
return bool(getattr(tool.Ifc.get_entity(bpy.context.active_object), "ContainedInStructure", False))
class ProjectTreeData:
class SpatialDecompositionData:
data = {}
is_loaded = False
@@ -98,7 +98,7 @@ class ProjectTreeData:
@classmethod
def subelement_class(cls):
results = []
props = bpy.context.scene.BIMProjectTreeProperties
props = bpy.context.scene.BIMSpatialDecompositionProperties
if not (container := props.active_container):
return results
container_class = tool.Ifc.get().by_id(container.ifc_definition_id).is_a()
@@ -175,13 +175,13 @@ class SelectProduct(bpy.types.Operator):
return {"FINISHED"}
class LoadContainerManager(bpy.types.Operator):
bl_idname = "bim.load_container_manager"
class ImportSpatialDecomposition(bpy.types.Operator):
bl_idname = "bim.import_spatial_decomposition"
bl_label = "Load Container Manager"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
core.load_container_manager(tool.Spatial)
core.import_spatial_decomposition(tool.Spatial)
return {"FINISHED"}
@@ -18,7 +18,7 @@
import bpy
from blenderbim.bim.prop import StrProperty, Attribute
from blenderbim.bim.module.spatial.data import ProjectTreeData
from blenderbim.bim.module.spatial.data import SpatialDecompositionData
from bpy.types import PropertyGroup
from bpy.props import (
PointerProperty,
@@ -35,9 +35,9 @@ import ifcopenshell
def get_subelement_class(self, context):
if not ProjectTreeData.is_loaded:
ProjectTreeData.load()
return ProjectTreeData.data["subelement_class"]
if not SpatialDecompositionData.is_loaded:
SpatialDecompositionData.load()
return SpatialDecompositionData.data["subelement_class"]
def update_elevation(self, context):
@@ -55,7 +55,7 @@ def update_name(self, context):
def update_active_container_index(self, context):
ProjectTreeData.data["subelement_class"] = ProjectTreeData.subelement_class()
SpatialDecompositionData.data["subelement_class"] = SpatialDecompositionData.subelement_class()
tool.Spatial.load_contained_elements()
@@ -122,7 +122,7 @@ class Element(PropertyGroup):
total: IntProperty(name="Total")
class BIMProjectTreeProperties(PropertyGroup):
class BIMSpatialDecompositionProperties(PropertyGroup):
containers: CollectionProperty(name="Containers", type=BIMContainer)
contracted_containers: StringProperty(name="Contracted containers", default="[]")
expanded_containers: StringProperty(name="Expanded containers", default="[]")
@@ -17,7 +17,7 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
from bpy.types import Panel, UIList
from blenderbim.bim.module.spatial.data import SpatialData, ProjectTreeData
from blenderbim.bim.module.spatial.data import SpatialData, SpatialDecompositionData
import blenderbim.tool as tool
@@ -91,13 +91,13 @@ class BIM_UL_containers(UIList):
)
class BIM_PT_project_tree(Panel):
bl_label = "Project Tree"
bl_idname = "BIM_PT_project_tree"
class BIM_PT_spatial_decomposition(Panel):
bl_label = "Spatial Decomposition"
bl_idname = "BIM_PT_spatial_decomposition"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
bl_parent_id = "BIM_PT_tab_project_tree"
bl_parent_id = "BIM_PT_tab_spatial_decomposition"
bl_options = {"HIDE_HEADER"}
@classmethod
@@ -105,9 +105,9 @@ class BIM_PT_project_tree(Panel):
return tool.Ifc.get()
def draw(self, context):
if not ProjectTreeData.is_loaded:
ProjectTreeData.load()
self.props = context.scene.BIMProjectTreeProperties
if not SpatialDecompositionData.is_loaded:
SpatialDecompositionData.load()
self.props = context.scene.BIMSpatialDecompositionProperties
if self.props.active_container:
row = self.layout.row(align=True)
@@ -115,7 +115,7 @@ class BIM_PT_project_tree(Panel):
text=f"Active: {self.props.active_container.name}",
icon="OUTLINER_COLLECTION",
)
row.operator("bim.load_container_manager", icon="FILE_REFRESH", text="")
row.operator("bim.import_spatial_decomposition", icon="FILE_REFRESH", text="")
if self.props.active_container.ifc_class != "IfcProject":
row = self.layout.row(align=True)
@@ -132,7 +132,7 @@ class BIM_PT_project_tree(Panel):
else:
row = self.layout.row(align=True)
row.label(text="Warning: No Active Container", icon="ERROR")
row.operator("bim.load_container_manager", icon="FILE_REFRESH", text="")
row.operator("bim.import_spatial_decomposition", icon="FILE_REFRESH", text="")
self.layout.template_list(
"BIM_UL_containers_manager",
+3 -3
View File
@@ -440,15 +440,15 @@ class BIM_PT_tab_project_info(Panel):
pass
class BIM_PT_tab_project_tree(Panel):
bl_label = "Project Tree"
class BIM_PT_tab_spatial_decomposition(Panel):
bl_label = "Spatial Decomposition"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
@classmethod
def poll(cls, context):
return tool.Blender.is_tab(context, "PROJECT")
return tool.Blender.is_tab(context, "PROJECT") and tool.Ifc.get()
def draw(self, context):
pass
+6 -6
View File
@@ -120,28 +120,28 @@ def select_product(spatial, product):
spatial.select_products([product])
def load_container_manager(spatial):
spatial.load_container_manager()
def import_spatial_decomposition(spatial):
spatial.import_spatial_decomposition()
def edit_container_attributes(spatial, entity=None):
spatial.edit_container_attributes(entity)
spatial.load_container_manager()
spatial.import_spatial_decomposition()
def contract_container(spatial, container=None):
spatial.contract_container(container)
spatial.load_container_manager()
spatial.import_spatial_decomposition()
def expand_container(spatial, container=None):
spatial.expand_container(container)
spatial.load_container_manager()
spatial.import_spatial_decomposition()
def delete_container(ifc, spatial, geometry, container=None):
geometry.delete_ifc_object(ifc.get_object(container))
spatial.load_container_manager()
spatial.import_spatial_decomposition()
def select_decomposed_elements(spatial):
+1 -1
View File
@@ -848,7 +848,7 @@ class Spatial:
def get_selected_product_types(cls): pass
def get_selected_products(cls): pass
def import_containers(cls, parent=None): pass
def load_container_manager(cls): pass
def import_spatial_decomposition(cls): pass
def run_root_copy_class(cls, obj=None): pass
def run_spatial_assign_container(cls, structure_obj=None, element_obj=None): pass
def select_object(cls, obj): pass
+41 -11
View File
@@ -208,7 +208,7 @@ class Spatial(blenderbim.core.tool.Spatial):
@classmethod
def load_contained_elements(cls):
props = bpy.context.scene.BIMProjectTreeProperties
props = bpy.context.scene.BIMSpatialDecompositionProperties
props.elements.clear()
if not (container := props.active_container):
return
@@ -241,17 +241,17 @@ class Spatial(blenderbim.core.tool.Spatial):
props.total_elements = total_elements
@classmethod
def load_container_manager(cls):
props = bpy.context.scene.BIMProjectTreeProperties
def import_spatial_decomposition(cls):
props = bpy.context.scene.BIMSpatialDecompositionProperties
previous_container_index = props.active_container_index
props.containers.clear()
cls.contracted_containers = json.loads(props.contracted_containers)
cls.import_spatial_structure(tool.Ifc.get().by_type("IfcProject")[0], 0)
cls.import_spatial_element(tool.Ifc.get().by_type("IfcProject")[0], 0)
props.active_container_index = min(previous_container_index, len(props.containers) - 1)
@classmethod
def import_spatial_structure(cls, element, level_index):
props = bpy.context.scene.BIMProjectTreeProperties
def import_spatial_element(cls, element, level_index):
props = bpy.context.scene.BIMSpatialDecompositionProperties
new = props.containers.add()
new.ifc_class = element.is_a()
new.name = element.Name or "Unnamed"
@@ -266,14 +266,14 @@ class Spatial(blenderbim.core.tool.Spatial):
new.ifc_definition_id = element.id()
if new.is_expanded:
for child in children or []:
cls.import_spatial_structure(child, level_index + 1)
cls.import_spatial_element(child, level_index + 1)
@classmethod
def edit_container_attributes(cls, entity):
# TODO
obj = tool.Ifc.get_object(entity)
blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
name = bpy.context.scene.BIMProjectTreeProperties.container_name
name = bpy.context.scene.BIMSpatialDecompositionProperties.container_name
if name != entity.Name:
cls.edit_container_name(entity, name)
@@ -283,21 +283,21 @@ class Spatial(blenderbim.core.tool.Spatial):
@classmethod
def get_active_container(cls):
props = bpy.context.scene.BIMProjectTreeProperties
props = bpy.context.scene.BIMSpatialDecompositionProperties
if props.active_container_index < len(props.containers):
container = tool.Ifc.get().by_id(props.containers[props.active_container_index].ifc_definition_id)
return container
@classmethod
def contract_container(cls, container):
props = bpy.context.scene.BIMProjectTreeProperties
props = bpy.context.scene.BIMSpatialDecompositionProperties
contracted_containers = json.loads(props.contracted_containers)
contracted_containers.append(container.id())
props.contracted_containers = json.dumps(contracted_containers)
@classmethod
def expand_container(cls, container):
props = bpy.context.scene.BIMProjectTreeProperties
props = bpy.context.scene.BIMSpatialDecompositionProperties
contracted_containers = json.loads(props.contracted_containers)
contracted_containers.remove(container.id())
props.contracted_containers = json.dumps(contracted_containers)
@@ -322,6 +322,36 @@ class Spatial(blenderbim.core.tool.Spatial):
space_polygon = shapely.force_3d(polygon)
return space_polygon
@classmethod
def debug_shape(cls, foo):
coords = [(p[0], p[1], 0) for p in foo.exterior.coords]
mesh = bpy.data.meshes.new(name="NewMesh")
bm = bmesh.new()
for coord in coords:
bm.verts.new(coord)
bm.verts.ensure_lookup_table()
bm.faces.new(bm.verts)
bm.to_mesh(mesh)
bm.free()
obj = bpy.data.objects.new("NewObject", mesh)
bpy.context.collection.objects.link(obj)
bpy.context.view_layer.update()
@classmethod
def debug_line(cls, start, end):
coords = [start, end]
mesh = bpy.data.meshes.new(name="NewMesh")
bm = bmesh.new()
for coord in coords:
bm.verts.new(coord)
bm.verts.ensure_lookup_table()
bm.edges.new(bm.verts)
bm.to_mesh(mesh)
bm.free()
obj = bpy.data.objects.new("NewLine", mesh)
bpy.context.collection.objects.link(obj)
bpy.context.view_layer.update()
@classmethod
def get_boundary_lines_from_context_visible_objects(cls):
calculation_rl = bpy.context.scene.BIMModelProperties.rl3