mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
Improve prototype of native round-tripping by reading from original file and preserving styles
This commit is contained in:
@@ -8,8 +8,9 @@ import zipfile
|
|||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from .helper import SIUnitHelper
|
from .helper import SIUnitHelper, get_representation_elements
|
||||||
from . import schema
|
from . import schema
|
||||||
|
from . import ifc
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import addon_utils
|
import addon_utils
|
||||||
|
|
||||||
@@ -1027,7 +1028,7 @@ class IfcParser():
|
|||||||
obj.data, obj, 'Model', 'Body', 'MODEL_VIEW')
|
obj.data, obj, 'Model', 'Body', 'MODEL_VIEW')
|
||||||
if 'Model/Box/MODEL_VIEW' in self.generated_subcontexts:
|
if 'Model/Box/MODEL_VIEW' in self.generated_subcontexts:
|
||||||
if self.ifc_export_settings.should_roundtrip_native \
|
if self.ifc_export_settings.should_roundtrip_native \
|
||||||
and obj.data.BIMMeshProperties.ifc_definition:
|
and obj.data.BIMMeshProperties.ifc_definition_id:
|
||||||
return
|
return
|
||||||
self.representations['Model/Box/MODEL_VIEW/{}'.format(obj.data.name)] = self.get_representation(
|
self.representations['Model/Box/MODEL_VIEW/{}'.format(obj.data.name)] = self.get_representation(
|
||||||
obj.data, obj, 'Model', 'Box', 'MODEL_VIEW')
|
obj.data, obj, 'Model', 'Box', 'MODEL_VIEW')
|
||||||
@@ -1068,7 +1069,7 @@ class IfcParser():
|
|||||||
if 'Model/Box/MODEL_VIEW' in self.generated_subcontexts \
|
if 'Model/Box/MODEL_VIEW' in self.generated_subcontexts \
|
||||||
and context_prefix == 'Model/Body/MODEL_VIEW':
|
and context_prefix == 'Model/Body/MODEL_VIEW':
|
||||||
if self.ifc_export_settings.should_roundtrip_native \
|
if self.ifc_export_settings.should_roundtrip_native \
|
||||||
and obj.data.BIMMeshProperties.ifc_definition:
|
and obj.data.BIMMeshProperties.ifc_definition_id:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.representations['Model/Box/MODEL_VIEW/{}'.format(mesh_name.split('/')[3])] = self.get_representation(
|
self.representations['Model/Box/MODEL_VIEW/{}'.format(mesh_name.split('/')[3])] = self.get_representation(
|
||||||
@@ -1101,6 +1102,7 @@ class IfcParser():
|
|||||||
'context': context,
|
'context': context,
|
||||||
'subcontext': subcontext,
|
'subcontext': subcontext,
|
||||||
'target_view': target_view,
|
'target_view': target_view,
|
||||||
|
'has_ifc_definition': False if not hasattr(mesh, 'BIMMeshProperties') else (mesh.BIMMeshProperties.ifc_definition or mesh.BIMMeshProperties.ifc_definition_id),
|
||||||
'ifc_definition': mesh.BIMMeshProperties.ifc_definition if hasattr(mesh, 'BIMMeshProperties') else None,
|
'ifc_definition': mesh.BIMMeshProperties.ifc_definition if hasattr(mesh, 'BIMMeshProperties') else None,
|
||||||
'ifc_definition_id': mesh.BIMMeshProperties.ifc_definition_id if hasattr(mesh, 'BIMMeshProperties') else None,
|
'ifc_definition_id': mesh.BIMMeshProperties.ifc_definition_id if hasattr(mesh, 'BIMMeshProperties') else None,
|
||||||
'is_parametric': mesh.BIMMeshProperties.is_parametric if hasattr(mesh, 'BIMMeshProperties') else False,
|
'is_parametric': mesh.BIMMeshProperties.is_parametric if hasattr(mesh, 'BIMMeshProperties') else False,
|
||||||
@@ -1172,7 +1174,9 @@ class IfcParser():
|
|||||||
parsed_data_names = []
|
parsed_data_names = []
|
||||||
for product in self.selected_products + self.type_products:
|
for product in self.selected_products + self.type_products:
|
||||||
obj = product['raw']
|
obj = product['raw']
|
||||||
if obj.data is None or obj.data.name in parsed_data_names:
|
if obj.data is None \
|
||||||
|
or obj.data.name in parsed_data_names \
|
||||||
|
or obj.data.BIMMeshProperties.ifc_definition_id:
|
||||||
continue
|
continue
|
||||||
parsed_data_names.append(obj.data.name)
|
parsed_data_names.append(obj.data.name)
|
||||||
for slot in obj.material_slots:
|
for slot in obj.material_slots:
|
||||||
@@ -2180,7 +2184,7 @@ class IfcExporter():
|
|||||||
results = []
|
results = []
|
||||||
for representation_name in product['representations']:
|
for representation_name in product['representations']:
|
||||||
representation = self.ifc_parser.representations[representation_name]
|
representation = self.ifc_parser.representations[representation_name]
|
||||||
if self.ifc_export_settings.should_roundtrip_native and representation['ifc_definition']:
|
if self.ifc_export_settings.should_roundtrip_native and representation['has_ifc_definition']:
|
||||||
results.append(representation['ifc'])
|
results.append(representation['ifc'])
|
||||||
else:
|
else:
|
||||||
results.append(self.get_product_mapped_geometry(product, representation))
|
results.append(self.get_product_mapped_geometry(product, representation))
|
||||||
@@ -2233,7 +2237,7 @@ class IfcExporter():
|
|||||||
self.file.createIfcDirection((forward.x, forward.y, forward.z)))
|
self.file.createIfcDirection((forward.x, forward.y, forward.z)))
|
||||||
|
|
||||||
def create_representation(self, representation):
|
def create_representation(self, representation):
|
||||||
if self.ifc_export_settings.should_roundtrip_native and representation['ifc_definition']:
|
if self.ifc_export_settings.should_roundtrip_native and representation['has_ifc_definition']:
|
||||||
return self.create_representation_from_definition(representation)
|
return self.create_representation_from_definition(representation)
|
||||||
self.ifc_vertices = []
|
self.ifc_vertices = []
|
||||||
self.ifc_edges = []
|
self.ifc_edges = []
|
||||||
@@ -2245,28 +2249,32 @@ class IfcExporter():
|
|||||||
return self.create_variable_representation(representation)
|
return self.create_variable_representation(representation)
|
||||||
|
|
||||||
def create_representation_from_definition(self, representation):
|
def create_representation_from_definition(self, representation):
|
||||||
# See bug #999 on why we don't garbage collect the temporary IFC file
|
if representation['ifc_definition']:
|
||||||
representation['ifc_definition_file'] = ifcopenshell.file.from_string(representation['ifc_definition'])
|
print('Authoring an IFC definition directly is not yet implemented')
|
||||||
entry = self.file.add(representation['ifc_definition_file'].by_id(representation['ifc_definition_id']))
|
return
|
||||||
substitutions = []
|
elif representation['ifc_definition_id']:
|
||||||
for element in representation['ifc_definition_file']:
|
entry = self.file.add(ifc.IfcStore.get_file().by_id(representation['ifc_definition_id']))
|
||||||
added_element = self.file.add(element)
|
substitutions = []
|
||||||
if added_element.is_a('IfcGeometricRepresentationContext'):
|
for element in get_representation_elements(
|
||||||
substitutions.append(added_element)
|
ifc.IfcStore.get_file(), representation['ifc_definition_id']):
|
||||||
for element in substitutions:
|
added_element = self.file.add(element)
|
||||||
if element.is_a() == 'IfcGeometricRepresentationContext':
|
if added_element.is_a('IfcGeometricRepresentationContext'):
|
||||||
new_element = [e for e in
|
substitutions.append(added_element)
|
||||||
self.file.by_type('IfcGeometricRepresentationContext')
|
for element in substitutions:
|
||||||
if e.ContextType == element.ContextType][0]
|
if element.is_a() == 'IfcGeometricRepresentationContext':
|
||||||
elif element.is_a() == 'IfcGeometricRepresentationSubContext':
|
new_element = [e for e in
|
||||||
new_element = [e for e in
|
self.file.by_type('IfcGeometricRepresentationContext')
|
||||||
self.file.by_type('IfcGeometricRepresentationContext')
|
if e.ContextType == element.ContextType][0]
|
||||||
if e.ContextType == element.ContextType and
|
elif element.is_a() == 'IfcGeometricRepresentationSubContext':
|
||||||
e.ContextIdentifier == element.ContextIdentifier][0]
|
new_element = [e for e in
|
||||||
for inverse in self.file.get_inverse(element):
|
self.file.by_type('IfcGeometricRepresentationContext')
|
||||||
ifcopenshell.util.element.replace_attribute(inverse, element, new_element)
|
if e.ContextType == element.ContextType and
|
||||||
self.file.remove(element)
|
e.ContextIdentifier == element.ContextIdentifier][0]
|
||||||
return entry
|
for inverse in self.file.get_inverse(element):
|
||||||
|
ifcopenshell.util.element.replace_attribute(inverse, element, new_element)
|
||||||
|
# TODO: Work out how and when to purge this
|
||||||
|
#self.file.remove(element)
|
||||||
|
return entry
|
||||||
|
|
||||||
def create_model_representation(self, representation):
|
def create_model_representation(self, representation):
|
||||||
if representation['subcontext'] == 'Annotation':
|
if representation['subcontext'] == 'Annotation':
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
import math
|
import math
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
|
# TODO: figure out where this should go
|
||||||
|
def get_representation_elements(ifc_file, step_id):
|
||||||
|
results = []
|
||||||
|
for child in ifc_file.traverse(ifc_file.by_id(step_id)):
|
||||||
|
if hasattr(child, 'StyledByItem') and child.StyledByItem:
|
||||||
|
for styled_by_item in child.StyledByItem:
|
||||||
|
for style in styled_by_item.Styles:
|
||||||
|
for style_child in ifc_file.traverse(style):
|
||||||
|
results.append(style_child)
|
||||||
|
results.append(child)
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
# TODO: Deprecate this in favour of ifcopenshell.util.unit
|
# TODO: Deprecate this in favour of ifcopenshell.util.unit
|
||||||
|
|
||||||
class SIUnitHelper:
|
class SIUnitHelper:
|
||||||
|
|||||||
@@ -1938,17 +1938,11 @@ class IfcImporter():
|
|||||||
mesh.BIMMeshProperties.geometry_type = str(self.get_geometry_type(element))
|
mesh.BIMMeshProperties.geometry_type = str(self.get_geometry_type(element))
|
||||||
if not self.ifc_import_settings.should_roundtrip_native:
|
if not self.ifc_import_settings.should_roundtrip_native:
|
||||||
return
|
return
|
||||||
dummy = ifcopenshell.file(schema=self.file.schema)
|
|
||||||
if element.is_a('IfcRepresentation'):
|
if element.is_a('IfcRepresentation'):
|
||||||
representation = element
|
representation = element
|
||||||
else:
|
else:
|
||||||
representation = self.get_representation_of_context(element.Representation.Representations, shape.context)
|
representation = self.get_representation_of_context(element.Representation.Representations, shape.context)
|
||||||
mesh.BIMMeshProperties.ifc_definition_id = int(dummy.add(representation).id())
|
mesh.BIMMeshProperties.ifc_definition_id = int(representation.id())
|
||||||
for child in self.file.traverse(representation):
|
|
||||||
[dummy.add(inverse) for inverse in self.file.get_inverse(child)]
|
|
||||||
dummy.add(child)
|
|
||||||
mesh.BIMMeshProperties.ifc_definition = dummy.to_string()
|
|
||||||
|
|
||||||
|
|
||||||
def create_curve(self, geometry):
|
def create_curve(self, geometry):
|
||||||
curve = bpy.data.curves.new(geometry.id, type='CURVE')
|
curve = bpy.data.curves.new(geometry.id, type='CURVE')
|
||||||
|
|||||||
Reference in New Issue
Block a user