New import workaround for vendors who create a silly amount of materials like DDS-CAD

This commit is contained in:
Dion Moult
2020-04-26 22:06:27 +10:00
parent b8ea5dc3be
commit d65f2b432b
5 changed files with 36 additions and 38 deletions
@@ -63,10 +63,9 @@ class MaterialCreator():
self.parse_styled_item(styled_item, self.materials[material_name])
if self.ifc_import_settings.should_treat_styled_item_as_material:
# Revit workaround: since Revit exports all material
# assignments as individual object styled items. Treating
# them as reusable materials makes things much more
# efficient in Blender.
# Revit workaround: since Revit/DDS-CAD exports all material
# assignments as individual object styled items. Treating them as
# reusable materials makes things much more efficient in Blender.
self.assign_material_to_mesh(self.materials[material_name])
else:
# Proper behaviour
@@ -233,10 +232,16 @@ class IfcImporter():
self.merge_by_class()
elif self.ifc_import_settings.should_merge_by_material:
self.merge_by_material()
if self.ifc_import_settings.should_merge_materials_by_colour \
or (self.ifc_import_settings.should_auto_set_workarounds \
and len(self.material_creator.materials) > 300):
self.merge_materials_by_colour()
if self.ifc_import_settings.should_clean_mesh:
self.clean_mesh()
def auto_set_workarounds(self):
if 'DDS-CAD' in self.file.wrapped_data.header.file_name.originating_system:
self.ifc_import_settings.should_treat_styled_item_as_material = True
applications = self.file.by_type('IfcApplication')
if not applications:
return
@@ -517,6 +522,28 @@ class IfcImporter():
context_override['selected_objects'] = context_override['selected_editable_objects'] = objs
bpy.ops.object.join(context_override)
def merge_materials_by_colour(self):
cleaned_materials = {}
for m in bpy.data.materials:
key = '-'.join([str(x) for x in m.diffuse_color])
cleaned_materials[key] = { 'diffuse_color': m.diffuse_color }
for cleaned_material in cleaned_materials.values():
cleaned_material['material'] = bpy.data.materials.new('Merged Material')
cleaned_material['material'].diffuse_color = cleaned_material['diffuse_color']
for obj in self.added_data.values():
if not hasattr(obj, 'material_slots') \
or not obj.material_slots:
continue
for slot in obj.material_slots:
m = slot.material
key = '-'.join([str(x) for x in m.diffuse_color])
slot.material = cleaned_materials[key]['material']
for material in self.material_creator.materials.values():
bpy.data.materials.remove(material)
def clean_mesh(self):
obj = None
last_obj = None
@@ -960,6 +987,7 @@ class IfcImportSettings:
self.should_ignore_site_coordinates = False
self.should_ignore_building_coordinates = False
self.should_reset_absolute_coordinates = False
self.should_merge_materials_by_colour = False
self.should_import_curves = False
self.should_import_opening_elements = False
self.should_import_spaces = False
@@ -94,6 +94,7 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
ifc_import_settings.should_import_aggregates = bpy.context.scene.BIMProperties.import_should_import_aggregates
ifc_import_settings.should_merge_by_class = bpy.context.scene.BIMProperties.import_should_merge_by_class
ifc_import_settings.should_merge_by_material = bpy.context.scene.BIMProperties.import_should_merge_by_material
ifc_import_settings.should_merge_materials_by_colour = bpy.context.scene.BIMProperties.import_should_merge_materials_by_colour
ifc_import_settings.should_clean_mesh = bpy.context.scene.BIMProperties.import_should_clean_mesh
ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
ifc_importer.execute()
@@ -813,6 +813,7 @@ class BIMProperties(PropertyGroup):
import_should_import_aggregates: BoolProperty(name="Import Aggregates", default=True)
import_should_merge_by_class: BoolProperty(name="Import and Merge by Class", default=False)
import_should_merge_by_material: BoolProperty(name="Import and Merge by Material", default=False)
import_should_merge_materials_by_colour: BoolProperty(name="Import and Merge Materials by Colour", default=False)
import_should_clean_mesh: BoolProperty(name="Import and Clean Mesh", default=True)
qa_reject_element_reason: StringProperty(name="Element Rejection Reason")
person: EnumProperty(items=getPersons, name="Person")
@@ -940,6 +940,8 @@ class BIM_PT_mvd(Panel):
row = layout.row()
row.prop(bim_properties, 'import_should_merge_by_material')
row = layout.row()
row.prop(bim_properties, 'import_should_merge_materials_by_colour')
row = layout.row()
row.prop(bim_properties, 'import_should_clean_mesh')
layout.label(text='Vendor Workarounds:')
-34
View File
@@ -1,34 +0,0 @@
import bpy
import pprint
print('# Start')
cleaned_materials = {}
n = 0
for m in bpy.data.materials:
r = m.diffuse_color[0]
g = m.diffuse_color[1]
b = m.diffuse_color[2]
key = str(r) + '-' + str(g) + '-' + str(b)
cleaned_materials[key] = {'name': 'name{}'.format(n)}
n += 1
pprint.pprint(cleaned_materials)
print(len(bpy.data.materials.keys()))
print(len(cleaned_materials.keys()))
for rgb, data in cleaned_materials.items():
m = bpy.data.materials.new(data['name'])
print(rgb)
m.diffuse_color = (
float(rgb.split('-')[0]),
float(rgb.split('-')[1]),
float(rgb.split('-')[2]),
1)
data['material'] = m
for o in bpy.context.selected_objects:
m = o.material_slots[0].material
r = m.diffuse_color[0]
g = m.diffuse_color[1]
b = m.diffuse_color[2]
key = str(r) + '-' + str(g) + '-' + str(b)
o.material_slots[0].material = cleaned_materials[key]['material']