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.template_variables = {}
self.data_dir = ''
self.ifc_files = []
self.unit = None
self.ifc_filenames = []
self.ifc_files = {}
self.resolved_pixels = set()
self.should_get_background = False
self.shapes_pickle_file = 'shapes.pickle'
self.text_pickle_file = 'text.pickle'
self.cut_pickle_file = 'cut.pickle'
self.should_recut = True
@@ -199,11 +198,10 @@ class IfcCutter:
return
loaded_files = []
for ifc_file in self.ifc_files:
print('Loading file {} ...'.format(ifc_file))
if ifc_file:
loaded_files.append(ifcopenshell.open(ifc_file))
self.ifc_files = loaded_files
for filename in self.ifc_filenames:
print('Loading file {} ...'.format(filename))
if filename:
self.ifc_files[filename] = ifcopenshell.open(filename)
def get_template_variables(self):
if not self.should_extract:
@@ -248,24 +246,29 @@ class IfcCutter:
if not self.should_recut:
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.set(settings.USE_PYTHON_OPENCASCADE, True)
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
products.extend(ifc_file.by_type('IfcElement'))
total_products = len(products)
for i, product in enumerate(products):
print('{}/{} geometry processed ...'.format(i, total_products), end='\r', flush=True)
if product.is_a('IfcOpeningElement') or product.is_a('IfcSite'):
continue
if product.Representation is not None:
total_products = len(products)
for i, product in enumerate(products):
print('{}/{} geometry processed ...'.format(i, total_products), end='\r', flush=True)
if product.is_a('IfcOpeningElement') \
or product.is_a('IfcSite') \
or product.Representation is None \
or self.has_annotation(product):
continue
try:
if product.GlobalId in shape_map:
shape = shape_map[product.GlobalId]
@@ -276,10 +279,16 @@ class IfcCutter:
except:
print('Failed to create shape for {}'.format(product))
if not os.path.isfile(self.shapes_pickle_file):
with open(self.shapes_pickle_file, 'wb') as shape_file:
with open(shape_pickle, 'wb') as shape_file:
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):
if reverse:
new_list = sorted(self.background_elements, key=lambda k: -k['z'])
@@ -643,7 +652,7 @@ class IfcCutter:
def get_ifc_element(self, global_id):
# TODO: make this less bad
element = None
for ifc_file in self.ifc_files:
for ifc_file in self.ifc_files.values():
try:
element = ifc_file.by_id(global_id)
return element
@@ -772,9 +781,7 @@ class SvgWriter():
self.svg.save(pretty=True)
def calculate_scale(self):
# TODO: properly handle units
if self.ifc_cutter.unit == 'METRE':
self.scale *= 1000
self.scale *= 1000 # IFC is in meters, SVG is in mm
self.raw_width = self.ifc_cutter.section_box['x']
self.raw_height = self.ifc_cutter.section_box['y']
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()
import ifccsv
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.diagram_name = self.diagram_name
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.stair_obj = None
ifc_cutter.dimension_obj = None
@@ -1619,7 +1617,6 @@ class CutSection(bpy.types.Operator):
'shape': 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.should_recut = bpy.context.scene.DocProperties.should_recut
ifc_cutter.should_extract = bpy.context.scene.DocProperties.should_extract