Add support for styled surfaces for native elements. See #865

This commit is contained in:
Dion Moult
2020-06-08 12:06:15 +10:00
parent afb05f42db
commit a8a51eb212
@@ -98,7 +98,11 @@ class MaterialCreator():
return return
slots = [s.name for s in obj.material_slots] slots = [s.name for s in obj.material_slots]
for index, polygon in enumerate(mesh.polygons): for index, polygon in enumerate(mesh.polygons):
material = mesh['ios_materials'][mesh['ios_material_ids'][index]] material_id = mesh['ios_material_ids'][index]
# Magic number 999999 represents no material, until this has a better approach
if material_id == 999999:
continue
material = mesh['ios_materials'][material_id]
if 'surface-style-' in material: if 'surface-style-' in material:
material = material.split('-')[2] material = material.split('-')[2]
try: try:
@@ -647,45 +651,73 @@ class IfcImporter():
def create_native_mesh(self, element, shape): def create_native_mesh(self, element, shape):
data = self.native_elements[element.GlobalId] data = self.native_elements[element.GlobalId]
bmeshes = []
curves = []
materials = [] materials = []
items = []
for representation in self.get_body_representations(element.Representation.Representations): for representation in self.get_body_representations(element.Representation.Representations):
for item in representation['raw'].Items: for item in representation['raw'].Items:
materials.append(self.get_representation_item_material_name(item))
if item.id() in data: if item.id() in data:
item = data[item.id()] item = data[item.id()]
if item.is_a() == 'IfcExtrudedAreaSolid': if item.is_a() == 'IfcExtrudedAreaSolid':
bm = self.create_native_extruded_area_solid(item, element) bm = self.create_native_extruded_area_solid(item, element)
if bm: if bm:
bmesh.ops.transform(bm, matrix=representation['matrix'], verts=bm.verts) bmesh.ops.transform(bm, matrix=representation['matrix'], verts=bm.verts)
bmeshes.append(bm) items.append(bm)
else:
items.append(None)
elif item.is_a('IfcSweptDiskSolid'): elif item.is_a('IfcSweptDiskSolid'):
curves.append(self.transform_curve( items.append(self.transform_curve(
self.create_native_swept_disk_solid(item, element), representation['matrix'])) self.create_native_swept_disk_solid(item, element), representation['matrix']))
else:
items.append(None)
if not bmeshes and not curves: if not items:
return None return None
bevel_depth = None bevel_depth = None
merged_curve = None merged_curve = None
for curve in curves: merged_bm = bmesh.new()
if bevel_depth is None: material_ids = []
bevel_depth = curve.bevel_depth for i, item in enumerate(items):
merged_curve = curve if not item:
elif curve.bevel_depth == bevel_depth: continue
self.merge_curves(merged_curve, curve) if isinstance(item, bpy.types.Curve):
else: if bevel_depth is None:
# TODO: handle if there are multiple different radiuses bevel_depth = item.bevel_depth
pass merged_curve = item
elif item.bevel_depth == bevel_depth:
self.merge_curves(merged_curve, item)
else:
# TODO: handle if there are multiple different radiuses
# We don't have a choice but to meshify it
pass
elif isinstance(item, bmesh.types.BMesh):
total_polygons = len(item.faces)
if merged_bm is None:
merged_bm = item
else:
self.merge_bmeshes(merged_bm, item)
if materials[i]:
material_ids += [i] * total_polygons
else:
# Magic number 999999 represents no material, until this has a better approach
material_ids += [999999] * total_polygons
if merged_curve: if merged_curve:
return merged_curve return merged_curve
# TODO: handle both curve and bmeshes combined # TODO: handle both curve and bmeshes combined
mesh = bpy.data.meshes.new('Native Mesh') mesh = bpy.data.meshes.new('Native Mesh')
merged_bm = self.merge_bmeshes(bmeshes)
merged_bm.to_mesh(mesh) merged_bm.to_mesh(mesh)
merged_bm.free() merged_bm.free()
mesh['ios_materials'] = materials
mesh['ios_material_ids'] = material_ids
return mesh return mesh
def get_representation_item_material_name(self, item):
if not item.StyledByItem:
return
styled_item = item.StyledByItem[0]
return self.material_creator.get_material_name(styled_item)
def transform_curve(self, curve, matrix): def transform_curve(self, curve, matrix):
for spline in curve.splines: for spline in curve.splines:
for point in spline.points: for point in spline.points:
@@ -704,14 +736,12 @@ class IfcImporter():
new_spline.points[-1].co = point.co new_spline.points[-1].co = point.co
return a return a
def merge_bmeshes(self, bmeshes): def merge_bmeshes(self, a, b):
merged_bm = bmesh.new()
mesh = bpy.data.meshes.new('x') mesh = bpy.data.meshes.new('x')
for bm in bmeshes: b.to_mesh(mesh)
bm.to_mesh(mesh) b.free()
bm.free() a.from_mesh(mesh)
merged_bm.from_mesh(mesh) return a
return merged_bm
def create_native_swept_disk_solid(self, item, element): def create_native_swept_disk_solid(self, item, element):
# TODO: support inner radius, start param, and end param # TODO: support inner radius, start param, and end param