mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-20 12:12:15 +00:00
You can now manage actor assignments to products
This commit is contained in:
@@ -28,6 +28,7 @@ classes = (
|
||||
operator.AddPersonAndOrganisation,
|
||||
operator.AddPersonAttribute,
|
||||
operator.AddRole,
|
||||
operator.AssignActor,
|
||||
operator.ClearUser,
|
||||
operator.DisableEditingActor,
|
||||
operator.DisableEditingAddress,
|
||||
@@ -53,11 +54,13 @@ classes = (
|
||||
operator.RemovePersonAttribute,
|
||||
operator.RemoveRole,
|
||||
operator.SetUser,
|
||||
operator.UnassignActor,
|
||||
prop.BIMOwnerProperties,
|
||||
ui.BIM_PT_people,
|
||||
ui.BIM_PT_organisations,
|
||||
ui.BIM_PT_owner,
|
||||
ui.BIM_PT_actor,
|
||||
ui.BIM_PT_object_actor,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ def refresh():
|
||||
OrganisationsData.is_loaded = False
|
||||
OwnerData.is_loaded = False
|
||||
ActorData.is_loaded = False
|
||||
ObjectActorData.is_loaded = False
|
||||
|
||||
|
||||
class RolesAddressesData:
|
||||
@@ -243,3 +244,46 @@ class ActorData:
|
||||
{"id": actor.id(), "name": actor.Name or "Unnamed", "the_actor": the_actor, "is_editing": is_editing}
|
||||
)
|
||||
return actors
|
||||
|
||||
|
||||
class ObjectActorData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.is_loaded = True
|
||||
cls.data = {
|
||||
"actor": cls.actor(),
|
||||
"actors": cls.actors()
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def actor(cls):
|
||||
return [(str(p.id()), p.Name or "Unnamed", "") for p in tool.Ifc.get().by_type("IfcActor")]
|
||||
|
||||
@classmethod
|
||||
def actors(cls):
|
||||
results = []
|
||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
if not element:
|
||||
return results
|
||||
for rel in getattr(element, "HasAssignments", []):
|
||||
if rel.is_a("IfcRelAssignsToActor"):
|
||||
actor = rel.RelatingActor
|
||||
if actor.TheActor.is_a("IfcPerson"):
|
||||
roles = cls.get_roles(actor.TheActor)
|
||||
elif actor.TheActor.is_a("IfcOrganization"):
|
||||
roles = cls.get_roles(actor.TheActor)
|
||||
elif actor.TheActor.is_a("IfcPersonAndOrganization"):
|
||||
roles = cls.get_roles(actor.TheActor.ThePerson)
|
||||
roles.extend(cls.get_roles(actor.TheActor.TheOrganization))
|
||||
role = ", ".join(roles)
|
||||
results.append({
|
||||
"id": actor.id(), "name": actor.Name or "Unnamed", "role": role, "ifc_class": actor.is_a()
|
||||
})
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def get_roles(cls, parent):
|
||||
return [r.UserDefinedRole or r.Role for r in parent.Roles or []]
|
||||
|
||||
@@ -355,3 +355,27 @@ class RemoveActor(bpy.types.Operator, Operator):
|
||||
|
||||
def _execute(self, context):
|
||||
core.remove_actor(tool.Ifc, actor=tool.Ifc.get().by_id(self.actor))
|
||||
|
||||
|
||||
class AssignActor(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.assign_actor"
|
||||
bl_label = "Assign Actor"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
actor: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
core.assign_actor(
|
||||
tool.Ifc, actor=tool.Ifc.get().by_id(self.actor), element=tool.Ifc.get_entity(context.active_object)
|
||||
)
|
||||
|
||||
|
||||
class UnassignActor(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.unassign_actor"
|
||||
bl_label = "Unassign Actor"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
actor: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
core.unassign_actor(
|
||||
tool.Ifc, actor=tool.Ifc.get().by_id(self.actor), element=tool.Ifc.get_entity(context.active_object)
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
import bpy
|
||||
from blenderbim.bim.prop import StrProperty, Attribute
|
||||
from blenderbim.bim.module.owner.data import OwnerData, ActorData
|
||||
from blenderbim.bim.module.owner.data import OwnerData, ActorData, ObjectActorData
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
@@ -50,6 +50,12 @@ def get_the_actor(self, context):
|
||||
return ActorData.data["the_actor"]
|
||||
|
||||
|
||||
def get_actor(self, context):
|
||||
if not ObjectActorData.is_loaded:
|
||||
ObjectActorData.load()
|
||||
return ObjectActorData.data["actor"]
|
||||
|
||||
|
||||
def update_actor_type(self, context):
|
||||
ActorData.data["the_actor"] = ActorData.the_actor()
|
||||
|
||||
@@ -95,3 +101,4 @@ class BIMOwnerProperties(PropertyGroup):
|
||||
update=update_actor_type,
|
||||
)
|
||||
the_actor: EnumProperty(items=get_the_actor, name="Actor")
|
||||
actor: EnumProperty(items=get_actor, name="Actor")
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import bpy
|
||||
import blenderbim.bim.helper
|
||||
import blenderbim.tool as tool
|
||||
from blenderbim.bim.module.owner.data import PeopleData, OrganisationsData, OwnerData, ActorData
|
||||
from blenderbim.bim.module.owner.data import PeopleData, OrganisationsData, OwnerData, ActorData, ObjectActorData
|
||||
|
||||
|
||||
def draw_roles(box, parent):
|
||||
@@ -281,3 +281,38 @@ class BIM_PT_actor(bpy.types.Panel):
|
||||
row.label(text=actor["the_actor"])
|
||||
row.operator("bim.enable_editing_actor", icon="GREASEPENCIL", text="").actor = actor["id"]
|
||||
row.operator("bim.remove_actor", icon="X", text="").actor = actor["id"]
|
||||
|
||||
|
||||
class BIM_PT_object_actor(bpy.types.Panel):
|
||||
bl_label = "IFC Actor"
|
||||
bl_idname = "BIM_PT_object_actor"
|
||||
bl_options = {"DEFAULT_CLOSED"}
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "object"
|
||||
bl_parent_id = "BIM_PT_misc_object"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
def draw(self, context):
|
||||
if not ObjectActorData.is_loaded:
|
||||
ObjectActorData.load()
|
||||
|
||||
self.props = context.scene.BIMOwnerProperties
|
||||
|
||||
if not ObjectActorData.data["actor"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="No Actors Found", icon="USER")
|
||||
return
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props, "actor", text="")
|
||||
row.operator("bim.assign_actor", icon="ADD", text="").actor = int(self.props.actor)
|
||||
|
||||
for actor in ObjectActorData.data["actors"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=actor["name"], icon="USER")
|
||||
row.label(text=actor["role"])
|
||||
row.operator("bim.unassign_actor", icon="X", text="").actor = actor["id"]
|
||||
|
||||
@@ -165,3 +165,11 @@ def disable_editing_actor(owner):
|
||||
def edit_actor(ifc, owner):
|
||||
ifc.run("owner.edit_actor", actor=owner.get_actor(), attributes=owner.export_actor_attributes())
|
||||
disable_editing_actor(owner)
|
||||
|
||||
|
||||
def assign_actor(ifc, actor=None, element=None):
|
||||
ifc.run("owner.assign_actor", relating_actor=actor, related_object=element)
|
||||
|
||||
|
||||
def unassign_actor(ifc, actor=None, element=None):
|
||||
ifc.run("owner.unassign_actor", relating_actor=actor, related_object=element)
|
||||
|
||||
@@ -277,3 +277,30 @@ Scenario: Edit actor
|
||||
And I press "bim.enable_editing_actor(actor={actor})"
|
||||
When I press "bim.edit_actor"
|
||||
Then "scene.BIMOwnerProperties.active_actor_id" is "0"
|
||||
|
||||
Scenario: Assign actor
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_person"
|
||||
And I press "bim.add_actor"
|
||||
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 the variable "actor" is "{ifc}.by_type('IfcActor')[0].id()"
|
||||
And the object "IfcWall/Cube" is selected
|
||||
When I press "bim.assign_actor(actor={actor})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Unassign actor
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_person"
|
||||
And I press "bim.add_actor"
|
||||
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 the variable "actor" is "{ifc}.by_type('IfcActor')[0].id()"
|
||||
And the object "IfcWall/Cube" is selected
|
||||
And I press "bim.assign_actor(actor={actor})"
|
||||
When I press "bim.unassign_actor(actor={actor})"
|
||||
Then nothing happens
|
||||
|
||||
@@ -259,3 +259,15 @@ class TestEditActor:
|
||||
ifc.run("owner.edit_actor", actor="actor", attributes="attributes").should_be_called()
|
||||
owner.clear_actor().should_be_called()
|
||||
subject.edit_actor(ifc, owner)
|
||||
|
||||
|
||||
class TestAssignActor:
|
||||
def test_run(self, ifc, owner):
|
||||
ifc.run("owner.assign_actor", relating_actor="actor", related_object="element").should_be_called()
|
||||
subject.assign_actor(ifc, actor="actor", element="element")
|
||||
|
||||
|
||||
class TestUnassignActor:
|
||||
def test_run(self, ifc, owner):
|
||||
ifc.run("owner.unassign_actor", relating_actor="actor", related_object="element").should_be_called()
|
||||
subject.unassign_actor(ifc, actor="actor", element="element")
|
||||
|
||||
Reference in New Issue
Block a user