def getCameraAltitudeHeight(self, main_scene_xml_file_prifix, pos_x, pos_z): currdir = os.path.split(os.path.realpath(__file__))[0] sys.path.append(currdir + '/bin/rt/' + current_rt_program + '/python/2.7/') os.environ[ 'PATH'] = currdir + '/bin/rt/' + current_rt_program + os.pathsep + os.environ[ 'PATH'] import mitsuba from mitsuba.core import Vector, Point, Ray, Thread from mitsuba.render import SceneHandler import platform scenepath = session.get_scenefile_path() fileResolver = Thread.getThread().getFileResolver() logger = Thread.getThread().getLogger() logger.clearAppenders() scenepath = scenepath.encode('utf-8') fileResolver.appendPath(scenepath) filepath = os.path.join(session.get_scenefile_path(), main_scene_xml_file_prifix + terr_scene_file).encode("utf-8") scene = SceneHandler.loadScene(fileResolver.resolve(filepath)) scene.configure() scene.initialize() ray = Ray() ray.setOrigin(Point(pos_x, 999999999, pos_z)) ray.setDirection(Vector(0, -1, 0)) its = scene.rayIntersect(ray) if not its is None: return its.p[1] else: print("Camera is outside of the scene, do not use relative height") return 0
def redirect_logger(write_function=print, log_level=EInfo, tqdm_progressbar=None): """ Redirect Mitsuba's Logger output to a custom function (so it can be used with e.g. tqdm). Additionally, can be used to control the log level :param write_function: A function like print() or tqdm.write() that is used to write log messages and progess bars :param log_level: The Mitsuba log level (mitsuba.EError, ...) :param tqdm_progressbar: Optionally, pass a tqdm progress bar. The Mitsuba rendering bar will be set as that bar's description :return: """ class RedirectedAppender(Appender): def __init__(self, write_function, tqdm_progressbar): self.write_function = write_function self.tqdm_progressbar = tqdm_progressbar super().__init__() def append(self, log_level, message): self.write_function(message) def logProgress(self, progress, name, formatted, eta): if self.tqdm_progressbar is not None: self.tqdm_progressbar.set_description_str(formatted.replace('\r', ''), refresh=True) else: self.write_function(f"\r{formatted}", end='') logger = Thread.getThread().getLogger() logger.clearAppenders() logger.addAppender(RedirectedAppender(write_function, tqdm_progressbar)) logger.setLogLevel(log_level)
def initializeMitsuba(self): # Start up the scheduling system with one worker per local core self.scheduler = Scheduler.getInstance() for i in range(0, multiprocessing.cpu_count()): self.scheduler.registerWorker(LocalWorker(i, 'wrk%i' % i)) self.scheduler.start() # Create a queue for tracking render jobs self.queue = RenderQueue() # Get a reference to the plugin manager self.pmgr = PluginManager.getInstance() # Process Mitsuba log and progress messages within Python class CustomAppender(Appender): def append(self2, logLevel, message): print(message) def logProgress(self2, progress, name, formatted, eta): # Asynchronously notify the main thread self.renderProgress.emit(progress) logger = Thread.getThread().getLogger() logger.setLogLevel(EWarn) # Display warning & error messages logger.clearAppenders() logger.addAppender(CustomAppender()) def closeEvent(self, e): self.job.cancel() self.queue.join() self.scheduler.stop()
def getScene(self): if (project_dir == "null"): print("No simulation.") return fileResolver = Thread.getThread().getFileResolver() logger = Thread.getThread().getLogger() logger.clearAppenders() scenepath = session.get_scenefile_path_according_to_basedir( project_dir) fileResolver.appendPath(str(scenepath)) main_xml = str(os.path.join(scenepath, main_scene_xml_file)) if not os.path.exists(main_xml): print("Simulation not generated.") return scene = SceneHandler.loadScene(main_xml) scene.configure() scene.initialize() return LessScene(scene, self.XSize, self.YSize)
def __initialize_mitsuba_setting(self): self.plgr = PluginManager.getInstance() self.output_dir = self.scene.output_dir mitsuba_module_path = os.path.dirname(inspect.getfile(MitsubaRenderer)) self.file_resolver = Thread.getThread().getFileResolver() self.file_resolver.appendPath( os.path.join(mitsuba_module_path, "xml_files/")) self.file_resolver.appendPath( os.path.join(mitsuba_module_path, "textures/")) self.file_resolver.appendPath( os.path.join(mitsuba_module_path, "shapes/")) self.mitsuba_scene = Scene()
def getTerrainBoundingAABB(self, main_scene_xml_file_prifix): # get bounding sphere currdir = os.path.split(os.path.realpath(__file__))[0] import platform if platform.system() == "Windows": sys.path.append( os.path.join(currdir, "bin", "rt", current_rt_program, "python", "3.6")) else: sys.path.append( os.path.join(currdir, "bin", "rt", current_rt_program, "python", "3.5")) os.environ['PATH'] = os.path.join( currdir, "bin", "rt", current_rt_program) + os.pathsep + os.environ['PATH'] import mitsuba from mitsuba.core import Vector, Point, Ray, Thread from mitsuba.render import SceneHandler import platform scenepath = session.get_scenefile_path() # if "Windows" in platform.system(): # scenepath = str(scenepath.replace('\\', '\\\\')) # 得到高程信息 通过光线跟踪的方法精确得到高程信息 fileResolver = Thread.getThread().getFileResolver() logger = Thread.getThread().getLogger() logger.clearAppenders() scenepath = scenepath.encode('utf-8') fileResolver.appendPath(scenepath) filepath = os.path.join(session.get_scenefile_path(), main_scene_xml_file_prifix + terr_scene_file).encode("utf-8") scene = SceneHandler.loadScene(fileResolver.resolve(filepath)) scene.configure() scene.initialize() return scene.getKDTree().getAABB()
def do_simulation_multi_spectral_py(): currdir = os.path.split(os.path.realpath(__file__))[0] sys.path.append(currdir + '/bin/rt/' + current_rt_program + '/python/2.7/') os.environ['PATH'] = currdir + '/bin/rt/' + current_rt_program + os.pathsep + os.environ['PATH'] import mitsuba from mitsuba.core import Vector, Point, Ray, Thread, Scheduler, LocalWorker, PluginManager, Transform from mitsuba.render import SceneHandler from mitsuba.render import RenderQueue, RenderJob from mitsuba.render import Scene import multiprocessing scheduler = Scheduler.getInstance() for i in range(0, multiprocessing.cpu_count()): scheduler.registerWorker(LocalWorker(i, 'wrk%i' % i)) scheduler.start() cfgfile = session.get_config_file() f = open(cfgfile, 'r') cfg = json.load(f) distFileName = spectral_img_prefix + "_VZ=" + str(cfg["observation"]["obs_zenith"]) + \ "_VA=" + str(cfg["observation"]["obs_azimuth"]) distFile = os.path.join(session.get_output_dir(), distFileName).encode("utf-8") scene_file_path = os.path.join(session.get_scenefile_path(), main_scene_xml_file).encode("utf-8") scene_path = session.get_scenefile_path().encode("utf-8") fileResolver = Thread.getThread().getFileResolver() fileResolver.appendPath(scene_path) scene = SceneHandler.loadScene(fileResolver.resolve(scene_file_path)) scene.setDestinationFile(distFile) scene.configure() scene.initialize() queue = RenderQueue() sceneResID = scheduler.registerResource(scene) job = RenderJob(('Simulation Job '+distFileName).encode("utf-8"), scene, queue, sceneResID) job.start() queue.waitLeft(0) queue.join() if output_format not in ("npy", "NPY") and os.path.exists(distFile + ".npy"): data = np.load(distFile + ".npy") bandlist = cfg["sensor"]["bands"].split(",") RasterHelper.saveToHdr_no_transform(data, distFile, bandlist, output_format) os.remove(distFile + ".npy") log("INFO: Finished")
def forest_generate_according_tree_pos_file_for3d(config_file_path): import mitsuba from mitsuba.core import Vector, Point, Ray, Thread from mitsuba.render import SceneHandler from mitsuba.render import RenderQueue, RenderJob from mitsuba.render import Scene from mitsuba.render import Intersection f = open(config_file_path, 'r') cfg = json.load(f) tree_pos = combine_file_path(session.get_input_dir(), cfg["scene"]["forest"]["tree_pos_file"]) if cfg["scene"]["forest"]["tree_pos_file"] == "" or ( not os.path.exists(tree_pos)): return # 读取地形数据 计算每个树的高程 if cfg["scene"]["terrain"]["terrain_type"] != "PLANE" and cfg["scene"][ "terrain"]["terrain_type"] == "RASTER": demfile = combine_file_path(session.get_input_dir(), cfg["scene"]["terrain"]["terr_file"]) img_w, img_h, dem_arr = RasterHelper.read_dem_as_array(demfile) dem_arr = dem_arr - dem_arr.min() scenepath = session.get_scenefile_path() if "Windows" in platform.system(): scenepath = str(scenepath.replace('\\', '\\\\')) # 得到高程信息 通过光线跟踪的方法精确得到高程信息 fileResolver = Thread.getThread().getFileResolver() logger = Thread.getThread().getLogger() logger.clearAppenders() fileResolver.appendPath(scenepath) # 由于batch模式不会改变地形几何结构,因此在用地形打点计算树木的高程时,用第一个terrain文件即可,所以加上了_0_ scene = SceneHandler.loadScene( fileResolver.resolve(str(terr_scene_file))) scene.configure() scene.initialize() tf = open(tree_pos) objectPosFile = open( os.path.join(session.get_input_dir(), "object_pos_3dView.txt"), 'w') # 创建一个虚拟根节点,最后再删除 for line in tf: arr = line.replace("\n", "").split(" ") objectName = arr[0] x = float(arr[1]) y = float(arr[2]) xScale = cfg["scene"]["terrain"]["extent_width"] zScale = cfg["scene"]["terrain"]["extent_height"] treeX = 0.5 * xScale - x treeZ = 0.5 * zScale - y if cfg["scene"]["terrain"]["terrain_type"] != "PLANE": ray = Ray() ray.setOrigin(Point(treeX, 9999, treeZ)) ray.setDirection(Vector(0, -1, 0)) its = scene.rayIntersect(ray) if not its is None: linestr = objectName + " " + str(treeX) + " " + str( its.p[1]) + " " + str(treeZ) + "\n" else: # log("warning: precise height not found.") if cfg["scene"]["terrain"]["terrain_type"] == "RASTER": im_r = int((y / float(zScale)) * img_h) im_c = int((x / float(xScale)) * img_w) if im_r >= img_h: im_r = img_h - 1 if im_c >= img_w: im_c = img_w - 1 linestr = objectName + " " + str(treeX) + " " + str( dem_arr[im_r][im_c]) + " " + str(treeZ) + "\n" else: linestr = objectName + " " + str(treeX) + " " + str( 0) + " " + str(treeZ) + "\n" else: linestr = objectName + " " + str(treeX) + " " + str( 0) + " " + str(treeZ) + "\n" objectPosFile.write(linestr) objectPosFile.close()
def forest_generate_according_tree_pos_file(config_file_path, forest_file_name, linestart, lineend, forest_prifix=""): import mitsuba from mitsuba.core import Vector, Point, Ray, Thread from mitsuba.render import SceneHandler from mitsuba.render import RenderQueue, RenderJob from mitsuba.render import Scene from mitsuba.render import Intersection f = open(config_file_path, 'r') cfg = json.load(f) tree_pos = combine_file_path(session.get_input_dir(), cfg["scene"]["forest"]["tree_pos_file"]) if cfg["scene"]["forest"]["tree_pos_file"] == "" or ( not os.path.exists(tree_pos)): return # 保存场景中树的位置 forest*.xml # f = open(os.path.join(session.get_scenefile_path(),forest_file_name),'w') f = codecs.open( os.path.join(session.get_scenefile_path(), forest_file_name), "w", "utf-8-sig") doc = minidom.Document() root = doc.createElement("scene") doc.appendChild(root) root.setAttribute("version", "0.5.0") #读取地形数据 计算每个树的高程 if cfg["scene"]["terrain"]["terrain_type"] != "PLANE" and cfg["scene"][ "terrain"]["terrain_type"] == "RASTER": demfile = combine_file_path(session.get_input_dir(), cfg["scene"]["terrain"]["terr_file"]) img_w, img_h, dem_arr = RasterHelper.read_dem_as_array(demfile) dem_arr = dem_arr - dem_arr.min() #读取object boundingbox 数据 bound_path = os.path.join(session.get_input_dir(), obj_bounding_box_file) if os.path.exists(bound_path): fobj = open(bound_path) bound_dict = dict() for line in fobj: arr = line.split(":") objName = arr[0] arr = list(map(lambda x: float(x), arr[1].split(" "))) bound_dict[objName] = [ arr[3] - arr[0], arr[4] - arr[1], arr[5] - arr[2] ] scenepath = session.get_scenefile_path() # if "Windows" in platform.system(): # scenepath = str(scenepath.replace('\\', '\\\\')) #得到高程信息 通过光线跟踪的方法精确得到高程信息 fileResolver = Thread.getThread().getFileResolver() logger = Thread.getThread().getLogger() logger.clearAppenders() fileResolver.appendPath(str(scenepath)) # 由于batch模式不会改变地形几何结构,因此在用地形打点计算树木的高程时,用第一个terrain文件即可,所以加上了_0_ # if(forest_prifix != ""): # forest_prifix = forest_prifix[0:len(forest_prifix)-1] +"_0_" scene = SceneHandler.loadScene( fileResolver.resolve(str(forest_prifix + terr_scene_file))) # scene = SceneHandler.loadScene(fileResolver.resolve(r"E:\Research\20-LESS\RealScene\SimProj\calLAI\Parameters\_scenefile\terrain1.xml")) scene.configure() scene.initialize() tf = open(tree_pos) hidden_objects = SceneGenerate.get_hidded_objects() #创建一个虚拟根节点,最后再删除 treeIdx = 0 for line in tf: if treeIdx >= linestart and treeIdx <= lineend: arr = line.replace("\n", "").strip().split(" ") objectName = arr[0] if objectName in hidden_objects: continue shapenode = doc.createElement("shape") root.appendChild(shapenode) shapenode.setAttribute("type", "instance") refnode = doc.createElement("ref") shapenode.appendChild(refnode) refnode.setAttribute("id", objectName) trnode = doc.createElement("transform") shapenode.appendChild(trnode) trnode.setAttribute("name", "toWorld") if len(arr) == 6: # fit with scale_node = doc.createElement("scale") trnode.appendChild(scale_node) scale_node.setAttribute( "x", str(float(arr[4]) / bound_dict[objectName][0])) scale_node.setAttribute( "z", str(float(arr[4]) / bound_dict[objectName][0])) scale_node.setAttribute( "y", str(float(arr[5]) / bound_dict[objectName][1])) if len(arr) == 5: # for rotation of the tree angle = arr[len(arr) - 1] rotatenode = doc.createElement("rotate") trnode.appendChild(rotatenode) rotatenode.setAttribute("y", '1') rotatenode.setAttribute("angle", angle) translatenode = doc.createElement("translate") trnode.appendChild(translatenode) x = float(arr[1]) y = float(arr[2]) z = float(arr[3]) xScale = cfg["scene"]["terrain"]["extent_width"] zScale = cfg["scene"]["terrain"]["extent_height"] # treeX = xScale - x * (2 * xScale) / float(img_w) # treeZ = zScale - y * (2 * zScale) / float(img_h) treeX = 0.5 * xScale - x treeZ = 0.5 * zScale - y translatenode.setAttribute("x", str(treeX)) translatenode.setAttribute("z", str(treeZ)) if cfg["scene"]["terrain"]["terrain_type"] != "PLANE": ray = Ray() ray.setOrigin(Point(treeX, 9999, treeZ)) ray.setDirection(Vector(0, -1, 0)) its = scene.rayIntersect(ray) if not its is None: translatenode.setAttribute("y", str(its.p[1] + z)) # translatenode.setAttribute("y", str(z)) else: # log("warning: precise height not found.") if cfg["scene"]["terrain"]["terrain_type"] == "RASTER": im_r = int((y / float(zScale)) * img_h) im_c = int((x / float(xScale)) * img_w) if im_r >= img_h: im_r = img_h - 1 if im_c >= img_w: im_c = img_w - 1 translatenode.setAttribute( "y", str(dem_arr[im_r][im_c] + z)) else: translatenode.setAttribute("y", str(z)) else: translatenode.setAttribute("y", str(z)) treeIdx += 1 xm = doc.toprettyxml() # xm = xm.replace('<?xml version="1.0" ?>', '') f.write(xm) f.close() log("INFO: Objects and positions generated.")
def do_simulation_multiangle_seq(seqname): currdir = os.path.split(os.path.realpath(__file__))[0] sys.path.append(currdir + '/bin/rt/' + current_rt_program + '/python/2.7/') os.environ['PATH'] = currdir + '/bin/rt/' + current_rt_program + os.pathsep + os.environ['PATH'] import mitsuba from mitsuba.core import Vector, Point, Ray, Thread, Scheduler, LocalWorker, PluginManager, Transform from mitsuba.render import SceneHandler from mitsuba.render import RenderQueue, RenderJob from mitsuba.render import Scene import multiprocessing scheduler = Scheduler.getInstance() for i in range(0, multiprocessing.cpu_count()): scheduler.registerWorker(LocalWorker(i, 'wrk%i' % i)) scheduler.start() scene_path = session.get_scenefile_path() fileResolver = Thread.getThread().getFileResolver() fileResolver.appendPath(str(scene_path)) scene = SceneHandler.loadScene(fileResolver.resolve( str(os.path.join(session.get_scenefile_path(), main_scene_xml_file)))) scene.configure() scene.initialize() queue = RenderQueue() sceneResID = scheduler.registerResource(scene) bsphere = scene.getKDTree().getAABB().getBSphere() radius = bsphere.radius targetx, targety, targetz = bsphere.center[0], bsphere.center[1], bsphere.center[2] f = open(seqname + ".conf", 'r') params = json.load(f) obs_azimuth = params['seq1']['obs_azimuth'] obs_zenith = params['seq2']['obs_zenith'] cfgfile = session.get_config_file() f = open(cfgfile, 'r') cfg = json.load(f) viewR = cfg["sensor"]["obs_R"] mode = cfg["sensor"]["film_type"] azi_arr = map(lambda x: float(x), obs_azimuth.strip().split(":")[1].split(",")) zeni_arr = map(lambda x: float(x), obs_zenith.strip().split(":")[1].split(",")) seq_header = multi_file_prefix + "_" + seqname index = 0 for azi in azi_arr: for zeni in zeni_arr: distFile = os.path.join(session.get_output_dir(), seq_header + ("_VA_%.2f" % azi).replace(".", "_") + ("_VZ_%.2f" % zeni).replace(".", "_")) newScene = Scene(scene) pmgr = PluginManager.getInstance() newSensor = pmgr.createObject(scene.getSensor().getProperties()) theta = zeni / 180.0 * math.pi phi = (azi - 90) / 180.0 * math.pi scale_x = radius scale_z = radius toWorld = Transform.lookAt( Point(targetx - viewR * math.sin(theta) * math.cos(phi), targety + viewR * math.cos(theta), targetz - viewR * math.sin(theta) * math.sin(phi)), # original Point(targetx, targety, targetz), # target Vector(0, 0, 1) # up ) * Transform.scale( Vector(scale_x, scale_z, 1) # 视场大小 ) newSensor.setWorldTransform(toWorld) newFilm = pmgr.createObject(scene.getFilm().getProperties()) newFilm.configure() newSensor.addChild(newFilm) newSensor.configure() newScene.addSensor(newSensor) newScene.setSensor(newSensor) newScene.setSampler(scene.getSampler()) newScene.setDestinationFile(str(distFile)) job = RenderJob('Simulation Job' + "VA_"+str(azi)+"_VZ_"+str(zeni), newScene, queue, sceneResID) job.start() queue.waitLeft(0) queue.join() # handle npy if mode == "spectrum" and (output_format not in ("npy", "NPY")): for azi in azi_arr: for zeni in zeni_arr: distFile = os.path.join(session.get_output_dir(), seq_header + ("_VA_%.2f" % azi).replace(".", "_") + ("_VZ_%.2f" % zeni).replace( ".", "_")) data = np.load(distFile + ".npy") bandlist = cfg["sensor"]["bands"].split(",") RasterHelper.saveToHdr_no_transform(data, distFile, bandlist, output_format) os.remove(distFile + ".npy")
if sys.platform == 'linux': sys.setdlopenflags(oldflags) from mitsuba.core import ( Scheduler, LocalWorker, Thread, Bitmap, Point2i, Vector2i, FileStream, PluginManager, Spectrum, InterpolatedSpectrum, BlackBodySpectrum, Vector, Point, Matrix4x4, Transform, AnimatedTransform, Appender, EInfo, EWarn, EError, ) from mitsuba.render import ( RenderQueue, RenderJob, RenderListener, Scene, SceneHandler, TriMesh ) import multiprocessing main_thread = Thread.getThread() main_fresolver = main_thread.getFileResolver() main_logger = main_thread.getLogger() class CustomAppender(Appender): def append(self, logLevel, message): MtsLog(message) def logProgress(self, progress, name, formatted, eta): render_engine = MtsManager.RenderEngine if not render_engine.is_preview: percent = progress / 100 render_engine.update_progress(percent) render_engine.update_stats('', 'Progress: %s - ETA: %s' % ('{:.2%}'.format(percent), eta))
Vector, Point, Matrix4x4, Transform, AnimatedTransform, Appender, EInfo, EWarn, EError, ) from mitsuba.render import (RenderQueue, RenderJob, RenderListener, Scene, SceneHandler, TriMesh) import multiprocessing main_thread = Thread.getThread() main_fresolver = main_thread.getFileResolver() main_logger = main_thread.getLogger() class CustomAppender(Appender): def append(self, logLevel, message): MtsLog(message) def logProgress(self, progress, name, formatted, eta): render_engine = MtsManager.RenderEngine if not render_engine.is_preview: percent = progress / 100 render_engine.update_progress(percent) render_engine.update_stats( '', 'Progress: %s - ETA: %s' %