Recreating round-tripped representations now preserves surface styles

This commit is contained in:
Dion Moult
2020-11-24 12:09:49 +11:00
parent e2543954c0
commit c057cb9aab
3 changed files with 17 additions and 20 deletions
@@ -58,7 +58,7 @@ class MaterialCreator:
return return
self.parsed_meshes.append(self.mesh.name) self.parsed_meshes.append(self.mesh.name)
if self.parse_representations(element): if self.parse_representations(element):
self.assign_material_slots_to_faces(obj, self.mesh) self.assign_material_slots_to_faces(obj)
def parse_representations(self, element): def parse_representations(self, element):
has_parsed = False has_parsed = False
@@ -91,22 +91,23 @@ class MaterialCreator:
return True return True
style = bpy.data.materials.get(style_name) style = bpy.data.materials.get(style_name)
if not style: if not style:
style = bpy.data.materials.new(style_name) style = bpy.data.materials.new(style_name)
self.parse_styled_item(styled_item, style)
self.parse_styled_item(styled_item, style)
self.assign_style_to_mesh(style) self.assign_style_to_mesh(style)
item_id = self.mesh.BIMMeshProperties.ifc_item_ids.add() item_id = self.mesh.BIMMeshProperties.ifc_item_ids.add()
item_id.name = str(item.id()) item_id.name = str(item.id())
return True return True
def assign_material_slots_to_faces(self, obj, mesh): def assign_material_slots_to_faces(self, obj):
if "ios_materials" not in mesh or not mesh["ios_materials"]: if "ios_materials" not in self.mesh or not self.mesh["ios_materials"]:
return return
if len(obj.material_slots) == 1: if len(obj.material_slots) == 1:
return return
material_to_slot = {} material_to_slot = {}
for i, material in enumerate(mesh["ios_materials"]): for i, material in enumerate(self.mesh["ios_materials"]):
if material == "NULLMAT": if material == "NULLMAT":
continue continue
elif "surface-style-" in material: elif "surface-style-" in material:
@@ -124,9 +125,9 @@ class MaterialCreator:
slot_index = [self.canonicalise_material_name(s.name) for s in obj.material_slots].index(material) slot_index = [self.canonicalise_material_name(s.name) for s in obj.material_slots].index(material)
material_to_slot[i] = slot_index material_to_slot[i] = slot_index
if len(mesh.polygons) == len(mesh["ios_material_ids"]): if len(self.mesh.polygons) == len(self.mesh["ios_material_ids"]):
material_index = [(material_to_slot[mat_id] if mat_id != -1 else 0) for mat_id in mesh["ios_material_ids"]] material_index = [(material_to_slot[mat_id] if mat_id != -1 else 0) for mat_id in self.mesh["ios_material_ids"]]
mesh.polygons.foreach_set("material_index", material_index) self.mesh.polygons.foreach_set("material_index", material_index)
def canonicalise_material_name(self, name): def canonicalise_material_name(self, name):
return re.sub(r"\.[0-9]{3}$", "", name) return re.sub(r"\.[0-9]{3}$", "", name)
@@ -4509,8 +4509,8 @@ class GetRepresentationIfcParameters(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = bpy.context.active_object.data.BIMMeshProperties props = bpy.context.active_object.data.BIMMeshProperties
dummy = ifcopenshell.file.from_string(props.ifc_definition) elements = ifc.IfcStore.get_file().traverse(ifc.IfcStore.get_file().by_id(props.ifc_definition_id))
for element in dummy: for element in elements:
if not element.is_a("IfcRepresentationItem"): if not element.is_a("IfcRepresentationItem"):
continue continue
for i in range(0, len(element)): for i in range(0, len(element)):
@@ -4533,21 +4533,21 @@ class UpdateIfcRepresentation(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = bpy.context.active_object.data.BIMMeshProperties props = bpy.context.active_object.data.BIMMeshProperties
parameter = props.ifc_parameters[self.index] parameter = props.ifc_parameters[self.index]
dummy = ifcopenshell.file.from_string(props.ifc_definition) element = ifc.IfcStore.get_file().by_id(parameter.step_id)[parameter.index] = parameter.value
element = dummy.by_id(parameter.step_id)[parameter.index] = parameter.value
props.ifc_definition = dummy.to_string()
self.recreate_ifc_representation() self.recreate_ifc_representation()
return {"FINISHED"} return {"FINISHED"}
def recreate_ifc_representation(self): def recreate_ifc_representation(self):
props = bpy.context.active_object.data.BIMMeshProperties props = bpy.context.active_object.data.BIMMeshProperties
dummy = ifcopenshell.file.from_string(props.ifc_definition)
logger = logging.getLogger("ImportIFC") logger = logging.getLogger("ImportIFC")
self.ifc_import_settings = import_ifc.IfcImportSettings.factory(bpy.context, ifc.IfcStore.path, logger) self.ifc_import_settings = import_ifc.IfcImportSettings.factory(bpy.context, ifc.IfcStore.path, logger)
element = dummy.by_id(props.ifc_definition_id) element = ifc.IfcStore.get_file().by_id(props.ifc_definition_id)
settings = ifcopenshell.geom.settings() settings = ifcopenshell.geom.settings()
shape = ifcopenshell.geom.create_shape(settings, element) shape = ifcopenshell.geom.create_shape(settings, element)
ifc_importer = import_ifc.IfcImporter(self.ifc_import_settings) ifc_importer = import_ifc.IfcImporter(self.ifc_import_settings)
ifc_importer.file = dummy ifc_importer.file = ifc.IfcStore.get_file()
mesh = ifc_importer.create_mesh(element, shape) mesh = ifc_importer.create_mesh(element, shape)
bpy.context.active_object.data.user_remap(mesh) bpy.context.active_object.data.user_remap(mesh)
ifc_importer.material_creator.mesh = mesh
if ifc_importer.material_creator.parse_representation(element):
ifc_importer.material_creator.assign_material_slots_to_faces(bpy.context.active_object)
@@ -755,16 +755,12 @@ class BIM_PT_mesh(Panel):
row = layout.row() row = layout.row()
row.prop(props, "geometry_type") row.prop(props, "geometry_type")
row = layout.row()
row.prop(props, "ifc_definition")
layout.label(text="IFC Parameters:") layout.label(text="IFC Parameters:")
row = layout.row() row = layout.row()
row.operator("bim.get_representation_ifc_parameters") row.operator("bim.get_representation_ifc_parameters")
for index, ifc_parameter in enumerate(props.ifc_parameters): for index, ifc_parameter in enumerate(props.ifc_parameters):
row = layout.row(align=True) row = layout.row(align=True)
row.prop(ifc_parameter, "name", text="") row.prop(ifc_parameter, "name", text="")
row.prop(ifc_parameter, "step_id")
row.prop(ifc_parameter, "index")
row.prop(ifc_parameter, "value", text="") row.prop(ifc_parameter, "value", text="")
row.operator("bim.update_ifc_representation", icon="FILE_REFRESH", text="").index = index row.operator("bim.update_ifc_representation", icon="FILE_REFRESH", text="").index = index