Fix #1554. Changing Blender material name now auto updates both IFC material name and surface style name

This commit is contained in:
Dion Moult
2021-07-08 18:59:40 +10:00
parent 21c4433c75
commit 519a53dc61
4 changed files with 38 additions and 7 deletions
+20 -4
View File
@@ -5,6 +5,7 @@ import ifcopenshell.api.owner.settings
from bpy.app.handlers import persistent
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.attribute.data import Data as AttributeData
from ifcopenshell.api.material.data import Data as MaterialData
from ifcopenshell.api.type.data import Data as TypeData
@@ -34,11 +35,23 @@ def mode_callback(obj, data):
def name_callback(obj, data):
try:
oby.type
obj.name
except:
return # In case the object RNA is gone during an undo / redo operation
# Blender material names are up to 63 UTF-8 bytes
if not obj.BIMObjectProperties.ifc_definition_id or "/" not in obj.name or len(bytes(obj.name, "utf-8")) >= 63:
# Blender names are up to 63 UTF-8 bytes
if len(bytes(obj.name, "utf-8")) >= 63:
return
if isinstance(obj, bpy.types.Material):
if obj.BIMObjectProperties.ifc_definition_id:
IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id).Name = obj.name
AttributeData.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
MaterialData.load_materials()
if obj.BIMMaterialProperties.ifc_style_id:
IfcStore.get_file().by_id(obj.BIMMaterialProperties.ifc_style_id).Name = obj.name
return
if not obj.BIMObjectProperties.ifc_definition_id or "/" not in obj.name:
return
element = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id)
if not element.is_a("IfcRoot"):
@@ -73,7 +86,10 @@ def active_object_callback():
def subscribe_to(object, data_path, callback):
subscribe_to = object.path_resolve(data_path, False)
try:
subscribe_to = object.path_resolve(data_path, False)
except:
return
bpy.msgbus.subscribe_rna(
key=subscribe_to,
owner=object,
+1 -1
View File
@@ -62,7 +62,7 @@ class IfcStore:
map_object = IfcStore.guid_map
try:
obj = map_object[id_or_guid]
obj.type # In case the object has been deleted, this triggers an exception
obj.name # In case the object has been deleted, this triggers an exception
except:
return
return obj
+16 -2
View File
@@ -800,6 +800,8 @@ class IfcImporter:
def merge_by_class(self):
merge_set = {}
for obj in self.added_data.values():
if not isinstance(obj, bpy.types.Object):
continue
if "/" not in obj.name or "IfcRelAggregates" in obj.users_collection[0].name:
continue
merge_set.setdefault(obj.name.split("/")[0], []).append(obj)
@@ -808,6 +810,8 @@ class IfcImporter:
def merge_by_material(self):
merge_set = {}
for obj in self.added_data.values():
if not isinstance(obj, bpy.types.Object):
continue
if "/" not in obj.name or "IfcRelAggregates" in obj.users_collection[0].name:
continue
if not obj.material_slots:
@@ -834,6 +838,8 @@ class IfcImporter:
cleaned_material["material"].diffuse_color = cleaned_material["diffuse_color"]
for obj in self.added_data.values():
if not isinstance(obj, bpy.types.Object):
continue
if not hasattr(obj, "material_slots") or not obj.material_slots:
continue
for slot in obj.material_slots:
@@ -858,6 +864,8 @@ class IfcImporter:
obj = None
last_obj = None
for obj in self.added_data.values():
if not isinstance(obj, bpy.types.Object):
continue
if obj.type == "MESH":
obj.select_set(True)
last_obj = obj
@@ -1005,7 +1013,7 @@ class IfcImporter:
def create_materials(self):
for material in self.file.by_type("IfcMaterial"):
blender_material = bpy.data.materials.new(material.Name)
blender_material.BIMObjectProperties.ifc_definition_id = material.id()
self.link_element(material, blender_material)
self.material_creator.materials[material.id()] = blender_material
blender_material.use_fake_user = True
@@ -1028,6 +1036,11 @@ class IfcImporter:
self.create_style(style, blender_material)
def create_style(self, style, blender_material):
old_definition_id = blender_material.BIMObjectProperties.ifc_definition_id
if not old_definition_id:
self.link_element(style, blender_material)
blender_material.BIMObjectProperties.ifc_definition_id = old_definition_id
blender_material.BIMMaterialProperties.ifc_style_id = style.id()
self.material_creator.styles[style.id()] = blender_material
for surface_style in style.Styles:
@@ -1060,7 +1073,8 @@ class IfcImporter:
def place_objects_in_spatial_tree(self):
for ifc_definition_id, obj in self.added_data.items():
self.place_object_in_spatial_tree(self.file.by_id(ifc_definition_id), obj)
if isinstance(obj, bpy.types.Object):
self.place_object_in_spatial_tree(self.file.by_id(ifc_definition_id), obj)
def place_object_in_spatial_tree(self, element, obj):
if element.is_a("IfcProject"):
@@ -128,6 +128,7 @@ class SelectClashSource(bpy.types.Operator):
bl_label = "Select Clash Source"
bl_options = {"REGISTER", "UNDO"}
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
filter_glob: bpy.props.StringProperty(default="*.ifc", options={"HIDDEN"})
index: bpy.props.IntProperty()
group: bpy.props.StringProperty()