RuntimeScene
1# coding: utf-8 2# This script construct a less scene, which supports the modification of non-structural parameters dynamically 3import os 4import sys 5from importlib import reload 6import multiprocessing 7import json 8import numpy as np 9from PostProcessing import RasterHelper 10from Observation import ObservationOrthographic 11from Terrain import TERRAIN_BRDF_TYPE 12 13 14class RuntimeScene(object): 15 def __init__(self, simulation): 16 self.__simulation = simulation 17 self.less_runtime_scene = None 18 self.__sim_mode = "devel11" 19 20 # load mitsuba 21 self.__init_mitsuba_path() 22 globals()["mitsuba"] = __import__("mitsuba") 23 reload(mitsuba) 24 25 self.pmgr = mitsuba.core.PluginManager.getInstance() 26 27 # for simulation 28 self.queue = mitsuba.render.RenderQueue() 29 # prepare for simulation 30 self.scheduler = mitsuba.core.Scheduler.getInstance() 31 # Start up the scheduling system with one worker per local core 32 min_cores = min(multiprocessing.cpu_count(), 33 int(self.__simulation.get_scene().get_advanced_params().number_of_cores)) 34 print("INFO: Using number of cores:", min_cores) 35 if not self.scheduler.isRunning(): 36 for i in range(0, min_cores): 37 self.scheduler.registerWorker(mitsuba.core.LocalWorker(i, 'wrk%i' % i)) 38 self.scheduler.start() 39 40 def shutdown_simulator(self): 41 self.queue.join() 42 self.scheduler.stop() 43 44 def __init_mitsuba_path(self): 45 band_num = self.__simulation.get_scene().get_sensor().get_number_of_bands() 46 if not os.path.exists(".less"): 47 os.mkdir(".less") 48 with open(".less/num.cfg", "w") as f: 49 f.write(str(band_num)) 50 with open(".less/range.cfg", "w") as f: 51 f.write("360 830") 52 pyd_dir = "" 53 dll_path = "" 54 currdir = os.path.split(os.path.realpath(__file__))[0] 55 if currdir.startswith(r"E:\03-Coding\lessrt"): 56 self.__sim_mode = "devel" 57 if self.__sim_mode == "devel": 58 lessrt_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) 59 pyd_dir = os.path.join(lessrt_dir, "python", "lesspy", "bin", "rt", "lessrt", "python", "3.10") 60 dll_path = os.path.join(lessrt_dir, "python", "lesspy", "bin", "rt", "lessrt") 61 else: 62 root_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) 63 pyd_dir = os.path.join(root_dir, "bin", "scripts", "Lesspy", "bin", "rt", "lessrt", "python", "3.10") 64 dll_path = os.path.join(root_dir, "bin", "scripts", "Lesspy", "bin", "rt", "lessrt") 65 66 sys.path.append(pyd_dir) 67 os.add_dll_directory(dll_path) 68 # os.environ['PATH'] = dll_path + os.pathsep + os.environ['PATH'] 69 70 def get_xml_dir(self): 71 sim_dir = self.__simulation.get_sim_dir() 72 xml_dir = os.path.join(sim_dir, "Parameters", "_scenefile") 73 return xml_dir 74 75 def load_scene(self, scene_name="main.xml"): 76 xml_dir = self.get_xml_dir() 77 fileResolver = mitsuba.core.Thread.getThread().getFileResolver() 78 logger = mitsuba.core.Thread.getThread().getLogger() 79 # logger.clearAppenders() 80 fileResolver.appendPath(str(xml_dir)) 81 self.less_runtime_scene = mitsuba.render.SceneHandler.loadScene( 82 fileResolver.resolve(os.path.join(xml_dir, scene_name))) 83 self.less_runtime_scene.configure() 84 self.less_runtime_scene.initialize() 85 86 def update_parameters(self): 87 cwd = os.getcwd() 88 sim_dir = sim_dir = self.__simulation.get_sim_dir() 89 os.chdir(sim_dir) 90 interpreter = self.__simulation.get_scene_helper().get_py_interpreter_path() 91 script_lesspy_path = self.__simulation.get_scene_helper().get_script_less_py_path() 92 os.system(interpreter + " " + script_lesspy_path + " -g v1") 93 os.chdir(cwd) 94 95 xml_dir = self.get_xml_dir() 96 fileResolver = mitsuba.core.Thread.getThread().getFileResolver() 97 logger = mitsuba.core.Thread.getThread().getLogger() 98 # logger.clearAppenders() 99 fileResolver.appendPath(str(xml_dir)) 100 tmp_scene = mitsuba.render.SceneHandler.loadScene( 101 fileResolver.resolve(os.path.join(xml_dir, "tmp_main.xml"))) 102 tmp_scene.configure() 103 104 # update sensor 105 new_sensor = tmp_scene.getSensor() 106 self.less_runtime_scene.addSensor(new_sensor) 107 self.less_runtime_scene.setSensor(new_sensor) 108 # directly create sensor from properties is not possible from python because the properties are not complete 109 # new_sensor_props = tmp_scene.getSensor().getProperties() 110 # tmp_sensor = self.pmgr.createObject(new_sensor_props) 111 # tmp_film = self.pmgr.createObject(tmp_scene.getFilm().getProperties()) 112 # tmp_film.configure() 113 # tmp_sensor.addChild(tmp_film) 114 # tmp_sensor.configure() 115 # self.less_runtime_scene.addSensor(tmp_sensor) 116 # self.less_runtime_scene.setSensor(tmp_sensor) 117 # self.less_runtime_scene.setSampler(tmp_scene.getSampler()) 118 119 # update illumination 120 for emitter in self.less_runtime_scene.getEmitters(): 121 self.less_runtime_scene.removeEmitter(emitter) 122 emitters = tmp_scene.getEmitters() 123 for emitter in emitters: 124 self.less_runtime_scene.addChild(emitter) 125 126 # update BSDF 127 # update terrain BRDF 128 landscape = self.__simulation.get_scene().get_landscape() 129 if landscape.get_terrain().get_terr_brdf_type() != TERRAIN_BRDF_TYPE.LAMBERTIAN: 130 print("INFO: Only Lambertian supports runtime modification of scene properties currently, If" 131 "you want to use other BRDF types, plase contact [email protected]") 132 sys.exit(0) 133 terrain_op_name = landscape.get_terrain().get_optical() 134 terrain_ref = landscape.get_op_item(terrain_op_name).get_op_front_reflectance() 135 soil_op_obj = self.__create_terrain_bsdf(terrain_ref) 136 for shape in self.less_runtime_scene.getShapes(): 137 if shape.getID() == "terrain": 138 shape.setBSDF(soil_op_obj) 139 break 140 141 ## update op 142 sgroups = landscape.get_objects() 143 group_names = list(sgroups.keys()) 144 modified_phases = [] 145 for ins_shape in self.less_runtime_scene.getShapes(): 146 if ins_shape.getID() != "terrain": 147 shape_group_id = ins_shape.getShapeGroup().getID() 148 if shape_group_id in group_names: 149 mesh_shapes = ins_shape.getShapeGroup().getKDTree().getShapes() 150 values = list(sgroups[shape_group_id].values()) 151 idx = 0 152 for mesh_shape in mesh_shapes: 153 op_name = values[idx]["op_name"] 154 is_turbid = values[idx]["is_turbid"] 155 lad = values[idx]["lad"] 156 op_item = landscape.get_op_item(op_name) 157 if not is_turbid: 158 mix_bsdf = self.__create_mixture_bsdf(op_item.get_op_front_reflectance(), 159 op_item.get_op_back_reflectance(), 160 op_item.get_op_transmittance()) 161 mesh_shape.addChild(mix_bsdf) 162 else: # turbid medium: modifying phase function and configure medium 163 inter_medium = mesh_shape.getInteriorMedium() 164 leaf_density = values[idx]["leaf_density"] 165 hotspot_factor = values[idx]["hotspot_factor"] 166 optical_lad = op_name + "_" + lad 167 if optical_lad not in modified_phases: # 当前组分所使用的phase function如果没更新,则更新 168 modified_phases.append(optical_lad) 169 phase_function = inter_medium.getPhaseFunction() 170 phase_function.isConfigured = False # reset the configuration to recompute phase values 171 phase_function.frontRef = mitsuba.core.Spectrum(op_item.get_op_front_reflectance()) 172 phase_function.backRef = mitsuba.core.Spectrum(op_item.get_op_back_reflectance()) 173 phase_function.transmittance = mitsuba.core.Spectrum(op_item.get_op_transmittance()) 174 phase_function.opticalName = op_name 175 phase_function.ladType = self.__get_lad_type(lad) 176 phase_function.configure() 177 inter_medium.ladType = self.__get_lad_type(lad) 178 inter_medium.leafAreaDensity = leaf_density 179 inter_medium.hotspotFactor = hotspot_factor 180 inter_medium.configure() 181 idx += 1 182 group_names.remove(shape_group_id) 183 if len(group_names) == 0: 184 break 185 186 def start(self): 187 job = mitsuba.render.RenderJob('Simulating', self.less_runtime_scene, self.queue) 188 job.start() 189 self.queue.waitLeft(0) 190 self.__post_processing() 191 192 def __create_terrain_bsdf(self, reflectance): 193 bsdf = self.__create_object('diffuse', {'reflectance': mitsuba.core.Spectrum(reflectance)}) 194 bsdf.configure() 195 return bsdf 196 197 def __create_object(self, name: str, properties: {}): 198 props = mitsuba.core.Properties(name) 199 for key in properties: 200 props[key] = properties[key] 201 return self.pmgr.createObject(props) 202 203 def __create_mixture_bsdf(self, reflectance_front=0.4, reflectance_back=0.4, transmittance=0.4): 204 mixbsdf = self.__create_object('mixturebsdf', {'ensureEnergyConservation': False, 'weights': '1, 1'}) 205 twosidedbsdf = self.__create_object('twosided', {}) 206 refbsdf = self.__create_object("diffuse", {'reflectance': mitsuba.core.Spectrum(reflectance_front)}) 207 refbsdf.configure() 208 twosidedbsdf.addChild(refbsdf) 209 refbsdf = self.__create_object("diffuse", {'reflectance': mitsuba.core.Spectrum(reflectance_back)}) 210 refbsdf.configure() 211 twosidedbsdf.addChild(refbsdf) 212 twosidedbsdf.configure() 213 transbsdf = self.__create_object('difftrans', {'transmittance': mitsuba.core.Spectrum(transmittance)}) 214 transbsdf.configure() 215 mixbsdf.addChild(twosidedbsdf) 216 mixbsdf.addChild(transbsdf) 217 mixbsdf.configure() 218 return mixbsdf 219 220 def __get_lad_type(self, lad_str): 221 if lad_str == "Spherical": 222 return mitsuba.render.PhaseFunction.ESpherical 223 if lad_str == "Uniform": 224 return mitsuba.render.PhaseFunction.EUniform 225 if lad_str == "Planophile": 226 return mitsuba.render.PhaseFunction.EPlanophile 227 if lad_str == "Erectophile": 228 return mitsuba.render.PhaseFunction.EErectophile 229 if lad_str == "Plagiophile": 230 return mitsuba.render.PhaseFunction.EPlagiophile 231 if lad_str == "Extremophile": 232 return mitsuba.render.PhaseFunction.EExtremophile 233 return mitsuba.render.ELadType.EINVALIDE 234 235 def __post_processing(self): 236 sim_dir = self.__simulation.get_sim_dir() 237 distFile = self.__simulation.get_dist_file() 238 infofile = os.path.join(sim_dir, "Results", "spectral.txt") 239 f = open(infofile, 'w') 240 f.write(os.path.basename(distFile)) 241 f.close() 242 243 cfgfile = os.path.join(sim_dir, "Parameters", "input.conf") 244 f = open(cfgfile, 'r') 245 cfg = json.load(f) 246 247 output_format = "ENVI" 248 if cfg["sensor"]["sensor_type"] == "PhotonTracing": 249 out_file_no_extension = distFile + "_downwelling" 250 output_fileName = distFile + "_downwelling.npy" 251 if output_format not in ("npy", "NPY") and os.path.exists(output_fileName): 252 data = np.load(output_fileName) 253 bandlist = cfg["sensor"]["bands"].split(",") 254 RasterHelper.saveToHdr_no_transform(data, out_file_no_extension, bandlist, output_format) 255 os.remove(output_fileName) 256 out_file_no_extension = distFile + "_upwelling" 257 output_fileName = distFile + "_upwelling.npy" 258 if output_format not in ("npy", "NPY") and os.path.exists(output_fileName): 259 data = np.load(output_fileName) 260 bandlist = cfg["sensor"]["bands"].split(",") 261 RasterHelper.saveToHdr_no_transform(data, out_file_no_extension, bandlist, output_format) 262 os.remove(output_fileName) 263 else: 264 out_file_no_extension = distFile + "_4Components" 265 output_fileName = distFile + "_4Components.npy" 266 267 if output_format not in ("npy", "NPY") and os.path.exists(output_fileName): 268 data = np.load(output_fileName) 269 dshape = data.shape 270 if len(dshape) == 3: 271 if dshape[2] <= 4: 272 data = data[:, :, 0] 273 else: 274 data = data[:, :, 0:5] 275 bandlist = [] 276 RasterHelper.saveToHdr_no_transform(data, out_file_no_extension, bandlist, output_format) 277 os.remove(output_fileName) 278 279 if output_format not in ("npy", "NPY") and os.path.exists(distFile + ".npy"): 280 data = np.load(distFile + ".npy") 281 282 # converte to brightness temperature 283 if cfg["sensor"]["thermal_radiation"]: 284 bandlist = cfg["sensor"]["bands"].split(",") 285 data = RasterHelper.convertRadiance2BTimage(data, bandlist) 286 287 bandlist = cfg["sensor"]["bands"].split(",") 288 RasterHelper.saveToHdr_no_transform(data, distFile, bandlist, output_format) 289 os.remove(distFile + ".npy") 290 print("INFO: Finished")
class
RuntimeScene:
15class RuntimeScene(object): 16 def __init__(self, simulation): 17 self.__simulation = simulation 18 self.less_runtime_scene = None 19 self.__sim_mode = "devel11" 20 21 # load mitsuba 22 self.__init_mitsuba_path() 23 globals()["mitsuba"] = __import__("mitsuba") 24 reload(mitsuba) 25 26 self.pmgr = mitsuba.core.PluginManager.getInstance() 27 28 # for simulation 29 self.queue = mitsuba.render.RenderQueue() 30 # prepare for simulation 31 self.scheduler = mitsuba.core.Scheduler.getInstance() 32 # Start up the scheduling system with one worker per local core 33 min_cores = min(multiprocessing.cpu_count(), 34 int(self.__simulation.get_scene().get_advanced_params().number_of_cores)) 35 print("INFO: Using number of cores:", min_cores) 36 if not self.scheduler.isRunning(): 37 for i in range(0, min_cores): 38 self.scheduler.registerWorker(mitsuba.core.LocalWorker(i, 'wrk%i' % i)) 39 self.scheduler.start() 40 41 def shutdown_simulator(self): 42 self.queue.join() 43 self.scheduler.stop() 44 45 def __init_mitsuba_path(self): 46 band_num = self.__simulation.get_scene().get_sensor().get_number_of_bands() 47 if not os.path.exists(".less"): 48 os.mkdir(".less") 49 with open(".less/num.cfg", "w") as f: 50 f.write(str(band_num)) 51 with open(".less/range.cfg", "w") as f: 52 f.write("360 830") 53 pyd_dir = "" 54 dll_path = "" 55 currdir = os.path.split(os.path.realpath(__file__))[0] 56 if currdir.startswith(r"E:\03-Coding\lessrt"): 57 self.__sim_mode = "devel" 58 if self.__sim_mode == "devel": 59 lessrt_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) 60 pyd_dir = os.path.join(lessrt_dir, "python", "lesspy", "bin", "rt", "lessrt", "python", "3.10") 61 dll_path = os.path.join(lessrt_dir, "python", "lesspy", "bin", "rt", "lessrt") 62 else: 63 root_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) 64 pyd_dir = os.path.join(root_dir, "bin", "scripts", "Lesspy", "bin", "rt", "lessrt", "python", "3.10") 65 dll_path = os.path.join(root_dir, "bin", "scripts", "Lesspy", "bin", "rt", "lessrt") 66 67 sys.path.append(pyd_dir) 68 os.add_dll_directory(dll_path) 69 # os.environ['PATH'] = dll_path + os.pathsep + os.environ['PATH'] 70 71 def get_xml_dir(self): 72 sim_dir = self.__simulation.get_sim_dir() 73 xml_dir = os.path.join(sim_dir, "Parameters", "_scenefile") 74 return xml_dir 75 76 def load_scene(self, scene_name="main.xml"): 77 xml_dir = self.get_xml_dir() 78 fileResolver = mitsuba.core.Thread.getThread().getFileResolver() 79 logger = mitsuba.core.Thread.getThread().getLogger() 80 # logger.clearAppenders() 81 fileResolver.appendPath(str(xml_dir)) 82 self.less_runtime_scene = mitsuba.render.SceneHandler.loadScene( 83 fileResolver.resolve(os.path.join(xml_dir, scene_name))) 84 self.less_runtime_scene.configure() 85 self.less_runtime_scene.initialize() 86 87 def update_parameters(self): 88 cwd = os.getcwd() 89 sim_dir = sim_dir = self.__simulation.get_sim_dir() 90 os.chdir(sim_dir) 91 interpreter = self.__simulation.get_scene_helper().get_py_interpreter_path() 92 script_lesspy_path = self.__simulation.get_scene_helper().get_script_less_py_path() 93 os.system(interpreter + " " + script_lesspy_path + " -g v1") 94 os.chdir(cwd) 95 96 xml_dir = self.get_xml_dir() 97 fileResolver = mitsuba.core.Thread.getThread().getFileResolver() 98 logger = mitsuba.core.Thread.getThread().getLogger() 99 # logger.clearAppenders() 100 fileResolver.appendPath(str(xml_dir)) 101 tmp_scene = mitsuba.render.SceneHandler.loadScene( 102 fileResolver.resolve(os.path.join(xml_dir, "tmp_main.xml"))) 103 tmp_scene.configure() 104 105 # update sensor 106 new_sensor = tmp_scene.getSensor() 107 self.less_runtime_scene.addSensor(new_sensor) 108 self.less_runtime_scene.setSensor(new_sensor) 109 # directly create sensor from properties is not possible from python because the properties are not complete 110 # new_sensor_props = tmp_scene.getSensor().getProperties() 111 # tmp_sensor = self.pmgr.createObject(new_sensor_props) 112 # tmp_film = self.pmgr.createObject(tmp_scene.getFilm().getProperties()) 113 # tmp_film.configure() 114 # tmp_sensor.addChild(tmp_film) 115 # tmp_sensor.configure() 116 # self.less_runtime_scene.addSensor(tmp_sensor) 117 # self.less_runtime_scene.setSensor(tmp_sensor) 118 # self.less_runtime_scene.setSampler(tmp_scene.getSampler()) 119 120 # update illumination 121 for emitter in self.less_runtime_scene.getEmitters(): 122 self.less_runtime_scene.removeEmitter(emitter) 123 emitters = tmp_scene.getEmitters() 124 for emitter in emitters: 125 self.less_runtime_scene.addChild(emitter) 126 127 # update BSDF 128 # update terrain BRDF 129 landscape = self.__simulation.get_scene().get_landscape() 130 if landscape.get_terrain().get_terr_brdf_type() != TERRAIN_BRDF_TYPE.LAMBERTIAN: 131 print("INFO: Only Lambertian supports runtime modification of scene properties currently, If" 132 "you want to use other BRDF types, plase contact [email protected]") 133 sys.exit(0) 134 terrain_op_name = landscape.get_terrain().get_optical() 135 terrain_ref = landscape.get_op_item(terrain_op_name).get_op_front_reflectance() 136 soil_op_obj = self.__create_terrain_bsdf(terrain_ref) 137 for shape in self.less_runtime_scene.getShapes(): 138 if shape.getID() == "terrain": 139 shape.setBSDF(soil_op_obj) 140 break 141 142 ## update op 143 sgroups = landscape.get_objects() 144 group_names = list(sgroups.keys()) 145 modified_phases = [] 146 for ins_shape in self.less_runtime_scene.getShapes(): 147 if ins_shape.getID() != "terrain": 148 shape_group_id = ins_shape.getShapeGroup().getID() 149 if shape_group_id in group_names: 150 mesh_shapes = ins_shape.getShapeGroup().getKDTree().getShapes() 151 values = list(sgroups[shape_group_id].values()) 152 idx = 0 153 for mesh_shape in mesh_shapes: 154 op_name = values[idx]["op_name"] 155 is_turbid = values[idx]["is_turbid"] 156 lad = values[idx]["lad"] 157 op_item = landscape.get_op_item(op_name) 158 if not is_turbid: 159 mix_bsdf = self.__create_mixture_bsdf(op_item.get_op_front_reflectance(), 160 op_item.get_op_back_reflectance(), 161 op_item.get_op_transmittance()) 162 mesh_shape.addChild(mix_bsdf) 163 else: # turbid medium: modifying phase function and configure medium 164 inter_medium = mesh_shape.getInteriorMedium() 165 leaf_density = values[idx]["leaf_density"] 166 hotspot_factor = values[idx]["hotspot_factor"] 167 optical_lad = op_name + "_" + lad 168 if optical_lad not in modified_phases: # 当前组分所使用的phase function如果没更新,则更新 169 modified_phases.append(optical_lad) 170 phase_function = inter_medium.getPhaseFunction() 171 phase_function.isConfigured = False # reset the configuration to recompute phase values 172 phase_function.frontRef = mitsuba.core.Spectrum(op_item.get_op_front_reflectance()) 173 phase_function.backRef = mitsuba.core.Spectrum(op_item.get_op_back_reflectance()) 174 phase_function.transmittance = mitsuba.core.Spectrum(op_item.get_op_transmittance()) 175 phase_function.opticalName = op_name 176 phase_function.ladType = self.__get_lad_type(lad) 177 phase_function.configure() 178 inter_medium.ladType = self.__get_lad_type(lad) 179 inter_medium.leafAreaDensity = leaf_density 180 inter_medium.hotspotFactor = hotspot_factor 181 inter_medium.configure() 182 idx += 1 183 group_names.remove(shape_group_id) 184 if len(group_names) == 0: 185 break 186 187 def start(self): 188 job = mitsuba.render.RenderJob('Simulating', self.less_runtime_scene, self.queue) 189 job.start() 190 self.queue.waitLeft(0) 191 self.__post_processing() 192 193 def __create_terrain_bsdf(self, reflectance): 194 bsdf = self.__create_object('diffuse', {'reflectance': mitsuba.core.Spectrum(reflectance)}) 195 bsdf.configure() 196 return bsdf 197 198 def __create_object(self, name: str, properties: {}): 199 props = mitsuba.core.Properties(name) 200 for key in properties: 201 props[key] = properties[key] 202 return self.pmgr.createObject(props) 203 204 def __create_mixture_bsdf(self, reflectance_front=0.4, reflectance_back=0.4, transmittance=0.4): 205 mixbsdf = self.__create_object('mixturebsdf', {'ensureEnergyConservation': False, 'weights': '1, 1'}) 206 twosidedbsdf = self.__create_object('twosided', {}) 207 refbsdf = self.__create_object("diffuse", {'reflectance': mitsuba.core.Spectrum(reflectance_front)}) 208 refbsdf.configure() 209 twosidedbsdf.addChild(refbsdf) 210 refbsdf = self.__create_object("diffuse", {'reflectance': mitsuba.core.Spectrum(reflectance_back)}) 211 refbsdf.configure() 212 twosidedbsdf.addChild(refbsdf) 213 twosidedbsdf.configure() 214 transbsdf = self.__create_object('difftrans', {'transmittance': mitsuba.core.Spectrum(transmittance)}) 215 transbsdf.configure() 216 mixbsdf.addChild(twosidedbsdf) 217 mixbsdf.addChild(transbsdf) 218 mixbsdf.configure() 219 return mixbsdf 220 221 def __get_lad_type(self, lad_str): 222 if lad_str == "Spherical": 223 return mitsuba.render.PhaseFunction.ESpherical 224 if lad_str == "Uniform": 225 return mitsuba.render.PhaseFunction.EUniform 226 if lad_str == "Planophile": 227 return mitsuba.render.PhaseFunction.EPlanophile 228 if lad_str == "Erectophile": 229 return mitsuba.render.PhaseFunction.EErectophile 230 if lad_str == "Plagiophile": 231 return mitsuba.render.PhaseFunction.EPlagiophile 232 if lad_str == "Extremophile": 233 return mitsuba.render.PhaseFunction.EExtremophile 234 return mitsuba.render.ELadType.EINVALIDE 235 236 def __post_processing(self): 237 sim_dir = self.__simulation.get_sim_dir() 238 distFile = self.__simulation.get_dist_file() 239 infofile = os.path.join(sim_dir, "Results", "spectral.txt") 240 f = open(infofile, 'w') 241 f.write(os.path.basename(distFile)) 242 f.close() 243 244 cfgfile = os.path.join(sim_dir, "Parameters", "input.conf") 245 f = open(cfgfile, 'r') 246 cfg = json.load(f) 247 248 output_format = "ENVI" 249 if cfg["sensor"]["sensor_type"] == "PhotonTracing": 250 out_file_no_extension = distFile + "_downwelling" 251 output_fileName = distFile + "_downwelling.npy" 252 if output_format not in ("npy", "NPY") and os.path.exists(output_fileName): 253 data = np.load(output_fileName) 254 bandlist = cfg["sensor"]["bands"].split(",") 255 RasterHelper.saveToHdr_no_transform(data, out_file_no_extension, bandlist, output_format) 256 os.remove(output_fileName) 257 out_file_no_extension = distFile + "_upwelling" 258 output_fileName = distFile + "_upwelling.npy" 259 if output_format not in ("npy", "NPY") and os.path.exists(output_fileName): 260 data = np.load(output_fileName) 261 bandlist = cfg["sensor"]["bands"].split(",") 262 RasterHelper.saveToHdr_no_transform(data, out_file_no_extension, bandlist, output_format) 263 os.remove(output_fileName) 264 else: 265 out_file_no_extension = distFile + "_4Components" 266 output_fileName = distFile + "_4Components.npy" 267 268 if output_format not in ("npy", "NPY") and os.path.exists(output_fileName): 269 data = np.load(output_fileName) 270 dshape = data.shape 271 if len(dshape) == 3: 272 if dshape[2] <= 4: 273 data = data[:, :, 0] 274 else: 275 data = data[:, :, 0:5] 276 bandlist = [] 277 RasterHelper.saveToHdr_no_transform(data, out_file_no_extension, bandlist, output_format) 278 os.remove(output_fileName) 279 280 if output_format not in ("npy", "NPY") and os.path.exists(distFile + ".npy"): 281 data = np.load(distFile + ".npy") 282 283 # converte to brightness temperature 284 if cfg["sensor"]["thermal_radiation"]: 285 bandlist = cfg["sensor"]["bands"].split(",") 286 data = RasterHelper.convertRadiance2BTimage(data, bandlist) 287 288 bandlist = cfg["sensor"]["bands"].split(",") 289 RasterHelper.saveToHdr_no_transform(data, distFile, bandlist, output_format) 290 os.remove(distFile + ".npy") 291 print("INFO: Finished")
RuntimeScene(simulation)
16 def __init__(self, simulation): 17 self.__simulation = simulation 18 self.less_runtime_scene = None 19 self.__sim_mode = "devel11" 20 21 # load mitsuba 22 self.__init_mitsuba_path() 23 globals()["mitsuba"] = __import__("mitsuba") 24 reload(mitsuba) 25 26 self.pmgr = mitsuba.core.PluginManager.getInstance() 27 28 # for simulation 29 self.queue = mitsuba.render.RenderQueue() 30 # prepare for simulation 31 self.scheduler = mitsuba.core.Scheduler.getInstance() 32 # Start up the scheduling system with one worker per local core 33 min_cores = min(multiprocessing.cpu_count(), 34 int(self.__simulation.get_scene().get_advanced_params().number_of_cores)) 35 print("INFO: Using number of cores:", min_cores) 36 if not self.scheduler.isRunning(): 37 for i in range(0, min_cores): 38 self.scheduler.registerWorker(mitsuba.core.LocalWorker(i, 'wrk%i' % i)) 39 self.scheduler.start()
def
load_scene(self, scene_name='main.xml'):
76 def load_scene(self, scene_name="main.xml"): 77 xml_dir = self.get_xml_dir() 78 fileResolver = mitsuba.core.Thread.getThread().getFileResolver() 79 logger = mitsuba.core.Thread.getThread().getLogger() 80 # logger.clearAppenders() 81 fileResolver.appendPath(str(xml_dir)) 82 self.less_runtime_scene = mitsuba.render.SceneHandler.loadScene( 83 fileResolver.resolve(os.path.join(xml_dir, scene_name))) 84 self.less_runtime_scene.configure() 85 self.less_runtime_scene.initialize()
def
update_parameters(self):
87 def update_parameters(self): 88 cwd = os.getcwd() 89 sim_dir = sim_dir = self.__simulation.get_sim_dir() 90 os.chdir(sim_dir) 91 interpreter = self.__simulation.get_scene_helper().get_py_interpreter_path() 92 script_lesspy_path = self.__simulation.get_scene_helper().get_script_less_py_path() 93 os.system(interpreter + " " + script_lesspy_path + " -g v1") 94 os.chdir(cwd) 95 96 xml_dir = self.get_xml_dir() 97 fileResolver = mitsuba.core.Thread.getThread().getFileResolver() 98 logger = mitsuba.core.Thread.getThread().getLogger() 99 # logger.clearAppenders() 100 fileResolver.appendPath(str(xml_dir)) 101 tmp_scene = mitsuba.render.SceneHandler.loadScene( 102 fileResolver.resolve(os.path.join(xml_dir, "tmp_main.xml"))) 103 tmp_scene.configure() 104 105 # update sensor 106 new_sensor = tmp_scene.getSensor() 107 self.less_runtime_scene.addSensor(new_sensor) 108 self.less_runtime_scene.setSensor(new_sensor) 109 # directly create sensor from properties is not possible from python because the properties are not complete 110 # new_sensor_props = tmp_scene.getSensor().getProperties() 111 # tmp_sensor = self.pmgr.createObject(new_sensor_props) 112 # tmp_film = self.pmgr.createObject(tmp_scene.getFilm().getProperties()) 113 # tmp_film.configure() 114 # tmp_sensor.addChild(tmp_film) 115 # tmp_sensor.configure() 116 # self.less_runtime_scene.addSensor(tmp_sensor) 117 # self.less_runtime_scene.setSensor(tmp_sensor) 118 # self.less_runtime_scene.setSampler(tmp_scene.getSampler()) 119 120 # update illumination 121 for emitter in self.less_runtime_scene.getEmitters(): 122 self.less_runtime_scene.removeEmitter(emitter) 123 emitters = tmp_scene.getEmitters() 124 for emitter in emitters: 125 self.less_runtime_scene.addChild(emitter) 126 127 # update BSDF 128 # update terrain BRDF 129 landscape = self.__simulation.get_scene().get_landscape() 130 if landscape.get_terrain().get_terr_brdf_type() != TERRAIN_BRDF_TYPE.LAMBERTIAN: 131 print("INFO: Only Lambertian supports runtime modification of scene properties currently, If" 132 "you want to use other BRDF types, plase contact [email protected]") 133 sys.exit(0) 134 terrain_op_name = landscape.get_terrain().get_optical() 135 terrain_ref = landscape.get_op_item(terrain_op_name).get_op_front_reflectance() 136 soil_op_obj = self.__create_terrain_bsdf(terrain_ref) 137 for shape in self.less_runtime_scene.getShapes(): 138 if shape.getID() == "terrain": 139 shape.setBSDF(soil_op_obj) 140 break 141 142 ## update op 143 sgroups = landscape.get_objects() 144 group_names = list(sgroups.keys()) 145 modified_phases = [] 146 for ins_shape in self.less_runtime_scene.getShapes(): 147 if ins_shape.getID() != "terrain": 148 shape_group_id = ins_shape.getShapeGroup().getID() 149 if shape_group_id in group_names: 150 mesh_shapes = ins_shape.getShapeGroup().getKDTree().getShapes() 151 values = list(sgroups[shape_group_id].values()) 152 idx = 0 153 for mesh_shape in mesh_shapes: 154 op_name = values[idx]["op_name"] 155 is_turbid = values[idx]["is_turbid"] 156 lad = values[idx]["lad"] 157 op_item = landscape.get_op_item(op_name) 158 if not is_turbid: 159 mix_bsdf = self.__create_mixture_bsdf(op_item.get_op_front_reflectance(), 160 op_item.get_op_back_reflectance(), 161 op_item.get_op_transmittance()) 162 mesh_shape.addChild(mix_bsdf) 163 else: # turbid medium: modifying phase function and configure medium 164 inter_medium = mesh_shape.getInteriorMedium() 165 leaf_density = values[idx]["leaf_density"] 166 hotspot_factor = values[idx]["hotspot_factor"] 167 optical_lad = op_name + "_" + lad 168 if optical_lad not in modified_phases: # 当前组分所使用的phase function如果没更新,则更新 169 modified_phases.append(optical_lad) 170 phase_function = inter_medium.getPhaseFunction() 171 phase_function.isConfigured = False # reset the configuration to recompute phase values 172 phase_function.frontRef = mitsuba.core.Spectrum(op_item.get_op_front_reflectance()) 173 phase_function.backRef = mitsuba.core.Spectrum(op_item.get_op_back_reflectance()) 174 phase_function.transmittance = mitsuba.core.Spectrum(op_item.get_op_transmittance()) 175 phase_function.opticalName = op_name 176 phase_function.ladType = self.__get_lad_type(lad) 177 phase_function.configure() 178 inter_medium.ladType = self.__get_lad_type(lad) 179 inter_medium.leafAreaDensity = leaf_density 180 inter_medium.hotspotFactor = hotspot_factor 181 inter_medium.configure() 182 idx += 1 183 group_names.remove(shape_group_id) 184 if len(group_names) == 0: 185 break