Reintroduced feature to copy attributes to selected objects.

This commit is contained in:
Dion Moult
2021-10-23 19:55:22 +11:00
parent 295568453c
commit 918915aeae
9 changed files with 106 additions and 48 deletions
@@ -24,6 +24,7 @@ classes = (
operator.DisableEditingAttributes, operator.DisableEditingAttributes,
operator.EditAttributes, operator.EditAttributes,
operator.GenerateGlobalId, operator.GenerateGlobalId,
operator.CopyAttributeToSelection,
prop.BIMAttributeProperties, prop.BIMAttributeProperties,
ui.BIM_PT_object_attributes, ui.BIM_PT_object_attributes,
ui.BIM_PT_material_attributes, ui.BIM_PT_material_attributes,
@@ -20,10 +20,21 @@ import bpy
import json import json
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import blenderbim.bim.helper
import blenderbim.bim.handler
import blenderbim.tool as tool
import blenderbim.core.attribute as core
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.attribute.data import Data from ifcopenshell.api.attribute.data import Data
class Operator:
def execute(self, context):
IfcStore.execute_ifc_operator(self, context)
blenderbim.bim.handler.refresh_ui_data()
return {"FINISHED"}
class EnableEditingAttributes(bpy.types.Operator): class EnableEditingAttributes(bpy.types.Operator):
bl_idname = "bim.enable_editing_attributes" bl_idname = "bim.enable_editing_attributes"
bl_label = "Enable Editing Attributes" bl_label = "Enable Editing Attributes"
@@ -40,22 +51,9 @@ class EnableEditingAttributes(bpy.types.Operator):
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.BIMAttributeProperties props = obj.BIMAttributeProperties
props.attributes.clear() props.attributes.clear()
for attribute in Data.products[oprops.ifc_definition_id]: if oprops.ifc_definition_id not in Data.products:
new = props.attributes.add() Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
if attribute["type"] == "entity" or (attribute["type"] == "list" and attribute["list_type"] == "entity"): blenderbim.bim.helper.import_attributes2(tool.Ifc.get().by_id(oprops.ifc_definition_id), props.attributes)
continue
new.name = attribute["name"]
new.is_null = attribute["is_null"]
if attribute["type"] == "string" or attribute["type"] == "list":
new.string_value = attribute["value"] or ""
elif attribute["type"] == "integer":
new.int_value = attribute["value"] or 0
elif attribute["type"] == "float":
new.float_value = attribute["value"] or 0.0
elif attribute["type"] == "enum":
new.enum_items = json.dumps(attribute["enum_items"])
if attribute["value"]:
new.enum_value = attribute["value"]
props.is_editing_attributes = True props.is_editing_attributes = True
return {"FINISHED"} return {"FINISHED"}
@@ -139,3 +137,14 @@ class GenerateGlobalId(bpy.types.Operator):
global_id.data_type = "string" global_id.data_type = "string"
global_id.string_value = ifcopenshell.guid.new() global_id.string_value = ifcopenshell.guid.new()
return {"FINISHED"} return {"FINISHED"}
class CopyAttributeToSelection(bpy.types.Operator, Operator):
bl_idname = "bim.copy_attribute_to_selection"
bl_label = "Copy Attribute To Selection"
attribute_name: bpy.props.StringProperty()
def _execute(self, context):
value = context.active_object.BIMAttributeProperties.attributes.get(self.attribute_name).get_value()
for obj in context.selected_objects:
core.copy_attribute_to_selection(tool.Ifc, name=self.attribute_name, value=value, obj=obj)
@@ -60,6 +60,9 @@ def draw_ui(context, layout, obj_type):
icon="RADIOBUT_OFF" if blender_attribute.is_null else "RADIOBUT_ON", icon="RADIOBUT_OFF" if blender_attribute.is_null else "RADIOBUT_ON",
text="", text="",
) )
if attribute["name"] != "GlobalId":
op = row.operator("bim.copy_attribute_to_selection", icon="COPYDOWN", text="")
op.attribute_name = attribute["name"]
else: else:
row = layout.row() row = layout.row()
op = row.operator("bim.enable_editing_attributes", icon="GREASEPENCIL", text="Edit") op = row.operator("bim.enable_editing_attributes", icon="GREASEPENCIL", text="Edit")
-31
View File
@@ -456,37 +456,6 @@ class CopyPropertyToSelection(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class CopyAttributeToSelection(bpy.types.Operator):
bl_idname = "bim.copy_attribute_to_selection"
bl_label = "Copy Attribute To Selection"
attribute_name: bpy.props.StringProperty()
attribute_value: bpy.props.StringProperty()
def execute(self, context):
# TODO: this is dead code, awaiting reimplementation. See #1222.
self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(context.scene.BIMProperties.export_schema)
self.applicable_attributes_cache = {}
for obj in context.selected_objects:
if "/" not in obj.name:
continue
attribute = obj.BIMObjectProperties.attributes.get(self.attribute_name)
if not attribute:
applicable_attributes = self.get_applicable_attributes(obj.name.split("/")[0])
if self.attribute_name not in applicable_attributes:
continue
attribute = obj.BIMObjectProperties.attributes.add()
attribute.name = self.attribute_name
attribute.string_value = self.attribute_value
return {"FINISHED"}
def get_applicable_attributes(self, ifc_class):
if ifc_class not in self.applicable_attributes_cache:
self.applicable_attributes_cache[ifc_class] = [
a.name() for a in self.schema.declaration_by_name(ifc_class).all_attributes()
]
return self.applicable_attributes_cache[ifc_class]
class ConfigureVisibility(bpy.types.Operator): class ConfigureVisibility(bpy.types.Operator):
bl_idname = "bim.configure_visibility" bl_idname = "bim.configure_visibility"
bl_label = "Configure module UI visibility in BlenderBIM" bl_label = "Configure module UI visibility in BlenderBIM"
-1
View File
@@ -196,7 +196,6 @@ class Attribute(PropertyGroup):
class ModuleVisibility(PropertyGroup): class ModuleVisibility(PropertyGroup):
name: StringProperty(name="Name") name: StringProperty(name="Name")
is_visible: BoolProperty(name="Value", default=True, update=update_is_visible) is_visible: BoolProperty(name="Value", default=True, update=update_is_visible)
# is_visible: BoolProperty(name="Value", update=update_is_visible)
class BIMProperties(PropertyGroup): class BIMProperties(PropertyGroup):
@@ -0,0 +1,26 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
def copy_attribute_to_selection(ifc, name=None, value=None, obj=None):
element = ifc.get_entity(obj)
if element:
try:
ifc.run("attribute.edit_attributes", product=element, attributes={name: value})
except:
pass
+1
View File
@@ -1,6 +1,7 @@
[pytest] [pytest]
markers = markers =
aggregate aggregate
attribute
bimtester bimtester
context context
geometry geometry
@@ -0,0 +1,19 @@
@attribute
Feature: Attribute
Scenario: Copy attribute to selected
Given an empty IFC project
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 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 object "IfcWall/Cube" is selected
And additionally the object "IfcWall/Cube.001" is selected
And I press "bim.enable_editing_attributes(obj='IfcWall/Cube.001', obj_type='Object')"
And I set "active_object.BIMAttributeProperties.attributes[2].string_value" to "Foo"
When I press "bim.copy_attribute_to_selection(attribute_name='Description')"
Then nothing happens
@@ -0,0 +1,31 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.attribute as subject
from test.core.bootstrap import ifc
class TestCopyAttributeToSelection:
def test_run(self, ifc):
ifc.get_entity("obj").should_be_called().will_return("element")
ifc.run("attribute.edit_attributes", product="element", attributes={"name": "value"}).should_be_called()
subject.copy_attribute_to_selection(ifc, name="name", value="value", obj="obj")
def test_do_nothing_if_object_is_not_an_element(self, ifc):
ifc.get_entity("obj").should_be_called().will_return(None)
subject.copy_attribute_to_selection(ifc, name="name", value="value", obj="obj")