diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 783d6db47b..9538a75682 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -213,6 +213,7 @@ if bpy is not None: covetool_ui.BIM_PT_covetool, covetool_operator.Login, covetool_operator.RunSimpleAnalysis, + covetool_operator.RunAnalysis, ) def menu_func_export(self, context): diff --git a/src/ifcblenderexport/blenderbim/bim/export_ifc.py b/src/ifcblenderexport/blenderbim/bim/export_ifc.py index e3f798ff9f..b9f81a3a25 100644 --- a/src/ifcblenderexport/blenderbim/bim/export_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/export_ifc.py @@ -159,7 +159,6 @@ class IfcParser(): self.styled_items = self.get_styled_items() self.spatial_structure_elements = self.get_spatial_structure_elements() self.groups = self.get_groups() - self.libraries = self.get_libraries() self.door_attributes = self.get_door_attributes() self.window_attributes = self.get_window_attributes() diff --git a/src/ifcblenderexport/blenderbim/bim/module/covetool/api.py b/src/ifcblenderexport/blenderbim/bim/module/covetool/api.py index 99966b62af..3367430268 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/covetool/api.py +++ b/src/ifcblenderexport/blenderbim/bim/module/covetool/api.py @@ -15,7 +15,7 @@ class Api: def post_request(self, path, data, use_token=True): url = self._api_url(path) headers = self._headers(use_token) - response = requests.post(url, headers=headers, data=data) + response = requests.post(url, headers=headers, json=data) return self._handle_response(response) def get_request(self, path, use_token=True): diff --git a/src/ifcblenderexport/blenderbim/bim/module/covetool/operator.py b/src/ifcblenderexport/blenderbim/bim/module/covetool/operator.py index b6331eedb3..96af3775c4 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/covetool/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/module/covetool/operator.py @@ -61,3 +61,120 @@ class RunSimpleAnalysis(bpy.types.Operator): covetool_results = bpy.data.texts.new('cove.tool Results') covetool_results.write(json.dumps(result, indent=4)) return {'FINISHED'} + + +class RunAnalysis(bpy.types.Operator): + bl_idname = 'bim.covetool_run_analysis' + bl_label = 'Run Analysis' + + def execute(self, context): + self.inputs = { + 'floors': [], + 'walls': [], + 'interior_walls': [], + 'windows': [], + 'skylights': [], + 'roofs': [], + 'shading_devices': [] + } + self.parse_objects() + data = { + 'run': bpy.context.scene.CoveToolProperties.projects[bpy.context.scene.CoveToolProperties.active_project_index].run_set, + 'source': 'BlenderBIM', + 'rotation_angle': 0, + **self.inputs + } + result = api.post_request('run-values', data) + covetool_results = bpy.data.texts.new('cove.tool Results') + covetool_results.write(json.dumps(result, indent=4)) + return {'FINISHED'} + + def parse_objects(self): + for obj in bpy.context.visible_objects: + covetool_category = self.get_covetool_category(obj) + if not covetool_category: + continue + if not self.has_triangulate_modifier(obj): + obj.modifiers.new(name='Triangulate', type='TRIANGULATE') + mesh = obj.evaluated_get(bpy.context.evaluated_depsgraph_get()).to_mesh() + meshes = {} + for polygon in mesh.polygons: + normal = '{}|{}|{}'.format( + round(polygon.normal[0], 2), + round(polygon.normal[1], 2), + round(polygon.normal[2], 2)) + meshes.setdefault(normal, { + 'Mesh': { + 'vertex_indices': {}, + 'Vertices': [], + 'Triangles': [] + }, + 'Center': {}, + 'Normal': { + 'X': round(polygon.normal[0], 2), + 'Y': round(polygon.normal[1], 2), + 'Z': round(polygon.normal[2], 2) + } + }) + for vertex in polygon.vertices: + global_vertex = obj.matrix_world @ mesh.vertices[vertex].co + meshes[normal]['Mesh']['vertex_indices'][vertex] = { + 'X': global_vertex[0] * 3.28084, # Covetools require feet + 'Y': global_vertex[1] * 3.28084, + 'Z': global_vertex[2] * 3.28084 + } + meshes[normal]['Mesh']['Triangles'].append([ + polygon.vertices[0], + polygon.vertices[1], + polygon.vertices[2] + ]) + for normal, mesh in meshes.items(): + sorted_keys = sorted(mesh['Mesh']['vertex_indices']) + mesh['Mesh']['Vertices'] = [mesh['Mesh']['vertex_indices'][k] for k in sorted_keys] + for triangle in mesh['Mesh']['Triangles']: + triangle[0] = sorted_keys.index(triangle[0]) + triangle[1] = sorted_keys.index(triangle[1]) + triangle[2] = sorted_keys.index(triangle[2]) + mesh['Center'] = mesh['Mesh']['Vertices'][0] # Not correct, but just for now + del mesh['Mesh']['vertex_indices'] + self.inputs[covetool_category].extend(meshes.values()) + + def has_triangulate_modifier(self, obj): + for modifier in obj.modifiers: + if modifier.type == 'TRIANGULATE': + return True + + def get_covetool_category(self, obj): + if not hasattr(obj, 'data') or not isinstance(obj.data, bpy.types.Mesh): + return + if 'IfcSlab' in obj.name: + return 'floors' + elif 'IfcRoof' in obj.name: + return 'roofs' + elif 'IfcWall' in obj.name: + if self.is_wall_internal(obj): + return 'interior_walls' + return 'walls' + elif 'IfcWindow' in obj.name: + if self.is_window_skylight(obj): + return 'skylights' + return 'windows' + elif 'IfcShadingDevice' in obj.name: + return 'shading_devices' + + def is_wall_internal(self, obj): + pset_wallcommon = obj.BIMObjectProperties.psets.get('Pset_WallCommon') + if pset_wallcommon: + is_external = pset_wallcommon.properties.get('IsExternal') + if is_external: + if is_external.string_value == 'True': + return False + else: + return True + predefined_type = obj.BIMObjectProperties.attributes.get('PredefinedType') + if predefined_type and predefined_type.string_value in ['MOVABLE', 'PARTITIONING', 'PLUMBINGWALL']: + return True + + def is_window_skylight(self, obj): + predefined_type = obj.BIMObjectProperties.attributes.get('PredefinedType') + return predefined_type and predefined_type.string_value == 'SKYLIGHT' diff --git a/src/ifcblenderexport/blenderbim/bim/module/covetool/ui.py b/src/ifcblenderexport/blenderbim/bim/module/covetool/ui.py index 91d3fe93cd..df9e23c42d 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/covetool/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/module/covetool/ui.py @@ -26,6 +26,9 @@ class BIM_PT_covetool(bpy.types.Panel): layout.template_list('BIM_UL_covetool_projects', '', props, 'projects', props, 'active_project_index') + row = layout.row() + row.operator('bim.covetool_run_analysis') + prop_names = [ 'si_units', 'building_height', 'roof_area', 'floor_area', 'skylight_area', 'wall_area_e', 'wall_area_ne', 'wall_area_n', 'wall_area_nw', 'wall_area_w', 'wall_area_sw', 'wall_area_s',