You can now add ports to distribution elements in Blender.

This commit is contained in:
Dion Moult
2022-02-01 19:16:13 +11:00
parent f9ce0903f7
commit 10138e28c9
12 changed files with 182 additions and 12 deletions
@@ -20,6 +20,7 @@ import bpy
from . import ui, prop, operator
classes = (
operator.AddPort,
operator.AddSystem,
operator.AssignSystem,
operator.DisableEditingSystem,
@@ -25,6 +25,7 @@ import blenderbim.tool as tool
def refresh():
SystemData.is_loaded = False
ObjectSystemData.is_loaded = False
PortData.is_loaded = False
class SystemData:
@@ -150,3 +150,12 @@ class HidePorts(bpy.types.Operator, Operator):
def _execute(self, context):
core.hide_ports(tool.System, element=tool.Ifc.get_entity(context.active_object))
class AddPort(bpy.types.Operator, Operator):
bl_idname = "bim.add_port"
bl_label = "Add Ports"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
core.add_port(tool.Ifc, tool.System, element=tool.Ifc.get_entity(context.active_object))
@@ -153,6 +153,7 @@ class BIM_PT_ports(Panel):
row.label(text=f"{PortData.data['total_ports']} Ports Found", icon="PLUGIN")
row.operator("bim.show_ports", icon="HIDE_OFF", text="")
row.operator("bim.hide_ports", icon="HIDE_ON", text="")
row.operator("bim.add_port", icon="ADD", text="")
class BIM_UL_systems(UIList):
+7
View File
@@ -74,3 +74,10 @@ def show_ports(system, element=None):
def hide_ports(system, element=None):
system.delete_element_objects(system.get_ports(element))
def add_port(ifc, system, element=None):
system.load_ports(system.get_ports(element))
obj = system.create_empty_at_cursor_with_element_orientation(element)
port = system.run_root_assign_class(obj=obj, ifc_class="IfcDistributionPort")
ifc.run("system.assign_port", element=element, port=port)
+2
View File
@@ -380,6 +380,7 @@ class Surveyor:
@interface
class System:
def create_empty_at_cursor_with_element_orientation(cls, element): pass
def delete_element_objects(cls, elements): pass
def disable_editing_system(cls): pass
def disable_system_editing_ui(cls): pass
@@ -389,6 +390,7 @@ class System:
def import_system_attributes(cls, system): pass
def import_systems(cls): pass
def load_ports(cls, port): pass
def run_root_assign_class(cls, obj=None, ifc_class=None, predefined_type=None, should_add_representation=True, context=None, ifc_representation_class=None): pass
def select_elements(cls, elements): pass
def select_system_products(cls, system): pass
def set_active_system(cls, system): pass
+9 -1
View File
@@ -199,7 +199,15 @@ class Drawing(blenderbim.core.tool.Drawing):
)
@classmethod
def run_root_assign_class(cls, obj=None, ifc_class=None, predefined_type=None, should_add_representation=True, context=None, ifc_representation_class=None):
def run_root_assign_class(
cls,
obj=None,
ifc_class=None,
predefined_type=None,
should_add_representation=True,
context=None,
ifc_representation_class=None,
):
return blenderbim.core.root.assign_class(
tool.Ifc,
tool.Collector,
+35 -3
View File
@@ -24,6 +24,15 @@ from blenderbim.bim import import_ifc
class System(blenderbim.core.tool.System):
@classmethod
def create_empty_at_cursor_with_element_orientation(cls, element):
element_obj = tool.Ifc.get_object(element)
obj = bpy.data.objects.new("Port", None)
obj.matrix_world = element_obj.matrix_world
obj.matrix_world.translation = bpy.context.scene.cursor.matrix.translation
bpy.context.scene.collection.objects.link(obj)
return obj
@classmethod
def delete_element_objects(cls, elements):
for element in elements:
@@ -77,11 +86,34 @@ class System(blenderbim.core.tool.System):
ifc_importer.calculate_unit_scale()
ports = set(ports)
ports -= ifc_importer.create_products(ports)
if ports:
for port in ports:
ifc_importer.create_product(port)
for port in ports or []:
if tool.Ifc.get_object(port):
continue
ifc_importer.create_product(port)
ifc_importer.place_objects_in_collections()
@classmethod
def run_root_assign_class(
cls,
obj=None,
ifc_class=None,
predefined_type=None,
should_add_representation=True,
context=None,
ifc_representation_class=None,
):
return blenderbim.core.root.assign_class(
tool.Ifc,
tool.Collector,
tool.Root,
obj=obj,
ifc_class=ifc_class,
predefined_type=predefined_type,
should_add_representation=should_add_representation,
context=context,
ifc_representation_class=ifc_representation_class,
)
@classmethod
def select_elements(cls, elements):
for element in elements:
+10
View File
@@ -103,3 +103,13 @@ class TestHidePorts:
system.get_ports("element").should_be_called().will_return(["port"])
system.delete_element_objects(["port"]).should_be_called()
subject.hide_ports(system, element="element")
class TestAddPort:
def test_run(self, ifc, system):
system.get_ports("element").should_be_called().will_return(["port"])
system.load_ports(["port"]).should_be_called()
system.create_empty_at_cursor_with_element_orientation("element").should_be_called().will_return("obj")
system.run_root_assign_class(obj="obj", ifc_class="IfcDistributionPort").should_be_called().will_return("port")
ifc.run("system.assign_port", element="element", port="port").should_be_called()
subject.add_port(ifc, system, element="element")
+17
View File
@@ -29,6 +29,18 @@ class TestImplementsTool(NewFile):
assert isinstance(subject(), blenderbim.core.tool.System)
class TestCreateEmptyAtCursorWithElementOrientation(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc().set(ifc)
obj = bpy.data.objects.new("Object", None)
element = ifc.createIfcWall()
tool.Ifc.link(element, obj)
bpy.context.scene.cursor.matrix.translation[0] = 5
obj = subject.create_empty_at_cursor_with_element_orientation(element)
assert obj.matrix_world.translation[0] == 5
class TestDeleteElementObjects(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
@@ -164,6 +176,11 @@ class TestLoadPorts(NewFile):
assert list(obj.location) == [0, 0, 0]
class TestRunAssignClassOperator(NewFile):
def test_nothing(self):
pass
class TestSelectElements(NewFile):
def test_run(self):
ifc = ifcopenshell.file()