3dmax批量导入obj_LESS Python SDK实现批量化三维辐射传输模拟

      三维辐射传输模型往往有复杂的输入参数,因此一般的模型都有相应的GUI软件,虽然GUI方便学习和使用,但是难以进行批处理以及嵌入其他程序中。在LESS中,已经提供了一个基于GUI的批处理工具,目前可以对场景中的观测参数、太阳参数以及光谱参数等进行批量修改和模拟,但是仍然无法批量地修改场景中的三维元素,例如树的结构或者树的位置,而批量修改三维结构在一些应用中也是非常常见的需求。

      经过与不少用户的交流,也花了不少时间,为了实现更方便的批量模拟,于是开发了这样一套基于Python的SDK接口pyLessSDK, 可以实现场景中任意元素的修改,进而实现批处理。同时,通过Python调用的形式,整个模拟过程无需打开GUI程序,更方便将模拟过程与其他处理过程进行整合。

     pyLessSDK经过一段时间的调试,以及一些用户的测试,已经逐步趋于稳定(虽然bug是难以避免的),更详细的说明和使用文档可以参考LESS的用户手册(点原文链接)。

LESS Python SDK主要功能

该SDK的主要类图如下:

3dmax批量导入obj_LESS Python SDK实现批量化三维辐射传输模拟_第1张图片

  • 基本模拟过程

  以下代码展示了利用python创建一个默认模拟工程,并直接进行模拟的示例。首先导入SimulationHelper和Simulation两个类,前者是模拟工程的辅助类,后者代表整个模拟工程。Simulation包含一个SimulatinHelper和一个Scene成员变量。SimulatinHelper主要提供创建新的模拟工程以及获取一些系统参数(例如python的路径等)等功能,例如create_new_sim函数根据一个输入的目录路径创建一个新的模拟工程,并用标准模板初始化该工程(设定默认参数等),如果模拟工程已经存在,则跳过。Simulation实例从一个模拟工程路径和一个SimulatinHelper实例构造而来,得到Simulation实例后(即sim),需要通过read_sim_project函数读取模拟工程的参数到sim对象中,然后可以调用save_sim_project()函数保存工程(此处没有修改参数,也可以不保存),最终调用start()函数执行模拟。

# coding: utf-8from SimulationHelper import SimulationHelperfrom Simulation import Simulationfrom PostProcessing import PostProcessingimport ossim_dir = r"D:\LESS\simulations\Ex01"sim_helper = SimulationHelper(r"D:\LESS")  # 创建SimulationHelper,参数为LESS的安装根目录sim_helper.create_new_sim(sim_dir)  # 新建模拟工程sim = Simulation(sim_dir, sim_helper)  # 初始化Simulation对象sim.read_sim_project()  # 读取模拟工程的内容sim.save_sim_project()  # 保存工程sim.start()  # 开始模拟

  以上代码是一个最简单的模拟过程,无需打开GUI程序即可实现。最终的模拟结果是一副图像(spectral_VZ=0_VA=180),保存的位置为D:\LESS\simulations\Ex01\Results\,默认保存为ENVI格式,像素值的类型为辐亮度(Radiance)。

3dmax批量导入obj_LESS Python SDK实现批量化三维辐射传输模拟_第2张图片

  为了将辐亮度转为反射率,可以使用PostProcessing中的radiance2brf函数,该函数具有三个参数,第一个为模拟工程的路径,用以获取辐照度等信息;第二个为输入文件路径,即辐亮度文件,也是上一步中模拟得到的文件;第三个为输出文件路径,即BRF文件。模拟结束后得到下图所示BRF文件。(代码中的高亮加粗代码为新增代码)

# coding: utf-8from SimulationHelper import SimulationHelperfrom Simulation import Simulationfrom PostProcessing import PostProcessingimport ossim_dir = r"D:\LESS\simulations\Ex01"sim_helper = SimulationHelper(r"D:\LESS")  # 创建SimulationHelper,参数为LESS的安装根目录sim_helper.create_new_sim(sim_dir)  # 新建模拟工程sim = Simulation(sim_dir, sim_helper)  # 初始化Simulation对象sim.read_sim_project()  # 读取模拟工程的内容# 模拟的输出文件sim.save_sim_project()  # 保存工程sim.start()  # 开始模拟PostProcessing.radiance2brf(sim.get_sim_dir(), sim.get_dist_file(), sim.get_dist_file()+"_BRF")

3dmax批量导入obj_LESS Python SDK实现批量化三维辐射传输模拟_第3张图片

  上述代码使用的是默认的输出文件名spectral_VZ=0_VA=180(通过函数sim.get_dist_file得到),实际上,为了方便使用,我们在模拟时,可以设定自己的输出文件名,在read_sim_project和save_sim_project之间通过修改参数实现,代码如下:

sim.read_sim_project()  # 读取模拟工程的内容sim.set_dist_file(os.path.join(sim.get_sim_dir(), "Results", "output_radiance_file"))# 模拟的输出文件sim.save_sim_project()  # 保存工程

在Ex01中,虽然我们实现了整个模拟流程,但是默认场景中只包含了一个简单100m*100m的平地。本例中,我们将在场景中添加一些树木,并设定其光谱。

  • 导入场景OBJ文件

    在LESS中,目前所有的场景元素(树木、房子等)均以三角面片的OBJ格式文件作为输入,树模型等可以通过第三方软件如OnyxTree等生成。

所有的场景元素均在类Scene中进行管理,当创建一个Simulation后,可以通过sim.get_scene()得到Scene的实例,进而访问或者修改场景中的元素。示例代码如下:

# coding: utf-8from SimulationHelper import SimulationHelperfrom Simulation import Simulationfrom PostProcessing import PostProcessingimport osfrom SceneObjects import SceneObjectfrom Utility import OBJHelperimport randomsim_dir = r"D:\LESS\simulations\Ex02"sim_helper = SimulationHelper(r"D:\LESS")  # 创建SimulationHelper,参数为LESS的安装根目录sim_helper.create_new_sim(sim_dir)  # 新建模拟工程sim = Simulation(sim_dir, sim_helper)  # 初始化Simulation对象sim.read_sim_project()  # 读取模拟工程的内容sim.set_dist_file(os.path.join(sim.get_sim_dir(), "Results", "output_radiance_file"))#################添加场景元素 start ####################scene = sim.get_scene()  # 得到Scenelandscape = scene.get_landscape()  # 得到LandScape对象landscape.clear_landscape_elements()  # # 清除工程已有的场景元素(重复运行程序时,必须执行)obj_tree01 = SceneObject("Tree01")  # 定义一个场景物体,名叫Tree01# 添加一个obj文件作为tree1的一个组分,对于包含多个group的obj文件,首先需要拆分并获取每个组的路径,再分别导入,每个group设置不同的光学属性comp_list = OBJHelper.seperate_obj(r"D:\LESS\app\Database\3D_Objects\Trees\RAMI\FREX_FROM_HET09_JBS_SUM.obj")# FREX_FROM_HET09_JBS_SUM.obj包含两个组分,第一个为leaves,第二个为branch,因此分别导入。# birch_leaf_green 和 birch_branch为默认已定义的内置光学属性,自定义光学属性将在下一个案例讲解obj_tree01.add_component_from_file(comp_list[0], "birch_leaf_green")obj_tree01.add_component_from_file(comp_list[1], "birch_branch")landscape.add_object(obj_tree01)# 当定义好一个obj文件时,还需要将其放置在不同的位置,在LESS中称之为instance# 随机放置在场景中,场景默认大小为100m*100mfor i in range(1000):    x = random.random()*100    y = random.random()*100    landscape.place_object("Tree01", x=x, y=y)############### 添加场景元素 end ############### 模拟的输出文件sim.save_sim_project()  # 保存工程sim.start()  # 开始模拟PostProcessing.radiance2brf(sim.get_sim_dir(), sim.get_dist_file(), sim.get_dist_file()+"_BRF")

3dmax批量导入obj_LESS Python SDK实现批量化三维辐射传输模拟_第4张图片

以上是一个简单的使用示例,更详细的说明请参考LESS用户手册。

你可能感兴趣的:(3dmax批量导入obj)