More clever object selection for assigning aggregates #5560

Basically those two properties (Relating Whole and Related Part) are now showing only objects that are valid for the assigning an aggregate - https://i.imgur.com/bqQsXhG.png
This commit is contained in:
Andrej730
2024-10-15 12:28:44 +05:00
parent f17c2eb80e
commit 6c573445dd
+43 -19
View File
@@ -17,6 +17,8 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import ifcopenshell.util.element
import bonsai.tool as tool
from bonsai.bim.prop import StrProperty, Attribute from bonsai.bim.prop import StrProperty, Attribute
from bonsai.bim.module.spatial.data import SpatialData from bonsai.bim.module.spatial.data import SpatialData
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
@@ -32,29 +34,51 @@ from bpy.props import (
) )
def update_relating_object(self, context): def can_aggregate(relating_obj: bpy.types.Object, related_obj: bpy.types.Object) -> bool:
def message(self, context): if related_obj == relating_obj:
self.layout.label(text="Please select a valid IFC Element") return False
# Just a quick way to ignore body representations.
if self.relating_object: if relating_obj.type != "EMPTY":
self.related_object = None return False
if not self.relating_object.BIMObjectProperties.ifc_definition_id: if not tool.Aggregate.can_aggregate(relating_obj, related_obj):
context.window_manager.popup_menu(message, title="Invalid Element Selected", icon="INFO") return False
self.relating_object = None return True
def update_related_object(self, context): def poll_relating_object(self: "BIMObjectAggregateProperties", relating_obj: bpy.types.Object) -> bool:
def message(self, context): if (tool.Ifc.get_entity(relating_obj)) is None:
self.layout.label(text="Please select a valid IFC Element") return False
if self.related_object: for related_obj_ in tool.Blender.get_selected_objects():
self.relating_object = None if not can_aggregate(relating_obj, related_obj_):
if not self.related_object.BIMObjectProperties.ifc_definition_id: return False
context.window_manager.popup_menu(message, title="Invalid Element Selected", icon="INFO") return True
self.related_object = None
def poll_related_object(self: "BIMObjectAggregateProperties", related_obj: bpy.types.Object) -> bool:
if (element := tool.Ifc.get_entity(related_obj)) is None:
return False
aggregate = ifcopenshell.util.element.get_aggregate(element)
if not aggregate:
return False
relating_obj = tool.Ifc.get_object(aggregate)
assert isinstance(relating_obj, bpy.types.Object)
for related_obj_ in tool.Blender.get_selected_objects():
if related_obj_ == related_obj:
return False
if not can_aggregate(relating_obj, related_obj_):
return False
return True
class BIMObjectAggregateProperties(PropertyGroup): class BIMObjectAggregateProperties(PropertyGroup):
is_editing: BoolProperty(name="Is Editing") is_editing: BoolProperty(name="Is Editing")
relating_object: PointerProperty(name="Relating Whole", type=bpy.types.Object, update=update_relating_object) relating_object: PointerProperty(name="Relating Whole", type=bpy.types.Object, poll=poll_relating_object)
related_object: PointerProperty(name="Related Part", type=bpy.types.Object, update=update_related_object) related_object: PointerProperty(
name="Related Part",
description="Related Part, will be used to derive the Relating Object",
type=bpy.types.Object,
poll=poll_related_object,
)