diff --git a/callbacks.py b/callbacks.py deleted file mode 100644 index 4e8e0a4bed84d76efba5bcd2d8cb4903b4697d7a..0000000000000000000000000000000000000000 --- a/callbacks.py +++ /dev/null @@ -1,265 +0,0 @@ -import dearpygui.dearpygui as dpg -import tifffile -from uuid import uuid4 - -from utils import * -from constants import SPACE, TREE_COLOR, ROAD_COLOR, BUILDING_COLOR -from remote_run import start_execution_lab_server, start_model_build, get_server_output_structure -from map_edit import dump_height_map, load_height_map, update_texture -from styles import get_accent_color, apply_theme -from generator import LCZ -from config import load_config, dump_config -from dynamic_ui import construct_config_ui, construct_model_output_structure_ui - -def map_window_on_close_clb(s, a, u): - delete_item_and_clear_alias(f'map_buildings_texture') - delete_item_and_clear_alias(f'map_trees_texture') - delete_item_and_clear_alias(f'map_roads_texture') - delete_item_children_and_clear_aliases(f'map_drawlist') - user_data = { - 'buildings_map': None, - 'trees_map': None, - 'roads_map': None, - 'height_map_file_path': None, - 'drawing': False, - 'prev_coords': None, - 'current_action': None, - 'max_height': 0, - 'output_dirs': None, - } - dpg.set_item_user_data('map_window', user_data) - -def set_file_path_clb(s, a, u): - file_path = a['file_path_name'] - dpg.set_value(u, file_path) - -def construct_config_ui_clb(s, a, u): - if not get_config_file_path(): - return - delete_config_items_and_clear_aliases() - update_config_values() - construct_config_ui(get_config_file_path(), get_config()) - - -################################################################################ -# -# Config -# -################################################################################ - - -def update_config_values(): - config = get_config() - for path in config: - if dpg.does_item_exist(f'{get_config_file_path()}.{path}'): - config[path].value = dpg.get_value(f'{get_config_file_path()}.{path}') - set_main_window_value('config', config) - -def config_save_as_clb(s, a, u): - update_config_values() - dump_config(get_config(), a['file_path_name']) - dpg.show_item('message_popup') - -def config_open_clb(s, a, u): - delete_config_items_and_clear_aliases() - config_file_path = a['file_path_name'] - config = load_config(config_file_path) - set_main_window_value('config', config) - set_main_window_value('config_file_path', config_file_path) - construct_config_ui(a['file_path_name'], config) - -def config_save_clb(s, a, u): - update_config_values() - dump_config(get_config(), get_config_file_path()) - dpg.show_item('message_popup') - -def open_config_open_dialog_clb(s, a, u): - dpg.show_item('config_open') - -def show_config_search_window_clb(s, a, u): - dpg.show_item('search_popup') - -def open_config_save_as_dialog_clb(s, a, u): - dpg.show_item('config_open') - -################################################################################ -# -# Config Search -# -################################################################################ - - -def search_clb(s, data, u): - if not get_config_file_path(): - return - - if not data: - return - - for path in get_config(): - if data.lower() in path.split('.')[-1]: - dpg.set_y_scroll('main', dpg.get_item_pos('.'.join([get_config_file_path(), path.split('.')[0]]))[1]) - for tag in path_iter(path, prefix=get_config_file_path()): - if dpg.get_value(COLLAPSING_HEADERS_UI) == True: - dpg.set_value(tag, True) - else: - dpg.set_value(dpg.get_item_parent(dpg.get_item_parent(tag)), dpg.get_item_parent(tag)) - change_color_temporarily('.'.join([get_config_file_path(), path, 'text']), color=get_accent_color()) - - -################################################################################ -# -# Map edit -# -################################################################################ - -def construct_map_layers(w, h): - dpg.set_item_width('map_child_window', w) - dpg.set_item_height('map_child_window', h) - - # dpg.add_texture_registry(tag='textures') - dpg.add_dynamic_texture(w, h, np.zeros(w * h * 4), tag=f'map_buildings_texture', parent='textures') - dpg.add_dynamic_texture(w, h, np.zeros(w * h * 4), tag=f'map_trees_texture', parent='textures') - dpg.add_dynamic_texture(w, h, np.zeros(w * h * 4), tag=f'map_roads_texture', parent='textures') - - dpg.bind_item_theme('map_child_window', 'map_image_theme') - dpg.add_drawlist(w, h, tag=f'map_drawlist', parent='map_child_window', pos=[0, 0]) - - dpg.draw_image(f'map_buildings_texture', color=BUILDING_COLOR, tag=f'map_buildings_image', pmin=(0, 0), pmax=(w, h), parent=f'map_drawlist') - dpg.draw_image(f'map_trees_texture', color=TREE_COLOR, tag=f'map_trees_image', pmin=(0, 0), pmax=(w, h), parent=f'map_drawlist') - dpg.draw_image(f'map_roads_texture', color=ROAD_COLOR, tag=f'map_roads_image', pmin=(0, 0), pmax=(w, h), parent=f'map_drawlist') - -def map_open_clb(s, a, u): - height_map_file_path = a['file_path_name'] - - if height_map_file_path.endswith('txt'): - height_map = load_height_map(height_map_file_path) - max_height = np.max(height_map) - height_map /= max_height - else: - height_map = tifffile.imread(height_map_file_path) - max_height = 1 - - h, w = height_map.shape - - print(dpg.get_item_user_data('map_window')) - - set_map_window_value('buildings_map', height_map) - set_map_window_value('roads_map', np.zeros((h, w))) - set_map_window_value('trees_map', np.zeros((h, w))) - set_map_window_value('height_map_file_path', height_map_file_path) - set_map_window_value('max_height', max_height) - - construct_map_layers(w, h) - - update_texture() - - dpg.show_item('map_window') - -def generate_map_clb(s, a, u): - height_map = LCZ(config_path=f'configs/{s}.json').to_height_map(dtype=np.float64) - - max_height = np.max(height_map) - height_map /= max_height - - h, w = height_map.shape - - set_map_window_value('buildings_map', height_map) - set_map_window_value('roads_map', np.zeros((h, w))) - set_map_window_value('trees_map', np.zeros((h, w))) - set_map_window_value('height_map_file_path', f'{uuid4()}.txt') - set_map_window_value('max_height', max_height) - - construct_map_layers(w, h) - - update_texture() - - dpg.show_item('map_window') - -def save_map(file_path): - if file_path.endswith('.tif') or file_path.endswith('.tiff'): - with TiffWriter(file_path) as tif: - tif.write(get_map_window_value('buildings_map')) - tif.write(get_map_window_value('roads_map')) - tif.write(get_map_window_value('trees_map')) - else: - dump_height_map(get_map_window_value('buildings_map'), file_path) - -def map_save_clb(s, a, u): - file_path = get_height_map_file_path() - save_map(file_path) - dpg.show_item('message_popup') - -def map_save_as_clb(s, a, u): - file_path = a['file_path_name'] - save_map(file_path) - dpg.show_item('message_popup') - -def open_map_save_as_dialog_clb(s, a, u): - dpg.show_item('map_save_as') - -def open_map_open_dialog_clb(s, a, u): - dpg.show_item('map_open') - -def set_action_clb(s, a, u): - set_map_window_value('current_action', s) - -def set_action_none_clb(s, a, u): - set_map_window_value('current_action', None) - - -################################################################################ -# -# Styles -# -################################################################################ - - -def apply_theme_clb(s, a, u): - apply_theme(s) - - -################################################################################ -# -# Remote execution -# -################################################################################ - - -def start_remote_execution_clb(s, a, u): - dpg.configure_item('login_modal', show=False) - u = dpg.get_item_user_data('login_modal') - if u == 'build_model': - start_model_build(dpg.get_value('server_username'), dpg.get_value('server_password'), dpg.get_value('gitlab_username'), dpg.get_value('gitlab_password')) - elif u == 'run_on_lab_server': - start_execution_lab_server(dpg.get_value('server_username'), dpg.get_value('server_password')) - elif u == 'download_output': - s = get_server_output_structure(dpg.get_value('server_username'), dpg.get_value('server_password')) - folders, filepaths = parse_dirs(s) - delete_item_children_and_clear_aliases('output') - construct_model_output_structure_ui(filepaths, folders) - dpg.show_item('model_output_window') - -def build_model_on_lab_server_clb(s, a, u): - pass - -def show_get_credentials_modal_clb(s, a, u): - dpg.set_item_user_data('login_modal', u) - - if u == 'run_on_lab_server': - if not get_config_file_path(): - show_status_text('no config.txt specified. cannot run.') - return - - update_config_values() - - dump_config(get_config(), 'tmp.txt') - - dpg.hide_item('gitlab_password') - dpg.hide_item('gitlab_username') - - elif u == 'download_output': - dpg.hide_item('gitlab_password') - dpg.hide_item('gitlab_username') - - dpg.show_item('login_modal') \ No newline at end of file diff --git a/config.py b/config.py index a35a5417feb8dee77fd42fb9c372fbabdaaa6460..a68c6779240763255e1f670be2cb0417ee72be90 100644 --- a/config.py +++ b/config.py @@ -163,6 +163,7 @@ def load_config(file_path): config = parse(text) for line in lines: + line = line.strip('\r\n') match = re.match(r" > (\w+) '(.*)' = *(.*)", line) if match: value_type, path, value = match.groups() @@ -251,4 +252,6 @@ def dump_config(config, file_path): if __name__ == '__main__': - print(load_config('../config-ex.txt')) \ No newline at end of file + cfg = load_config('../config-neutral-ex.txt') + print(cfg) + print(dump_config(cfg, '../cfg.txt')) \ No newline at end of file diff --git a/config_callbacks.py b/config_callbacks.py index 0cf9b6c5e9ca9b32cdd104694b4f67fb6b2ef6e5..967e4b991c7aff6bbc33f4bc889e9ea9e8ba0cb3 100644 --- a/config_callbacks.py +++ b/config_callbacks.py @@ -1,6 +1,6 @@ import dearpygui.dearpygui as dpg -from utils import get_config_file_path, delete_config_items_and_clear_aliases, update_config_values, get_config, update_config_values, set_main_window_value, change_color_temporarily, path_iter +from utils import show_message, get_config_file_path, delete_config_items_and_clear_aliases, update_config_values, get_config, update_config_values, set_main_window_value, change_color_temporarily, path_iter from style_constants import SPACE, COLLAPSING_HEADERS_UI from style import get_accent_color, apply_theme diff --git a/map_edit_callbacks.py b/map_edit_callbacks.py index f13050f26e26fe1e3f2e6c4347fbfdee780cdac0..48dbe38e5b2142acbbc3319ec966d9e202a77a96 100644 --- a/map_edit_callbacks.py +++ b/map_edit_callbacks.py @@ -1,3 +1,5 @@ +import os + import dearpygui.dearpygui as dpg import tifffile import numpy as np @@ -5,6 +7,7 @@ import numpy as np from map_edit_constants import TREE_COLOR, ROAD_COLOR, BUILDING_COLOR, LAYER_TO_COLOR from map_edit import dump_height_map, load_height_map, update_texture from generator import LCZ +from paths import BASE_PATH from utils import show_message, set_main_window_value, get_config, get_config_file_path, delete_item_and_clear_alias, delete_item_children_and_clear_aliases, set_map_window_value, get_map_window_value, get_height_map_file_path def delete_emission_point_clb(s, a, u): @@ -159,7 +162,7 @@ def map_open_clb(s, a, u): dpg.show_item('map_window') def generate_map_clb(s, a, u): - height_map = LCZ(config_path=f'configs/{s}.json').to_height_map(dtype=np.float64) + height_map = LCZ(config_path=os.path.join(BASE_PATH, 'configs', f'{s}.json')).to_height_map(dtype=np.float64) max_height = np.max(height_map) height_map /= max_height diff --git a/paths.py b/paths.py index ebb9cf724d6f49b379435f20faafb17b32634fdc..c92170276438cd2d7ff286e0b2024639b3b6da08 100644 --- a/paths.py +++ b/paths.py @@ -1,5 +1,8 @@ import os +import sys -FONT_PATH = os.path.join('fonts', 'Montserrat-Medium.ttf') -ICON_PATH = os.path.join('icons', 'icon.ico') -CONFIG_PARSER_EXECUTABLE = "config-parser/parser-cli" \ No newline at end of file +BASE_PATH = getattr(sys, '_MEIPASS', os.getcwd()) + +FONT_PATH = os.path.join(BASE_PATH, 'fonts', 'Montserrat-Medium.ttf') +ICON_PATH = os.path.join(BASE_PATH, 'icons', 'icon.ico') +CONFIG_PARSER_EXECUTABLE = os.path.join(BASE_PATH, 'config-parser', 'parser-cli') \ No newline at end of file diff --git a/remote_run_callbacks.py b/remote_run_callbacks.py index 87cdd2cb97bf612d99efa5437d9f763e585b383e..7356adeae0fc637da2b9cd4c11197a3f9fbd7ad0 100644 --- a/remote_run_callbacks.py +++ b/remote_run_callbacks.py @@ -8,7 +8,7 @@ from uuid import uuid4 import dearpygui.dearpygui as dpg from paramiko.ssh_exception import BadHostKeyException, AuthenticationException, UnableToAuthenticate, NoValidConnectionsError, SSHException -from utils import get_config_file_path, get_config, update_config_values, get_run_window_value, set_run_window_value +from utils import show_message, get_config_file_path, parse_dirs, construct_folder_structure, get_config, update_config_values, get_run_window_value, set_run_window_value, delete_item_children_and_clear_aliases from remote_run import Connection, BuildingSession, RunningSession from remote_run_constants import * from style_constants import FONT_SIZE @@ -201,7 +201,6 @@ def show_download_output_window_clb(s, a, running_session_id): stdout = conn.exec_command(f'cd ./{running_session_id}/output; find . -type f') output = stdout.read().decode() dirs, filepaths = parse_dirs(output) - construct_model_output_structure_ui(filepaths, dirs) dpg.set_item_user_data('model_output_window', (dirs, filepaths, running_session_id)) diff --git a/remote_run_ui.py b/remote_run_ui.py index cb4123a8015cfad724fef67716999a8a4b0ac7ca..fac0c38cb36c2726a5d2d3184e93e0ec2b7340a8 100644 --- a/remote_run_ui.py +++ b/remote_run_ui.py @@ -4,6 +4,7 @@ import os from remote_run_constants import * from remote_run_callbacks import * +from remote_run import * def construct_remote_run_window(): user_data = {