-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFlyByGen.py
More file actions
185 lines (141 loc) · 7.13 KB
/
FlyByGen.py
File metadata and controls
185 lines (141 loc) · 7.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# Copyright (c) 2023 Tartu University, Ric Dengel
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
The starting file is the FlyByGen.py.
It is responsible for configuration of the project.
This includes:
- Logging tools to enable log files of the process
- Starting of all subprocess which are the building blocks of the project.
:param paths: The Path paramter is a globally defined parameter defined in src/config/paths.json file.
The parameter is imported to each file through the json file and thus does not require to be used as function paramter.
"""
import json
import sys
import os
import logging
import shutil
import subprocess
import time
# BUG: Subprocesses don't terminate in Linux
from src.utils.setup import SetUp
# import signal
# import psutil
# FEATURE: Enable multithreading and locking of json files while scene is generated
class FlyByGen:
def init_for_os(self):
# Determine the operating system
current_os = os.name # 'nt' for Windows, 'posix' for Linux
# Load the appropriate path file based on the operating system
if current_os == 'nt': # Windows
path_file = 'src/config/windows/paths.json'
modules_blender_file = 'src/config/windows/modules_blender.json'
modules_post_file = 'src/config/windows/modules_post.json'
elif current_os == 'posix': # Linux
path_file = 'src/config/linux/paths.json'
modules_blender_file = 'src/config/linux/modules_blender.json'
modules_post_file = 'src/config/linux/modules_post.json'
else:
raise Exception(f"Unsupported operating system: {current_os}")
# Destination path file (common for both OS)
active_path_file = 'src/config/paths.json'
active_modules_blender_file = 'src/config/modules_blender.json'
active_modules_post_file = 'src/config/modules_post.json'
# Copy the content of the source path file to the destination path file
shutil.copyfile(path_file, active_path_file)
shutil.copyfile(modules_blender_file, active_modules_blender_file)
shutil.copyfile(modules_post_file, active_modules_post_file)
with open('src/config/paths.json', 'r') as f:
self.paths = json.load(f)
sys.path.append(self.paths['project_directory'])
# DOC: Add paths link to documentation
def logging_setup(self):
"""
Instantiates the logger and starts logging everything after the configuration is done
:return: A Output Logger object used to run subprocesses with active logging.
:rtype: obj[OutputLogger]
"""
FlyGenLogger = OutputLogger(self.paths)
FlyGenLogger.create_log_file()
FlyGenLogger.configure_logging()
FlyGenLogger.log_output_file()
return FlyGenLogger
# DOC: Add paths link to documentation
# FEATURE: Allow for more modular backend. Command should not be defined here. Define fully in json?
# FEATURE: Enable different logging levels and implement according messages
def set_blender_paths(self):
"""
Loads the commands from the json file and combines the blocks into a string which can be run by a subprocess
:return: Blender subprocess execution command
:rtype: [str]
"""
blender_path = self.paths['blender_path']
blend_file = self.paths['blend_file']
bpy_controller = self.paths['bpy_controller']
# return [blender_path, "-b", blend_file, "-P", bpy_controller]
return [blender_path, "-b", blend_file, "-P", bpy_controller]
def set_post_processing_path(self):
"""
Loads the commands from the json file and combines the blocks into a string which can be run by a subprocess
:return: post processing subprocess execution command
:rtype: [str]
"""
post_controller_python = self.paths["post_controller_python"]
post_processing_controller = self.paths['post_controller_path']
return [post_controller_python, post_processing_controller]
# BUG: Subprocesses don't terminate in Linux
# def cleanup_processes(self):
# # Check for and terminate any remaining subprocesses
# for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
# if 'blender' in proc.info['cmdline']:
# logging.warning(f"Terminating detached Blender process: {proc.info['pid']}")
# try:
# proc.terminate()
# except psutil.NoSuchProcess:
# pass
def run_graphics_module(self, cmd, config_path = None):
# FEATURE: run combinations of multiple config file data contents
if not config_path == None:
logging.info(f"Received config_path_list")
config_data = JsonParameterUpdater(config_path[0], config_path[1], config_path[2], self.FlyGenLogger)
adjustment_data, target_data = config_data.create_parameter_combinations()
config_data.run_parameter_combinations(adjustment_data, target_data, cmd)
# Set config
def __init__(self):
self.FlyGenLogger = self.logging_setup()
# BUG: Subprocesses don't terminate in Linux
main_setup = SetUp()
main_setup.check_libraries()
# signal.signal(signal.SIGTERM, self.cleanup_processes)
logging.info("Starting FlyByGen")
logging.info("Test print")
start_time = time.time()
# Run Graphics Module
config_path = ["src/config/blender/nucleus.json", "src/config/blender/nucleus_parameter_ranges.json", "src/config/blender/nucleus_increments.json"]
blender_command = self.set_blender_paths()
self.run_graphics_module(blender_command, config_path)
blender_time = time.time()
# Running python post processing
post_process_command = self.set_post_processing_path()
self.FlyGenLogger.run_subprocess(post_process_command)
post_time = time.time()
render = blender_time-start_time
post_processing_time = post_time-blender_time
total_time = post_time-start_time
logging.info(f"Render took: {int(render/60)}min {render%60}s")
logging.info(f"Post processing took: {int(post_processing_time/60)}min {(post_processing_time%60)}s")
logging.info(f"Pipeline ran for: {int(total_time/60)}min {total_time%60}s")
logging.info("Finished everything")
# print("Starting FlyByGen!")
FlyByGen.init_for_os(FlyByGen)
from src.utils.OutputLogger import OutputLogger
from src.utils.JsonParameterHandler import JsonParameterUpdater
FlyByGen()