mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
WIP migrate attribute management to partial editing with 4 new features! See #1222.
New features include: - New clarity between null and empty string attributes - Attribute editing now shows appropriate UI widgets depending on data type - Attribute editing for enumerations now show a dropdown - Attribute editing is now schema sensitive
This commit is contained in:
@@ -6,6 +6,7 @@ bpy = sys.modules.get("bpy")
|
||||
if bpy is not None:
|
||||
import bpy
|
||||
import blenderbim.bim.module.root as module_root
|
||||
import blenderbim.bim.module.attribute as module_attribute
|
||||
import blenderbim.bim.module.bcf as module_bcf
|
||||
import blenderbim.bim.module.context as module_context
|
||||
import blenderbim.bim.module.covetool as module_covetool
|
||||
@@ -87,8 +88,6 @@ if bpy is not None:
|
||||
operator.UnassignDocumentReference,
|
||||
operator.RemoveObjectDocumentReference,
|
||||
operator.GenerateGlobalId,
|
||||
operator.AddAttribute,
|
||||
operator.RemoveAttribute,
|
||||
operator.AddMaterialAttribute,
|
||||
operator.RemoveMaterialAttribute,
|
||||
operator.QuickProjectSetup,
|
||||
@@ -312,6 +311,7 @@ if bpy is not None:
|
||||
]
|
||||
|
||||
classes.extend(module_root.classes)
|
||||
classes.extend(module_attribute.classes)
|
||||
classes.extend(module_bcf.classes)
|
||||
classes.extend(module_context.classes)
|
||||
classes.extend(module_covetool.classes)
|
||||
@@ -350,6 +350,7 @@ if bpy is not None:
|
||||
bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties)
|
||||
bpy.types.SCENE_PT_unit.append(ui.ifc_units)
|
||||
module_root.register()
|
||||
module_attribute.register()
|
||||
module_bcf.register()
|
||||
module_context.register()
|
||||
module_covetool.register()
|
||||
@@ -382,5 +383,6 @@ if bpy is not None:
|
||||
module_covetool.unregister()
|
||||
module_context.unregister()
|
||||
module_bcf.unregister()
|
||||
module_attribute.register()
|
||||
module_root.unregister()
|
||||
bpy.app.handlers.depsgraph_update_pre.remove(operator.depsgraph_update_pre_handler)
|
||||
|
||||
@@ -847,7 +847,6 @@ class IfcImporter:
|
||||
obj = bpy.data.objects.new(self.get_name(element), mesh)
|
||||
obj.BIMObjectProperties.ifc_definition_id = element.id()
|
||||
self.material_creator.create(element, obj, mesh)
|
||||
self.add_element_attributes(element, obj.BIMObjectProperties)
|
||||
self.add_element_classifications(element, obj)
|
||||
self.add_element_document_relations(element, obj)
|
||||
self.add_type_product_psets(element, obj)
|
||||
@@ -975,7 +974,6 @@ class IfcImporter:
|
||||
obj.matrix_world = self.get_element_matrix(element)
|
||||
|
||||
self.add_element_representation_items(element, obj)
|
||||
self.add_element_attributes(element, obj.BIMObjectProperties)
|
||||
self.add_element_classifications(element, obj)
|
||||
self.add_element_document_relations(element, obj)
|
||||
self.add_defines_by_type_relation(element, obj)
|
||||
@@ -1732,7 +1730,6 @@ class IfcImporter:
|
||||
obj.instance_type = "COLLECTION"
|
||||
obj.instance_collection = collection
|
||||
self.place_object_in_spatial_tree(element, obj)
|
||||
self.add_element_attributes(element, obj.BIMObjectProperties)
|
||||
self.add_element_classifications(element, obj)
|
||||
self.add_element_document_relations(element, obj)
|
||||
self.add_defines_by_type_relation(element, obj)
|
||||
@@ -1795,7 +1792,6 @@ class IfcImporter:
|
||||
obj.BIMObjectProperties.ifc_definition_id = element.id()
|
||||
self.material_creator.create(element, obj, mesh)
|
||||
obj.matrix_world = self.get_element_matrix(element, mesh_name)
|
||||
self.add_element_attributes(element, obj.BIMObjectProperties)
|
||||
self.add_element_classifications(element, obj)
|
||||
self.add_element_document_relations(element, obj)
|
||||
self.add_defines_by_type_relation(element, obj)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import bpy
|
||||
from . import ui, operator
|
||||
|
||||
classes = (
|
||||
operator.EnableEditingAttributes,
|
||||
operator.DisableEditingAttributes,
|
||||
operator.EditAttributes,
|
||||
ui.BIM_PT_attributes,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
pass
|
||||
|
||||
|
||||
def unregister():
|
||||
pass
|
||||
@@ -0,0 +1,58 @@
|
||||
import ifcopenshell
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
|
||||
class Data:
|
||||
products = {}
|
||||
|
||||
@classmethod
|
||||
def load(cls, product_id):
|
||||
file = IfcStore.get_file()
|
||||
if not file:
|
||||
return
|
||||
product = file.by_id(product_id)
|
||||
cls.products[product_id] = []
|
||||
attributes = product.get_info()
|
||||
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(file.schema)
|
||||
declaration = schema.declaration_by_name(product.is_a())
|
||||
for attribute in declaration.all_attributes():
|
||||
data_type = str(attribute.type_of_attribute())
|
||||
value = getattr(product, attribute.name())
|
||||
list_type = None
|
||||
enum_items = ()
|
||||
if "<entity" in data_type:
|
||||
data_type = "entity"
|
||||
value = None if value is None else str(value)
|
||||
elif "<list" in data_type:
|
||||
if "<entity" in data_type:
|
||||
list_type = "entity"
|
||||
elif "<string>" in data_type:
|
||||
list_type = "string"
|
||||
elif "<real>" in data_type:
|
||||
list_type = "float"
|
||||
elif "<integer>" in data_type:
|
||||
list_type = "integer"
|
||||
data_type = "list"
|
||||
value = None if value is None else str(value)
|
||||
elif "<string>" in data_type:
|
||||
data_type = "string"
|
||||
value = None if value is None else str(value)
|
||||
elif "<real>" in data_type:
|
||||
data_type = "float"
|
||||
value = None if value is None else float(value)
|
||||
elif "<integer>" in data_type:
|
||||
data_type = "integer"
|
||||
value = None if value is None else int(value)
|
||||
elif "<enumeration" in data_type:
|
||||
data_type = "enum"
|
||||
value = None if value is None else str(value)
|
||||
enum_items = attribute.type_of_attribute().declared_type().enumeration_items()
|
||||
cls.products[product_id].append({
|
||||
"name": attribute.name(),
|
||||
"value": value,
|
||||
"type": data_type,
|
||||
"enum_items": enum_items,
|
||||
"list_type": list_type,
|
||||
"is_optional": attribute.optional(),
|
||||
"is_null": getattr(product, attribute.name()) is None
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
class Usecase():
|
||||
def __init__(self, file, settings=None):
|
||||
self.file = file
|
||||
self.settings = {
|
||||
"product": None,
|
||||
"attributes": {}
|
||||
}
|
||||
for key, value in settings.items():
|
||||
self.settings[key] = value
|
||||
|
||||
def execute(self):
|
||||
for name, value in self.settings["attributes"].items():
|
||||
setattr(self.settings["product"], name, value)
|
||||
@@ -0,0 +1,88 @@
|
||||
import bpy
|
||||
import json
|
||||
import blenderbim.bim.module.attribute.edit_attributes as edit_attributes
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.attribute.data import Data
|
||||
|
||||
|
||||
class EnableEditingAttributes(bpy.types.Operator):
|
||||
bl_idname = "bim.enable_editing_attributes"
|
||||
bl_label = "Enable Editing Attributes"
|
||||
|
||||
def execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
obj = bpy.context.active_object
|
||||
props = obj.BIMObjectProperties
|
||||
while len(props.attributes) > 0:
|
||||
props.attributes.remove(0)
|
||||
for attribute in Data.products[props.ifc_definition_id]:
|
||||
new = props.attributes.add()
|
||||
if attribute["type"] == "entity":
|
||||
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.
|
||||
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
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DisableEditingAttributes(bpy.types.Operator):
|
||||
bl_idname = "bim.disable_editing_attributes"
|
||||
bl_label = "Disable Editing Attributes"
|
||||
|
||||
def execute(self, context):
|
||||
obj = bpy.context.active_object
|
||||
props = obj.BIMObjectProperties
|
||||
props.is_editing_attributes = False
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EditAttributes(bpy.types.Operator):
|
||||
bl_idname = "bim.edit_attributes"
|
||||
bl_label = "Edit Attributes"
|
||||
|
||||
def execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
obj = bpy.context.active_object
|
||||
props = obj.BIMObjectProperties
|
||||
attributes = {}
|
||||
for attribute in Data.products[props.ifc_definition_id]:
|
||||
blender_attribute = props.attributes.get(attribute["name"])
|
||||
if not blender_attribute:
|
||||
continue
|
||||
if blender_attribute.is_null:
|
||||
attributes[attribute["name"]] = None
|
||||
elif attribute["type"] == "string":
|
||||
attributes[attribute["name"]] = blender_attribute.string_value
|
||||
elif attribute["type"] == "list":
|
||||
values = blender_attribute.string_value[1:-1].split(", ")
|
||||
print(attribute["name"])
|
||||
print(attribute["list_type"])
|
||||
if attribute["list_type"] == "float":
|
||||
values = [float(v) for v in values]
|
||||
elif attribute["list_type"] == "integer":
|
||||
values = [int(v) for v in values]
|
||||
attributes[attribute["name"]] = values
|
||||
elif attribute["type"] == "integer":
|
||||
attributes[attribute["name"]] = blender_attribute.int_value
|
||||
elif attribute["type"] == "float":
|
||||
attributes[attribute["name"]] = blender_attribute.float_value
|
||||
elif attribute["type"] == "enum":
|
||||
attributes[attribute["name"]] = blender_attribute.enum_value
|
||||
usecase = edit_attributes.Usecase(self.file, {
|
||||
"product": self.file.by_id(props.ifc_definition_id),
|
||||
"attributes": attributes
|
||||
})
|
||||
usecase.execute()
|
||||
Data.load(props.ifc_definition_id)
|
||||
bpy.ops.bim.disable_editing_attributes()
|
||||
return {"FINISHED"}
|
||||
@@ -0,0 +1,92 @@
|
||||
from bpy.types import Panel
|
||||
from blenderbim.bim.module.attribute.data import Data
|
||||
|
||||
|
||||
class BIM_PT_attributes(Panel):
|
||||
bl_label = "IFC Attributes"
|
||||
bl_idname = "BIM_PT_attributes"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "object"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return bool(context.active_object.BIMObjectProperties.ifc_definition_id)
|
||||
|
||||
def draw(self, context):
|
||||
props = context.active_object.BIMObjectProperties
|
||||
if not props.ifc_definition_id:
|
||||
return
|
||||
if props.ifc_definition_id not in Data.products:
|
||||
Data.load(props.ifc_definition_id)
|
||||
|
||||
props = context.active_object.BIMObjectProperties
|
||||
|
||||
|
||||
if props.is_editing_attributes:
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.edit_attributes", icon="CHECKMARK", text="Save Attributes")
|
||||
row.operator("bim.disable_editing_attributes", icon="X", text="")
|
||||
|
||||
for attribute in Data.products[props.ifc_definition_id]:
|
||||
if attribute["type"] == "entity":
|
||||
continue
|
||||
row = self.layout.row(align=True)
|
||||
blender_attribute = props.attributes.get(attribute["name"])
|
||||
if attribute["type"] == "string" or attribute["type"] == "list":
|
||||
row.prop(blender_attribute, "string_value", text=attribute["name"])
|
||||
elif attribute["type"] == "integer":
|
||||
row.prop(blender_attribute, "int_value", text=attribute["name"])
|
||||
elif attribute["type"] == "float":
|
||||
row.prop(blender_attribute, "float_value", text=attribute["name"])
|
||||
elif attribute["type"] == "enum":
|
||||
row.prop(blender_attribute, "enum_value", text=attribute["name"])
|
||||
|
||||
if attribute["name"] == "GlobalId":
|
||||
row.operator("bim.generate_global_id", icon="FILE_REFRESH", text="")
|
||||
if attribute["is_optional"]:
|
||||
row.prop(blender_attribute, "is_null", icon="RADIOBUT_OFF" if blender_attribute.is_null else "RADIOBUT_ON", text="")
|
||||
# TODO: reimplement, see #1222
|
||||
#op = row.operator("bim.copy_attribute_to_selection", icon="COPYDOWN", text="")
|
||||
#op.attribute_name = attribute.name
|
||||
#op.attribute_value = attribute.string_value
|
||||
else:
|
||||
row = self.layout.row()
|
||||
row.operator("bim.enable_editing_attributes", icon="GREASEPENCIL", text="Edit")
|
||||
for attribute in Data.products[props.ifc_definition_id]:
|
||||
if attribute["value"] is None or attribute["type"] == "entity":
|
||||
continue
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=attribute["name"])
|
||||
row.label(text=str(attribute["value"]))
|
||||
|
||||
# TODO: reimplement, see #1222
|
||||
#if "IfcSite/" in context.active_object.name or "IfcBuilding/" in context.active_object.name:
|
||||
# self.draw_addresses_ui()
|
||||
|
||||
def draw_addresses_ui(self):
|
||||
self.layout.label(text="Address:")
|
||||
address = bpy.context.active_object.BIMObjectProperties.address
|
||||
row = self.layout.row()
|
||||
row.prop(address, "purpose")
|
||||
if address.purpose == "USERDEFINED":
|
||||
row = self.layout.row()
|
||||
row.prop(address, "user_defined_purpose")
|
||||
row = self.layout.row()
|
||||
row.prop(address, "description")
|
||||
|
||||
row = self.layout.row()
|
||||
row.prop(address, "internal_location")
|
||||
row = self.layout.row()
|
||||
row.prop(address, "address_lines")
|
||||
row = self.layout.row()
|
||||
row.prop(address, "postal_box")
|
||||
row = self.layout.row()
|
||||
row.prop(address, "town")
|
||||
row = self.layout.row()
|
||||
row.prop(address, "region")
|
||||
row = self.layout.row()
|
||||
row.prop(address, "postal_code")
|
||||
row = self.layout.row()
|
||||
row.prop(address, "country")
|
||||
|
||||
@@ -13,5 +13,5 @@ class Data:
|
||||
cls.products[product_id] = {
|
||||
"type": product.is_a(),
|
||||
"PredefinedType": product.PredefinedType if hasattr(product, "PredefinedType") else None,
|
||||
"ObjectType": product.ObjectType or None
|
||||
"ObjectType": product.ObjectType if hasattr(product, "ObjectType") else None
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ class Data:
|
||||
if not file:
|
||||
return
|
||||
product = file.by_id(product_id)
|
||||
if product.ContainedInStructure:
|
||||
if not hasattr(product, "ContainedInStructure"):
|
||||
cls.products[product_id] = None
|
||||
elif product.ContainedInStructure:
|
||||
structure = product.ContainedInStructure[0].RelatingStructure
|
||||
cls.products[product_id] = {"type": structure.is_a(), "Name": structure.Name, "id": int(structure.id())}
|
||||
else:
|
||||
|
||||
@@ -11,7 +11,14 @@ class BIM_PT_spatial(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return bool(context.active_object.BIMObjectProperties.ifc_definition_id)
|
||||
props = context.active_object.BIMObjectProperties
|
||||
if not props.ifc_definition_id:
|
||||
return False
|
||||
if props.ifc_definition_id not in Data.products:
|
||||
Data.load(props.ifc_definition_id)
|
||||
if not Data.products[props.ifc_definition_id]:
|
||||
return False
|
||||
return True
|
||||
|
||||
def draw(self, context):
|
||||
props = context.active_object.BIMObjectProperties
|
||||
@@ -20,9 +27,6 @@ class BIM_PT_spatial(Panel):
|
||||
if props.ifc_definition_id not in Data.products:
|
||||
Data.load(props.ifc_definition_id)
|
||||
|
||||
if "Ifc" not in context.active_object.name:
|
||||
return
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
name = "{}/{}".format(
|
||||
Data.products[props.ifc_definition_id]["type"], Data.products[props.ifc_definition_id]["Name"]
|
||||
|
||||
@@ -910,28 +910,6 @@ class GenerateGlobalId(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddAttribute(bpy.types.Operator):
|
||||
bl_idname = "bim.add_attribute"
|
||||
bl_label = "Add Attribute"
|
||||
|
||||
def execute(self, context):
|
||||
if not bpy.context.active_object.BIMObjectProperties.applicable_attributes:
|
||||
return {"FINISHED"}
|
||||
name = bpy.context.active_object.BIMObjectProperties.applicable_attributes
|
||||
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(bpy.context.scene.BIMProperties.export_schema)
|
||||
for obj in bpy.context.selected_objects:
|
||||
if "/" not in obj.name or obj.BIMObjectProperties.attributes.find(name) != -1:
|
||||
continue
|
||||
entity = schema.declaration_by_name(obj.name.split("/")[0])
|
||||
if name not in [a.name() for a in entity.all_attributes()]:
|
||||
continue
|
||||
attribute = obj.BIMObjectProperties.attributes.add()
|
||||
attribute.name = name
|
||||
if attribute.name == "GlobalId":
|
||||
attribute.string_value = ifcopenshell.guid.new()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddMaterialAttribute(bpy.types.Operator):
|
||||
bl_idname = "bim.add_material_attribute"
|
||||
bl_label = "Add Material Attribute"
|
||||
@@ -943,22 +921,6 @@ class AddMaterialAttribute(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemoveAttribute(bpy.types.Operator):
|
||||
bl_idname = "bim.remove_attribute"
|
||||
bl_label = "Remove Attribute"
|
||||
attribute_index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
name = bpy.context.active_object.BIMObjectProperties.attributes[self.attribute_index].name
|
||||
for obj in bpy.context.selected_objects:
|
||||
if "/" not in obj.name:
|
||||
continue
|
||||
index = obj.BIMObjectProperties.attributes.find(name)
|
||||
if index != -1:
|
||||
obj.BIMObjectProperties.attributes.remove(index)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemoveMaterialAttribute(bpy.types.Operator):
|
||||
bl_idname = "bim.remove_material_attribute"
|
||||
bl_label = "Remove Material Attribute"
|
||||
|
||||
@@ -274,6 +274,10 @@ def getIfcClasses(self, context):
|
||||
return classes_enum
|
||||
|
||||
|
||||
def getAttributeEnumValues(self, context):
|
||||
return [(e, e, "") for e in json.loads(self.enum_items)]
|
||||
|
||||
|
||||
def getProfileDef(self, context):
|
||||
global profiledef_enum
|
||||
if len(profiledef_enum) < 1:
|
||||
@@ -440,20 +444,6 @@ def getQtoNames(self, context):
|
||||
return qtonames_enum
|
||||
|
||||
|
||||
def getApplicableAttributes(self, context):
|
||||
global attributes_enum
|
||||
attributes_enum.clear()
|
||||
if "/" in context.active_object.name and context.active_object.name.split("/")[0] in schema.ifc.elements:
|
||||
attributes_enum.extend(
|
||||
[
|
||||
(a["name"], a["name"], "")
|
||||
for a in schema.ifc.elements[context.active_object.name.split("/")[0]]["attributes"]
|
||||
if self.attributes.find(a["name"]) == -1
|
||||
]
|
||||
)
|
||||
return attributes_enum
|
||||
|
||||
|
||||
def getApplicableMaterialAttributes(self, context):
|
||||
global materialattributes_enum
|
||||
materialattributes_enum.clear()
|
||||
@@ -548,6 +538,9 @@ class Attribute(PropertyGroup):
|
||||
bool_value: BoolProperty(name="Value")
|
||||
int_value: IntProperty(name="Value")
|
||||
float_value: FloatProperty(name="Value")
|
||||
is_null: BoolProperty(name="Is Null")
|
||||
enum_items: StringProperty(name="Value")
|
||||
enum_value: EnumProperty(items=getAttributeEnumValues, name="Value")
|
||||
|
||||
|
||||
class MaterialLayer(PropertyGroup):
|
||||
@@ -1467,11 +1460,11 @@ class BIMObjectProperties(PropertyGroup):
|
||||
is_reassigning_class: BoolProperty(name="Is Reassigning Class")
|
||||
global_ids: CollectionProperty(name="GlobalIds", type=GlobalId)
|
||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||
is_editing_attributes: BoolProperty(name="Is Editing Attributes")
|
||||
relating_type: PointerProperty(name="Type Product", type=bpy.types.Object)
|
||||
relating_structure: PointerProperty(name="Spatial Container", type=bpy.types.Object)
|
||||
psets: CollectionProperty(name="Psets", type=PsetQto)
|
||||
qtos: CollectionProperty(name="Qtos", type=PsetQto)
|
||||
applicable_attributes: EnumProperty(items=getApplicableAttributes, name="Attribute Names")
|
||||
document_references: CollectionProperty(name="Document References", type=DocumentReference)
|
||||
active_document_reference_index: IntProperty(name="Active Document Reference Index")
|
||||
constraints: CollectionProperty(name="Constraints", type=Constraint)
|
||||
|
||||
@@ -26,59 +26,10 @@ class BIM_PT_object(Panel):
|
||||
if "Ifc" not in context.active_object.name:
|
||||
return
|
||||
|
||||
layout.label(text="Attributes:")
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, "applicable_attributes", text="")
|
||||
row.operator("bim.add_attribute")
|
||||
|
||||
for index, attribute in enumerate(props.attributes):
|
||||
row = layout.row(align=True)
|
||||
row.prop(attribute, "name", text="")
|
||||
row.prop(attribute, "string_value", text="")
|
||||
if attribute.name == "GlobalId":
|
||||
row.operator("bim.generate_global_id", icon="FILE_REFRESH", text="")
|
||||
op = row.operator("bim.copy_attribute_to_selection", icon="COPYDOWN", text="")
|
||||
op.attribute_name = attribute.name
|
||||
op.attribute_value = attribute.string_value
|
||||
row.operator("bim.remove_attribute", icon="X", text="").attribute_index = index
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, "attributes")
|
||||
|
||||
if "IfcSite/" in context.active_object.name or "IfcBuilding/" in context.active_object.name:
|
||||
self.draw_addresses_ui()
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, "relating_type")
|
||||
row.operator("bim.select_similar_type", icon="RESTRICT_SELECT_OFF", text="")
|
||||
|
||||
def draw_addresses_ui(self):
|
||||
layout = self.layout
|
||||
layout.label(text="Address:")
|
||||
address = bpy.context.active_object.BIMObjectProperties.address
|
||||
row = layout.row()
|
||||
row.prop(address, "purpose")
|
||||
if address.purpose == "USERDEFINED":
|
||||
row = layout.row()
|
||||
row.prop(address, "user_defined_purpose")
|
||||
row = layout.row()
|
||||
row.prop(address, "description")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(address, "internal_location")
|
||||
row = layout.row()
|
||||
row.prop(address, "address_lines")
|
||||
row = layout.row()
|
||||
row.prop(address, "postal_box")
|
||||
row = layout.row()
|
||||
row.prop(address, "town")
|
||||
row = layout.row()
|
||||
row.prop(address, "region")
|
||||
row = layout.row()
|
||||
row.prop(address, "postal_code")
|
||||
row = layout.row()
|
||||
row.prop(address, "country")
|
||||
|
||||
|
||||
class BIM_PT_object_material(Panel):
|
||||
bl_label = "IFC Object Material"
|
||||
|
||||
Reference in New Issue
Block a user