mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 23:20:56 +00:00
Fix #6060. Updating long name in spatial manager now also edits attribute for convenience.
Editing attributes now also refreshes the spatial manager (i.e. vice versa), and so does bulk attribute copying.
This commit is contained in:
@@ -19,12 +19,13 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import json
|
import json
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api.attribute
|
||||||
import ifcopenshell.guid
|
import ifcopenshell.guid
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import bonsai.bim.helper
|
import bonsai.bim.helper
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
import bonsai.core.attribute as core
|
import bonsai.core.attribute as core
|
||||||
|
import bonsai.core.spatial
|
||||||
from bonsai.bim.ifc import IfcStore
|
from bonsai.bim.ifc import IfcStore
|
||||||
|
|
||||||
|
|
||||||
@@ -112,20 +113,14 @@ class DisableEditingAttributes(bpy.types.Operator):
|
|||||||
class EditAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
class EditAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.edit_attributes"
|
bl_idname = "bim.edit_attributes"
|
||||||
bl_label = "Edit Attributes"
|
bl_label = "Edit Attributes"
|
||||||
bl_description = "ALT + Left Click to edit attributes on all selected objects"
|
bl_description = "Edit the attributes of the active object"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
obj: bpy.props.StringProperty(options={"SKIP_SAVE"})
|
|
||||||
mass_operation: bpy.props.BoolProperty(default=False, options={"SKIP_SAVE"})
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def _execute(self, context):
|
||||||
self.mass_operation = event.alt
|
self.file = IfcStore.get_file()
|
||||||
return self.execute(context)
|
obj = tool.Blender.get_active_object(is_selected=False)
|
||||||
|
if not (element := tool.Ifc.get_entity(obj)):
|
||||||
def edit_attributes_on_obj(self, obj):
|
return
|
||||||
props = obj.BIMAttributeProperties
|
|
||||||
product = tool.Ifc.get_entity(obj)
|
|
||||||
assert product
|
|
||||||
object_name = tool.Loader.get_name(product)
|
|
||||||
|
|
||||||
def callback(attributes, prop):
|
def callback(attributes, prop):
|
||||||
if prop.name in ("RefLatitude", "RefLongitude"):
|
if prop.name in ("RefLatitude", "RefLongitude"):
|
||||||
@@ -136,17 +131,15 @@ class EditAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
attributes[prop.name] = None
|
attributes[prop.name] = None
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
props = obj.BIMAttributeProperties
|
||||||
attributes = bonsai.bim.helper.export_attributes(props.attributes, callback=callback)
|
attributes = bonsai.bim.helper.export_attributes(props.attributes, callback=callback)
|
||||||
ifcopenshell.api.run("attribute.edit_attributes", self.file, product=product, attributes=attributes)
|
ifcopenshell.api.attribute.edit_attributes(self.file, product=element, attributes=attributes)
|
||||||
|
|
||||||
tool.Root.set_object_name(obj, product)
|
tool.Root.set_object_name(obj, element)
|
||||||
bpy.ops.bim.disable_editing_attributes(obj=obj.name)
|
bpy.ops.bim.disable_editing_attributes(obj=obj.name)
|
||||||
|
|
||||||
def _execute(self, context):
|
if tool.Root.is_spatial_element(element):
|
||||||
self.file = IfcStore.get_file()
|
bonsai.core.spatial.import_spatial_decomposition(tool.Spatial)
|
||||||
for obj in get_objs_for_operation(self, context):
|
|
||||||
self.edit_attributes_on_obj(obj)
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateGlobalId(bpy.types.Operator, tool.Ifc.Operator):
|
class GenerateGlobalId(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -195,14 +188,12 @@ class GenerateGlobalId(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
class CopyAttributeToSelection(bpy.types.Operator, tool.Ifc.Operator):
|
class CopyAttributeToSelection(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.copy_attribute_to_selection"
|
bl_idname = "bim.copy_attribute_to_selection"
|
||||||
bl_label = "Copy Attribute To Selection"
|
bl_label = "Copy Attribute To Selection"
|
||||||
name: bpy.props.StringProperty()
|
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
name: bpy.props.StringProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
value = context.active_object.BIMAttributeProperties.attributes.get(self.name).get_value()
|
value = tool.Blender.get_active_object().BIMAttributeProperties.attributes.get(self.name).get_value()
|
||||||
i = 0
|
total = core.copy_attribute_to_selection(
|
||||||
for obj in tool.Blender.get_selected_objects():
|
tool.Ifc, tool.Blender, tool.Root, tool.Spatial, name=self.name, value=value
|
||||||
success = core.copy_attribute_to_selection(tool.Ifc, tool.Root, name=self.name, value=value, obj=obj)
|
)
|
||||||
if success:
|
self.report({"INFO"}, f"Attribute was successfully copied to {total} elements.")
|
||||||
i += 1
|
|
||||||
self.report({"INFO"}, f"Attribute was successfully copied to {i} elements.")
|
|
||||||
|
|||||||
@@ -25,13 +25,12 @@ import bonsai.tool as tool
|
|||||||
|
|
||||||
def draw_ui(context, layout, attributes):
|
def draw_ui(context, layout, attributes):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
oprops = obj.BIMObjectProperties
|
|
||||||
props = obj.BIMAttributeProperties
|
props = obj.BIMAttributeProperties
|
||||||
|
|
||||||
if props.is_editing_attributes:
|
if props.is_editing_attributes:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
op = row.operator("bim.edit_attributes", icon="CHECKMARK", text="Save Attributes")
|
row.operator("bim.edit_attributes", icon="CHECKMARK", text="Save Attributes")
|
||||||
op = row.operator("bim.disable_editing_attributes", icon="CANCEL", text="")
|
row.operator("bim.disable_editing_attributes", icon="CANCEL", text="")
|
||||||
|
|
||||||
bonsai.bim.helper.draw_attributes(props.attributes, layout, copy_operator="bim.copy_attribute_to_selection")
|
bonsai.bim.helper.draw_attributes(props.attributes, layout, copy_operator="bim.copy_attribute_to_selection")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -65,7 +65,14 @@ def update_name(self: "BIMContainer", context: bpy.types.Context) -> None:
|
|||||||
element = tool.Ifc.get().by_id(ifc_definition_id)
|
element = tool.Ifc.get().by_id(ifc_definition_id)
|
||||||
tool.Spatial.edit_container_name(element, self.name)
|
tool.Spatial.edit_container_name(element, self.name)
|
||||||
if obj := tool.Ifc.get_object(element):
|
if obj := tool.Ifc.get_object(element):
|
||||||
obj.name = tool.Loader.get_name(element)
|
tool.Root.set_object_name(obj, element)
|
||||||
|
bonsai.bim.handler.refresh_ui_data()
|
||||||
|
|
||||||
|
|
||||||
|
def update_long_name(self: "BIMContainer", context: bpy.types.Context) -> None:
|
||||||
|
if ifc_definition_id := self.ifc_definition_id:
|
||||||
|
element = tool.Ifc.get().by_id(ifc_definition_id)
|
||||||
|
tool.Ifc.run("attribute.edit_attributes", product=element, attributes={"LongName": self.long_name})
|
||||||
bonsai.bim.handler.refresh_ui_data()
|
bonsai.bim.handler.refresh_ui_data()
|
||||||
|
|
||||||
|
|
||||||
@@ -148,7 +155,7 @@ class BIMContainer(PropertyGroup):
|
|||||||
name: StringProperty(name="Name", update=update_name)
|
name: StringProperty(name="Name", update=update_name)
|
||||||
ifc_class: StringProperty(name="IFC Class")
|
ifc_class: StringProperty(name="IFC Class")
|
||||||
description: StringProperty(name="Description")
|
description: StringProperty(name="Description")
|
||||||
long_name: StringProperty(name="Long Name")
|
long_name: StringProperty(name="Long Name", update=update_long_name)
|
||||||
elevation: StringProperty(name="Elevation", update=update_elevation)
|
elevation: StringProperty(name="Elevation", update=update_elevation)
|
||||||
level_index: IntProperty(name="Level Index")
|
level_index: IntProperty(name="Level Index")
|
||||||
has_children: BoolProperty(name="Has Children")
|
has_children: BoolProperty(name="Has Children")
|
||||||
|
|||||||
@@ -26,14 +26,21 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
def copy_attribute_to_selection(
|
def copy_attribute_to_selection(
|
||||||
ifc: tool.Ifc, root: tool.Root, name: str, value: Union[str, None], obj: bpy.types.Object
|
ifc: tool.Ifc, blender: tool.Blender, root: tool.Root, spatial: tool.Spatial, name: str, value: Union[str, None]
|
||||||
) -> bool:
|
) -> int:
|
||||||
if element := ifc.get_entity(obj):
|
total_changed = 0
|
||||||
try:
|
has_edited_spatial_name = False
|
||||||
ifc.run("attribute.edit_attributes", product=element, attributes={name: value})
|
for obj in blender.get_selected_objects(include_active=False):
|
||||||
if name in ("Name", "AxisTag"):
|
if element := ifc.get_entity(obj):
|
||||||
root.set_object_name(obj, element)
|
try:
|
||||||
return True
|
ifc.run("attribute.edit_attributes", product=element, attributes={name: value})
|
||||||
except:
|
if name in ("Name", "AxisTag"):
|
||||||
pass
|
root.set_object_name(obj, element)
|
||||||
return False
|
if name in ("Name", "LongName") and root.is_spatial_element(element):
|
||||||
|
has_edited_spatial_name = True
|
||||||
|
total_changed += 1
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if has_edited_spatial_name:
|
||||||
|
spatial.import_spatial_decomposition()
|
||||||
|
return total_changed
|
||||||
|
|||||||
Reference in New Issue
Block a user