Improved section caching, with annotation objects not cut.

This commit is contained in:
Dion Moult
2020-05-09 15:50:24 +10:00
parent 752a7c9b1c
commit e270cf6989
3 changed files with 37 additions and 31 deletions
+34 -27
View File
@@ -129,11 +129,10 @@ class IfcCutter:
self.cut_polygons = [] self.cut_polygons = []
self.template_variables = {} self.template_variables = {}
self.data_dir = '' self.data_dir = ''
self.ifc_files = [] self.ifc_filenames = []
self.unit = None self.ifc_files = {}
self.resolved_pixels = set() self.resolved_pixels = set()
self.should_get_background = False self.should_get_background = False
self.shapes_pickle_file = 'shapes.pickle'
self.text_pickle_file = 'text.pickle' self.text_pickle_file = 'text.pickle'
self.cut_pickle_file = 'cut.pickle' self.cut_pickle_file = 'cut.pickle'
self.should_recut = True self.should_recut = True
@@ -199,11 +198,10 @@ class IfcCutter:
return return
loaded_files = [] loaded_files = []
for ifc_file in self.ifc_files: for filename in self.ifc_filenames:
print('Loading file {} ...'.format(ifc_file)) print('Loading file {} ...'.format(filename))
if ifc_file: if filename:
loaded_files.append(ifcopenshell.open(ifc_file)) self.ifc_files[filename] = ifcopenshell.open(filename)
self.ifc_files = loaded_files
def get_template_variables(self): def get_template_variables(self):
if not self.should_extract: if not self.should_extract:
@@ -248,24 +246,29 @@ class IfcCutter:
if not self.should_recut: if not self.should_recut:
return return
shape_map = {}
if os.path.isfile(self.shapes_pickle_file):
with open(self.shapes_pickle_file, 'rb') as shape_file:
shape_map = pickle.load(shape_file)
settings = ifcopenshell.geom.settings() settings = ifcopenshell.geom.settings()
settings.set(settings.USE_PYTHON_OPENCASCADE, True) settings.set(settings.USE_PYTHON_OPENCASCADE, True)
products = [] products = []
for ifc_file in self.ifc_files:
for filename, ifc_file in self.ifc_files.items():
shape_pickle = os.path.join(
self.data_dir, 'cache', 'shapes', '{}.pickle'.format(os.path.basename(filename)))
shape_map = {}
if os.path.isfile(shape_pickle):
with open(shape_pickle, 'rb') as shape_file:
shape_map = pickle.load(shape_file)
# TODO: This should perhaps be configurable, e.g. spaces cut to show zones in the drawing # TODO: This should perhaps be configurable, e.g. spaces cut to show zones in the drawing
products.extend(ifc_file.by_type('IfcElement')) products.extend(ifc_file.by_type('IfcElement'))
total_products = len(products)
for i, product in enumerate(products): total_products = len(products)
print('{}/{} geometry processed ...'.format(i, total_products), end='\r', flush=True) for i, product in enumerate(products):
if product.is_a('IfcOpeningElement') or product.is_a('IfcSite'): print('{}/{} geometry processed ...'.format(i, total_products), end='\r', flush=True)
continue if product.is_a('IfcOpeningElement') \
if product.Representation is not None: or product.is_a('IfcSite') \
or product.Representation is None \
or self.has_annotation(product):
continue
try: try:
if product.GlobalId in shape_map: if product.GlobalId in shape_map:
shape = shape_map[product.GlobalId] shape = shape_map[product.GlobalId]
@@ -276,10 +279,16 @@ class IfcCutter:
except: except:
print('Failed to create shape for {}'.format(product)) print('Failed to create shape for {}'.format(product))
if not os.path.isfile(self.shapes_pickle_file): with open(shape_pickle, 'wb') as shape_file:
with open(self.shapes_pickle_file, 'wb') as shape_file:
pickle.dump(shape_map, shape_file, protocol=pickle.HIGHEST_PROTOCOL) pickle.dump(shape_map, shape_file, protocol=pickle.HIGHEST_PROTOCOL)
def has_annotation(self, element):
for representation in element.Representation.Representations:
if representation.ContextOfItems.ContextType == 'Plan' \
and representation.ContextOfItems.ContextIdentifier == 'Annotation':
return True
return False
def sort_background_elements(self, reverse=None): def sort_background_elements(self, reverse=None):
if reverse: if reverse:
new_list = sorted(self.background_elements, key=lambda k: -k['z']) new_list = sorted(self.background_elements, key=lambda k: -k['z'])
@@ -643,7 +652,7 @@ class IfcCutter:
def get_ifc_element(self, global_id): def get_ifc_element(self, global_id):
# TODO: make this less bad # TODO: make this less bad
element = None element = None
for ifc_file in self.ifc_files: for ifc_file in self.ifc_files.values():
try: try:
element = ifc_file.by_id(global_id) element = ifc_file.by_id(global_id)
return element return element
@@ -772,9 +781,7 @@ class SvgWriter():
self.svg.save(pretty=True) self.svg.save(pretty=True)
def calculate_scale(self): def calculate_scale(self):
# TODO: properly handle units self.scale *= 1000 # IFC is in meters, SVG is in mm
if self.ifc_cutter.unit == 'METRE':
self.scale *= 1000
self.raw_width = self.ifc_cutter.section_box['x'] self.raw_width = self.ifc_cutter.section_box['x']
self.raw_height = self.ifc_cutter.section_box['y'] self.raw_height = self.ifc_cutter.section_box['y']
self.width = self.raw_width * self.scale self.width = self.raw_width * self.scale
@@ -0,0 +1,2 @@
*
!.gitignore
@@ -1572,12 +1572,10 @@ class CutSection(bpy.types.Operator):
ifc_cutter = cut_ifc.IfcCutter() ifc_cutter = cut_ifc.IfcCutter()
import ifccsv import ifccsv
ifc_cutter.ifc_attribute_extractor = ifccsv.IfcAttributeExtractor ifc_cutter.ifc_attribute_extractor = ifccsv.IfcAttributeExtractor
ifc_cutter.ifc_files = [i.name for i in bpy.context.scene.DocProperties.ifc_files] ifc_cutter.ifc_filenames = [i.name for i in bpy.context.scene.DocProperties.ifc_files]
ifc_cutter.data_dir = bpy.context.scene.BIMProperties.data_dir ifc_cutter.data_dir = bpy.context.scene.BIMProperties.data_dir
ifc_cutter.diagram_name = self.diagram_name ifc_cutter.diagram_name = self.diagram_name
ifc_cutter.background_image = bpy.context.scene.render.filepath ifc_cutter.background_image = bpy.context.scene.render.filepath
if bpy.context.scene.unit_settings.length_unit == 'METERS':
ifc_cutter.unit = 'METRE'
ifc_cutter.leader_obj = None ifc_cutter.leader_obj = None
ifc_cutter.stair_obj = None ifc_cutter.stair_obj = None
ifc_cutter.dimension_obj = None ifc_cutter.dimension_obj = None
@@ -1619,7 +1617,6 @@ class CutSection(bpy.types.Operator):
'shape': None, 'shape': None,
'face': None 'face': None
} }
ifc_cutter.shapes_pickle_file = os.path.join(ifc_cutter.data_dir, 'shapes.pickle')
ifc_cutter.cut_pickle_file = os.path.join(ifc_cutter.data_dir, '{}-cut.pickle'.format(self.diagram_name)) ifc_cutter.cut_pickle_file = os.path.join(ifc_cutter.data_dir, '{}-cut.pickle'.format(self.diagram_name))
ifc_cutter.should_recut = bpy.context.scene.DocProperties.should_recut ifc_cutter.should_recut = bpy.context.scene.DocProperties.should_recut
ifc_cutter.should_extract = bpy.context.scene.DocProperties.should_extract ifc_cutter.should_extract = bpy.context.scene.DocProperties.should_extract