Fix #1585. Materials are added as a potential if you assign it as an object material too, for convenience.

This commit is contained in:
Dion Moult
2021-07-28 19:55:18 +10:00
parent d88c4fd377
commit 10b6253a36
2 changed files with 53 additions and 8 deletions
+6 -2
View File
@@ -54,11 +54,11 @@ class MaterialCreator:
if not self.mesh or self.mesh.name in self.parsed_meshes:
return
self.parsed_meshes.add(self.mesh.name)
self.add_default_material_surface_style(element)
self.add_default_material(element)
if self.parse_representations(element):
self.assign_material_slots_to_faces()
def add_default_material_surface_style(self, element):
def add_default_material(self, element):
element_material = ifcopenshell.util.element.get_material(element)
if not element_material:
return
@@ -71,6 +71,10 @@ class MaterialCreator:
if surface_style:
self.mesh.materials.append(self.styles[surface_style[0].id()])
return
# For authoring convenience, we choose to assign a material, even if it has no surface style. See #1585.
for material in [m for m in self.ifc_importer.file.traverse(element_material) if m.is_a("IfcMaterial")]:
self.mesh.materials.append(self.materials[material.id()])
return
def load_existing_materials(self):
for material in bpy.data.materials:
@@ -1,6 +1,7 @@
import bpy
import json
import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.attribute
import ifcopenshell.util.representation
import blenderbim.bim.helper
@@ -54,14 +55,19 @@ class AddMaterial(bpy.types.Operator):
self.file = IfcStore.get_file()
result = ifcopenshell.api.run("material.add_material", self.file, **{"name": obj.name})
obj.BIMObjectProperties.ifc_definition_id = result.id()
IfcStore.link_element(result, obj)
if obj.BIMMaterialProperties.ifc_style_id:
context = ifcopenshell.util.representation.get_context(self.file, "Model", "Body", "MODEL_VIEW")
if context:
ifcopenshell.api.run("style.assign_material_style", self.file, **{
"material": result,
"style": self.file.by_id(obj.BIMMaterialProperties.ifc_style_id),
"context": context,
})
ifcopenshell.api.run(
"style.assign_material_style",
self.file,
**{
"material": result,
"style": self.file.by_id(obj.BIMMaterialProperties.ifc_style_id),
"context": context,
},
)
Data.load(IfcStore.get_file())
material_prop_purge()
return {"FINISHED"}
@@ -103,19 +109,37 @@ class AssignMaterial(bpy.types.Operator):
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
material_type = self.material_type or obj.BIMObjectMaterialProperties.material_type
self.file = IfcStore.get_file()
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
ifcopenshell.api.run(
"material.assign_material",
self.file,
**{
"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
"product": element,
"type": material_type,
"material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)),
},
)
Data.load(IfcStore.get_file())
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
self.set_default_material(obj, element)
return {"FINISHED"}
def set_default_material(self, obj, element):
element_material = ifcopenshell.util.element.get_material(element)
material = [m for m in self.file.traverse(element_material) if m.is_a("IfcMaterial")]
if not material:
return
object_material_ids = [
om.BIMObjectProperties.ifc_definition_id
for om in obj.data.materials
if om is not None and om.BIMObjectProperties.ifc_definition_id
]
if material[0].id() in object_material_ids:
return
obj.data.materials.append(IfcStore.get_element(material[0].id()))
class UnassignMaterial(bpy.types.Operator):
bl_idname = "bim.unassign_material"
@@ -523,8 +547,25 @@ class EditAssignedMaterial(bpy.types.Operator):
elif material_set.is_a("IfcMaterialProfileSet"):
Data.load_profiles()
bpy.ops.bim.disable_editing_assigned_material(obj=obj.name)
self.set_default_material(obj, self.file.by_id(obj.BIMObjectProperties.ifc_definition_id))
return {"FINISHED"}
def set_default_material(self, obj, element):
element_material = ifcopenshell.util.element.get_material(element)
material = [m for m in self.file.traverse(element_material) if m.is_a("IfcMaterial")]
if not material:
return
object_material_ids = [
om.BIMObjectProperties.ifc_definition_id
for om in obj.data.materials
if om is not None and om.BIMObjectProperties.ifc_definition_id
]
if material[0].id() in object_material_ids:
return
obj.data.materials.append(IfcStore.get_element(material[0].id()))
class EnableEditingMaterialSetItem(bpy.types.Operator):
bl_idname = "bim.enable_editing_material_set_item"