mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 10:57:49 +00:00
Add support for plan representations and all target views
This commit is contained in:
@@ -539,40 +539,34 @@ class IfcParser():
|
||||
|
||||
self.append_default_representation(object, results)
|
||||
self.append_representation_per_context(object, results)
|
||||
self.append_generated_representation_per_context(object, results)
|
||||
return results
|
||||
|
||||
def append_default_representation(self, object, results):
|
||||
if not self.is_mesh_context_sensitive(object.data.name):
|
||||
results['Model/Body/{}'.format(object.data.name)] = self.get_representation(
|
||||
object.data, object, 'Model', 'Body')
|
||||
results['Model/Body/MODEL_VIEW/{}'.format(object.data.name)] = self.get_representation(
|
||||
object.data, object, 'Model', 'Body', 'MODEL_VIEW')
|
||||
|
||||
def append_representation_per_context(self, object, results):
|
||||
context = self.get_ifc_context(object.data.name)
|
||||
name = self.get_ifc_representation_name(object.data.name)
|
||||
for subcontext in self.ifc_export_settings.subcontexts:
|
||||
try:
|
||||
mesh = bpy.data.meshes['/'.join([context, subcontext, name])]
|
||||
except:
|
||||
continue
|
||||
results[mesh.name] = self.get_representation(
|
||||
mesh, object, context, subcontext)
|
||||
for context in self.ifc_export_settings.context_tree:
|
||||
for subcontext in context['subcontexts']:
|
||||
for target_view in subcontext['target_views']:
|
||||
mesh_name = '/'.join([context['name'], subcontext['name'], target_view, name])
|
||||
try:
|
||||
mesh = bpy.data.meshes[mesh_name]
|
||||
except:
|
||||
continue
|
||||
results[mesh_name] = self.get_representation(
|
||||
mesh, object, context['name'], subcontext['name'], target_view)
|
||||
|
||||
def append_generated_representation_per_context(self, object, results):
|
||||
context = self.get_ifc_context(object.data.name)
|
||||
name = self.get_ifc_representation_name(object.data.name)
|
||||
for subcontext in self.ifc_export_settings.generated_subcontexts:
|
||||
representation = self.get_representation(
|
||||
object.data, object, context, subcontext, is_generated=True)
|
||||
results['/'.join([context, subcontext, name])] = representation
|
||||
|
||||
def get_representation(self, mesh, object, context, subcontext, is_generated=False):
|
||||
def get_representation(self, mesh, object, context, subcontext, target_view, is_generated=False):
|
||||
return {
|
||||
'ifc': None,
|
||||
'raw': mesh,
|
||||
'raw_object': object,
|
||||
'context': context,
|
||||
'subcontext': subcontext,
|
||||
'target_view': target_view,
|
||||
'is_curve': isinstance(mesh, bpy.types.Curve),
|
||||
'is_wireframe': mesh.BIMMeshProperties.is_wireframe if hasattr(mesh, 'BIMMeshProperties') else False,
|
||||
'is_swept_solid': mesh.BIMMeshProperties.is_swept_solid if hasattr(mesh, 'BIMMeshProperties') else False,
|
||||
@@ -583,14 +577,9 @@ class IfcParser():
|
||||
def is_mesh_context_sensitive(self, name):
|
||||
return '/' in name
|
||||
|
||||
def get_ifc_context(self, name):
|
||||
if self.is_mesh_context_sensitive(name):
|
||||
return name.split('/')[0]
|
||||
return 'Model'
|
||||
|
||||
def get_ifc_representation_name(self, name):
|
||||
if self.is_mesh_context_sensitive(name):
|
||||
return name.split('/')[2]
|
||||
return name.split('/')[3]
|
||||
return name
|
||||
|
||||
def get_materials(self):
|
||||
@@ -706,18 +695,17 @@ class IfcParser():
|
||||
if not object.data:
|
||||
return names
|
||||
if not self.is_mesh_context_sensitive(object.data.name):
|
||||
names.append('Model/Body/{}'.format(object.data.name))
|
||||
for subcontext in self.ifc_export_settings.subcontexts:
|
||||
try:
|
||||
mesh = bpy.data.meshes['/'.join([
|
||||
self.get_ifc_context(object.data.name),
|
||||
subcontext,
|
||||
self.get_ifc_representation_name(object.data.name)])]
|
||||
except:
|
||||
continue
|
||||
names.append(mesh.name)
|
||||
for subcontext in self.ifc_export_settings.generated_subcontexts:
|
||||
names.append('Model/{}/{}'.format(subcontext, self.get_ifc_representation_name(object.data.name)))
|
||||
names.append('Model/Body/MODEL_VIEW/{}'.format(object.data.name))
|
||||
name = self.get_ifc_representation_name(object.data.name)
|
||||
for context in self.ifc_export_settings.context_tree:
|
||||
for subcontext in context['subcontexts']:
|
||||
for target_view in subcontext['target_views']:
|
||||
mesh_name = '/'.join([context['name'], subcontext['name'], target_view, name])
|
||||
try:
|
||||
mesh = bpy.data.meshes[mesh_name]
|
||||
except:
|
||||
continue
|
||||
names.append(mesh_name)
|
||||
return names
|
||||
|
||||
def get_spatial_structure_elements_tree(self, collections, name_filter):
|
||||
@@ -970,17 +958,18 @@ class IfcExporter():
|
||||
self.ifc_rep_context['Model'] = {
|
||||
'ifc': self.file.createIfcGeometricRepresentationContext(
|
||||
None, 'Model', 3, 1.0E-05, self.origin)}
|
||||
# TODO Make optional
|
||||
self.ifc_rep_context['Plan'] = {
|
||||
'ifc': self.file.createIfcGeometricRepresentationContext(
|
||||
None, 'Plan', 2, 1.0E-05, self.origin)}
|
||||
for subcontext in (self.ifc_export_settings.subcontexts +
|
||||
self.ifc_export_settings.generated_subcontexts):
|
||||
self.ifc_rep_context['Model'][subcontext] = {
|
||||
'ifc': self.file.createIfcGeometricRepresentationSubContext(
|
||||
subcontext, 'Model',
|
||||
None, None, None, None,
|
||||
self.ifc_rep_context['Model']['ifc'], None, 'MODEL_VIEW', None)}
|
||||
if 'Plan' in self.ifc_export_settings.contexts:
|
||||
self.ifc_rep_context['Plan'] = {
|
||||
'ifc': self.file.createIfcGeometricRepresentationContext(
|
||||
None, 'Plan', 2, 1.0E-05, self.origin)}
|
||||
for context in self.ifc_export_settings.context_tree:
|
||||
for subcontext in context['subcontexts']:
|
||||
self.ifc_rep_context[context['name']][subcontext['name']] = {}
|
||||
for target_view in subcontext['target_views']:
|
||||
self.ifc_rep_context[context['name']][subcontext['name']][target_view] = {
|
||||
'ifc': self.file.createIfcGeometricRepresentationSubContext(
|
||||
subcontext['name'], context['name'], None, None, None, None,
|
||||
self.ifc_rep_context[context['name']]['ifc'], None, target_view, None)}
|
||||
|
||||
def create_project(self):
|
||||
self.ifc_parser.project['attributes'].update({
|
||||
@@ -1119,7 +1108,7 @@ class IfcExporter():
|
||||
for material in self.ifc_parser.materials.values():
|
||||
styled_item = self.create_styled_item(material)
|
||||
styled_representation = self.file.createIfcStyledRepresentation(
|
||||
self.ifc_rep_context['Model']['Body']['ifc'], None, None, [styled_item])
|
||||
self.ifc_rep_context['Model']['Body']['MODEL_VIEW']['ifc'], None, None, [styled_item])
|
||||
material['ifc'] = self.file.createIfcMaterial(material['raw'].name, None, None)
|
||||
self.file.createIfcMaterialDefinitionRepresentation(
|
||||
material['raw'].name, None, [styled_representation], material['ifc'])
|
||||
@@ -1283,7 +1272,7 @@ class IfcExporter():
|
||||
object.bound_box[0][0], object.bound_box[0][1], object.bound_box[0][2]),
|
||||
object.dimensions[0], object.dimensions[1], object.dimensions[2])
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']]['ifc'],
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
|
||||
representation['subcontext'], 'BoundingBox', [bounding_box])
|
||||
|
||||
def create_cog_representation(self, representation):
|
||||
@@ -1291,7 +1280,7 @@ class IfcExporter():
|
||||
cog = self.create_cartesian_point(
|
||||
mesh.vertices[0].co.x, mesh.vertices[0].co.y, mesh.vertices[0].co.z)
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']]['ifc'],
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
|
||||
representation['subcontext'], 'BoundingBox', [cog])
|
||||
|
||||
def create_wireframe_representation(self, representation):
|
||||
@@ -1301,7 +1290,7 @@ class IfcExporter():
|
||||
self.ifc_edges.append(self.file.createIfcPolyline([
|
||||
self.ifc_vertices[v] for v in edge.vertices]))
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']]['ifc'],
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
|
||||
representation['subcontext'], 'Curve',
|
||||
self.ifc_edges)
|
||||
|
||||
@@ -1323,7 +1312,7 @@ class IfcExporter():
|
||||
self.ifc_vertices[i] for i in loop_vertex_indices]))
|
||||
geometric_curve_set = self.file.createIfcGeometricCurveSet(loops)
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']]['ifc'],
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
|
||||
representation['subcontext'], 'GeometricCurveSet', [geometric_curve_set])
|
||||
|
||||
# https://medium.com/@behreajj/scripting-curves-in-blender-with-python-c487097efd13
|
||||
@@ -1377,7 +1366,7 @@ class IfcExporter():
|
||||
# swept_area, self.origin, self.create_curve(representation['raw']),
|
||||
# 0., 1., self.file.createIfcDirection((0.0, -1.0, 0.0)))
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']]['ifc'],
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
|
||||
representation['subcontext'], 'AdvancedSweptSolid',
|
||||
swept_area_solids)
|
||||
|
||||
@@ -1420,7 +1409,7 @@ class IfcExporter():
|
||||
self.file.createIfcDirection((unit_direction.x, unit_direction.y, unit_direction.z)),
|
||||
self.convert_si_to_unit(direction.length))
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']]['ifc'],
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
|
||||
representation['subcontext'], 'SweptSolid',
|
||||
[extruded_area_solid])
|
||||
|
||||
@@ -1482,7 +1471,7 @@ class IfcExporter():
|
||||
self.file.createIfcPolyLoop([self.ifc_vertices[vertice] for vertice in polygon.vertices]),
|
||||
True)]))
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']]['ifc'],
|
||||
self.ifc_rep_context[representation['context']][representation['subcontext']][representation['target_view']]['ifc'],
|
||||
representation['subcontext'], 'Brep',
|
||||
[self.file.createIfcFacetedBrep(self.file.createIfcClosedShell(self.ifc_faces))])
|
||||
|
||||
@@ -1633,5 +1622,33 @@ class IfcExportSettings:
|
||||
self.output_file = None
|
||||
self.has_representations = True
|
||||
self.has_quantities = True
|
||||
self.contexts = ['Model', 'Plan']
|
||||
self.subcontexts = ['Axis', 'FootPrint', 'Reference', 'Body', 'Clearance', 'CoG', 'SurveyPoints']
|
||||
self.generated_subcontexts = ['Box']
|
||||
self.target_views = ['GRAPH_VIEW', 'SKETCH_VIEW', 'MODEL_VIEW', 'PLAN_VIEW', 'REFLECTED_PLAN_VIEW', 'SECTION_VIEW', 'ELEVATION_VIEW', 'USERDEFINED', 'NOTDEFINED']
|
||||
# TODO make this configurable via UI
|
||||
self.context_tree = self.build_context_tree()
|
||||
|
||||
def build_context_tree(self):
|
||||
tree = []
|
||||
for context in self.contexts:
|
||||
subcontexts = []
|
||||
for subcontext in self.subcontexts + self.generated_subcontexts:
|
||||
target_views = []
|
||||
for target_view in self.target_views:
|
||||
if context == 'Model' \
|
||||
and target_view != 'MODEL_VIEW':
|
||||
continue
|
||||
elif context == 'Plan' \
|
||||
and target_view == 'MODEL_VIEW':
|
||||
continue
|
||||
target_views.append(target_view)
|
||||
subcontexts.append({
|
||||
'name': subcontext,
|
||||
'target_views': target_views
|
||||
})
|
||||
tree.append({
|
||||
'name': context,
|
||||
'subcontexts': subcontexts
|
||||
})
|
||||
return tree
|
||||
|
||||
Reference in New Issue
Block a user