diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index b2b0918af9..f2fc5461a8 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -7,6 +7,10 @@ if bpy is not None: import bpy from . import ui, prop, operator + from .module.covetool import prop as covetool_prop + from .module.covetool import ui as covetool_ui + from .module.covetool import operator as covetool_operator + classes = ( operator.AssignClass, operator.SelectClass, @@ -201,6 +205,13 @@ if bpy is not None: ui.BIM_UL_topics, ui.BIM_UL_classifications, ui.BIM_ADDON_preferences, + covetool_prop.CoveToolProject, + covetool_prop.CoveToolSimpleAnalysis, + covetool_prop.CoveToolProperties, + covetool_ui.BIM_UL_covetool_projects, + covetool_ui.BIM_PT_covetool, + covetool_operator.Login, + covetool_operator.RunSimpleAnalysis, ) def menu_func_export(self, context): @@ -234,6 +245,7 @@ if bpy is not None: bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties) bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties) + bpy.types.Scene.CoveToolProperties = bpy.props.PointerProperty(type=covetool_prop.CoveToolProperties) def unregister(): for cls in reversed(classes): diff --git a/src/ifcblenderexport/blenderbim/bim/module/covetool/api.py b/src/ifcblenderexport/blenderbim/bim/module/covetool/api.py new file mode 100644 index 0000000000..99966b62af --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/covetool/api.py @@ -0,0 +1,41 @@ +import json +import requests + +class Api: + def login(self, username, password): + data = { + 'username': username, + 'password': password, + } + response_data = self.post_request('get-token', data, False) + if 'token' in response_data: + self.token = str(response_data['token']) + return self.token + + 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) + return self._handle_response(response) + + def get_request(self, path, use_token=True): + url = self._api_url(path) + headers = self._headers(use_token) + response = requests.get(url, headers=headers) + return self._handle_response(response) + + def _api_url(self, path): + return 'https://app.covetool.com/api/' + path + '/' + + def _headers(self, use_token): + headers = {} + if use_token: + headers['Authorization'] = 'Token ' + self.token + return headers + + def _handle_response(self, response): + if response.ok: + return response.json() + else: + return {'result': 'error'} + diff --git a/src/ifcblenderexport/blenderbim/bim/module/covetool/operator.py b/src/ifcblenderexport/blenderbim/bim/module/covetool/operator.py new file mode 100644 index 0000000000..b6331eedb3 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/covetool/operator.py @@ -0,0 +1,63 @@ +import bpy +import json + +from .api import Api + +api = Api() + +class Login(bpy.types.Operator): + bl_idname = 'bim.covetool_login' + bl_label = 'Login to cove.tool' + + def execute(self, context): + token = api.login( + bpy.context.scene.CoveToolProperties.username, + bpy.context.scene.CoveToolProperties.password) + if token: + bpy.context.scene.CoveToolProperties.token = token + + projects = api.get_request('projects') + for project in projects: + new_project = bpy.context.scene.CoveToolProperties.projects.add() + new_project.name = project['name'] + new_project.run_set = project['run_set'][0] + new_project.url = project['url'] + else: + self.report({'ERROR'}, 'Login failed :(') + return {'FINISHED'} + + +class RunSimpleAnalysis(bpy.types.Operator): + bl_idname = 'bim.covetool_run_simple_analysis' + bl_label = 'Run Simple Analysis' + + def execute(self, context): + simple_analysis = bpy.context.scene.CoveToolProperties.simple_analysis + data = { + 'run': bpy.context.scene.CoveToolProperties.projects[bpy.context.scene.CoveToolProperties.active_project_index].run_set, + 'si_units': simple_analysis.si_units, + 'building_height': simple_analysis.building_height, + 'roof_area': simple_analysis.roof_area, + 'floor_area': simple_analysis.floor_area, + 'skylight_area': simple_analysis.skylight_area, + 'wall_area_e': simple_analysis.wall_area_e, + 'wall_area_ne': simple_analysis.wall_area_ne, + 'wall_area_n': simple_analysis.wall_area_n, + 'wall_area_nw': simple_analysis.wall_area_nw, + 'wall_area_w': simple_analysis.wall_area_w, + 'wall_area_sw': simple_analysis.wall_area_sw, + 'wall_area_s': simple_analysis.wall_area_s, + 'wall_area_se': simple_analysis.wall_area_se, + 'window_area_e': simple_analysis.window_area_e, + 'window_area_ne': simple_analysis.window_area_ne, + 'window_area_n': simple_analysis.window_area_n, + 'window_area_nw': simple_analysis.window_area_nw, + 'window_area_w': simple_analysis.window_area_w, + 'window_area_sw': simple_analysis.window_area_sw, + 'window_area_s': simple_analysis.window_area_s, + 'window_area_se': simple_analysis.window_area_se, + } + 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'} diff --git a/src/ifcblenderexport/blenderbim/bim/module/covetool/prop.py b/src/ifcblenderexport/blenderbim/bim/module/covetool/prop.py new file mode 100644 index 0000000000..c8cfee244e --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/covetool/prop.py @@ -0,0 +1,41 @@ +import bpy.props +import bpy.types + + +class CoveToolProject(bpy.types.PropertyGroup): + name: bpy.props.StringProperty(name='Name') + run_set: bpy.props.StringProperty(name='Run Set') + url: bpy.props.StringProperty(name='URL') + + +class CoveToolSimpleAnalysis(bpy.types.PropertyGroup): + si_units: bpy.props.BoolProperty(name='SI Units') + building_height: bpy.props.StringProperty(name='Building Height') + roof_area: bpy.props.StringProperty(name='Roof Area') + floor_area: bpy.props.StringProperty(name='Floor Area') + skylight_area: bpy.props.StringProperty(name='Skylight Area') + wall_area_e: bpy.props.StringProperty(name='Wall Area E') + wall_area_ne: bpy.props.StringProperty(name='Wall Area NE') + wall_area_n: bpy.props.StringProperty(name='Wall Area N') + wall_area_nw: bpy.props.StringProperty(name='Wall Area NW') + wall_area_w: bpy.props.StringProperty(name='Wall Area W') + wall_area_sw: bpy.props.StringProperty(name='Wall Area SW') + wall_area_s: bpy.props.StringProperty(name='Wall Area S') + wall_area_se: bpy.props.StringProperty(name='Wall Area SE') + window_area_e: bpy.props.StringProperty(name='Window Area E') + window_area_ne: bpy.props.StringProperty(name='Window Area NE') + window_area_n: bpy.props.StringProperty(name='Window Area N') + window_area_nw: bpy.props.StringProperty(name='Window Area NW') + window_area_w: bpy.props.StringProperty(name='Window Area W') + window_area_sw: bpy.props.StringProperty(name='Window Area SW') + window_area_s: bpy.props.StringProperty(name='Window Area S') + window_area_se: bpy.props.StringProperty(name='Window Area SE') + + +class CoveToolProperties(bpy.types.PropertyGroup): + username: bpy.props.StringProperty(name='Username') + password: bpy.props.StringProperty(name='Password') + token: bpy.props.StringProperty(name='Token') + projects: bpy.props.CollectionProperty(name='Projects', type=CoveToolProject) + active_project_index: bpy.props.IntProperty(name='Active Project Index') + simple_analysis: bpy.props.PointerProperty(type=CoveToolSimpleAnalysis) diff --git a/src/ifcblenderexport/blenderbim/bim/module/covetool/ui.py b/src/ifcblenderexport/blenderbim/bim/module/covetool/ui.py new file mode 100644 index 0000000000..91d3fe93cd --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/covetool/ui.py @@ -0,0 +1,49 @@ +import bpy.types + +class BIM_PT_covetool(bpy.types.Panel): + bl_label = "cove.tool" + bl_idname = "BIM_PT_covetool" + bl_options = {'DEFAULT_CLOSED'} + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "scene" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + props = scene.CoveToolProperties + + if not props.token: + row = layout.row() + row.prop(props, 'username') + row = layout.row() + row.prop(props, 'password') + row = layout.row() + row.operator('bim.covetool_login') + return + + layout.template_list('BIM_UL_covetool_projects', '', props, 'projects', props, 'active_project_index') + + 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', + 'wall_area_se', 'window_area_e', 'window_area_ne', 'window_area_n', + 'window_area_nw', 'window_area_w', 'window_area_sw', + 'window_area_s', 'window_area_se'] + for prop_name in prop_names: + row = layout.row() + row.prop(props.simple_analysis, prop_name) + + row = layout.row() + row.operator('bim.covetool_run_simple_analysis') + + +class BIM_UL_covetool_projects(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + ob = data + if item: + layout.prop(item, 'name', text='', emboss=False) + else: + layout.label(text='', translate=False) diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 6e04b199d2..85daa6e290 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -1355,4 +1355,3 @@ class BIM_PT_ifcclash(Panel): row = layout.row() row.operator('bim.execute_ifc_clash') -