SDKCodeGenerator

  1# coding: utf-8
  2from SimulationHelper import SimulationHelper
  3from Simulation import Simulation
  4from Terrain import TERRAIN_TYPE, TERRAIN_BRDF_TYPE
  5from Sensor import *
  6import argparse
  7import os
  8
  9
 10def get_less_install_path():
 11    p = os.path.realpath(__file__)
 12    p = os.path.dirname(p)
 13    p = os.path.dirname(p)
 14    p = os.path.dirname(p)
 15    p = os.path.dirname(p)
 16    return p
 17
 18
 19class SDKCodeGenerator(object):
 20    def __init__(self, sim_dir):
 21        self.sim_dir = sim_dir
 22
 23    def generate(self, out_script_path):
 24        fs = open(out_script_path, 'w', encoding='utf-8')
 25        sim_helper = SimulationHelper(get_less_install_path())  # 创建SimulationHelper,参数为LESS的安装根目录
 26        sim_helper.create_new_sim(self.sim_dir)  # 新建模拟工程
 27        sim = Simulation(self.sim_dir, sim_helper)  # 初始化Simulation对象
 28        sim.read_sim_project()  # 读取模拟工程的内容
 29        scene = sim.get_scene()  # 得到Scene
 30        landscape = scene.get_landscape()  # 得到LandScape对象
 31
 32        fs.write("""# coding: utf-8
 33# This script is automatically generated from the GUI
 34# It can generate the same simulation project with the GUI one you created
 35# You can customize this script for usages such as batch processing
 36# The generated code may not cover all functionalities from GUI, please refer to the API for more details.
 37import sys
 38sys.path.append(r"{}")
 39from SimulationHelper import SimulationHelper
 40from Simulation import Simulation
 41from Terrain import TERRAIN_TYPE, TERRAIN_BRDF_TYPE
 42from OpticalProperty import OpticalItem
 43from SceneObjects import SceneObject
 44from Sensor import *
 45from Observation import *
 46from LiDAR import ALSLiDAR, TLSLiDAR, LiDARSimMode, MonoPulseLiDAR
 47from Illumination import Illumination
 48import os
 49
 50sim_helper = SimulationHelper(r"{}")  # Create SimulationHelper, the parameters is the path to LESS installation folder
 51sim_helper.create_new_sim(r"{}")  # Create a new simulation, if already exists, it skips
 52sim = Simulation(r"{}", sim_helper)  # Initialize a Simulation
 53sim.read_sim_project()  # Read the content of the simulation
 54scene = sim.get_scene()  # Read the scene
 55landscape = scene.get_landscape()  # Get the Landscape
 56# If you want to keep scene structures unchanged, you should comment out the following line
 57landscape.clear_landscape_elements()  # Clear existing objects and instances(must be run when you want change scene structures)
 58landscape.clear_user_defined_optical_properties()  # Clear optical properties defined by users
 59        """.format(os.path.dirname(os.path.realpath(__file__)), get_less_install_path(), self.sim_dir, self.sim_dir))
 60
 61        fs.write("\n# Optical properties")
 62        for op_item in landscape.get_all_op_items():
 63            if op_item.get_op_name() not in ["birch_branch", "dark_soil_mollisol", "birch_leaf_green"]:
 64                fs.write(
 65                    """\nop_item = OpticalItem("{}", "{}", {}, {})""".format(op_item.get_op_name(), op_item.get_op_value(), op_item.get_op_type(), op_item.get_op_model_params()))
 66                fs.write("""\nlandscape.add_op_item(op_item)  # Add optical properties""")
 67
 68        fs.write("\n\n# Objects")
 69        fs.write("\n# If yo do not intend to change scene structures, you should comment out this section to "
 70                 "avoid importing objs for each simulation,")
 71        fs.write("\n# and you should also comment out landscape.clear_landscape_elements()")
 72        objects = landscape.get_objects()
 73        for obj in objects:
 74            fs.write("""\nobj = SceneObject(r"{}")  # Define an object""".format(obj))
 75            for comp in objects[obj]:
 76                comp_path = os.path.join(sim.get_parameters_dir(), comp)
 77                if not objects[obj][comp]["is_turbid"]:
 78                    fs.write("""\nobj.add_component_from_file(r"{}", "{}")""".format(comp_path,
 79                                                                                     objects[obj][comp]["op_name"]))
 80                else:
 81                    fs.write(
 82                        """\nobj.add_component_from_file(r"{}", "{}", temperature="{}", color="{}",
 83                                is_turbid={}, leaf_density={}, lad="{}", hotspot_factor={})""".format(comp_path,
 84                                                                                                      objects[obj][
 85                                                                                                          comp][
 86                                                                                                          "op_name"],
 87                                                                                                      objects[obj][comp]["temperature"],
 88                                                                                                      objects[obj][comp]["color"],
 89                                                                                                      objects[obj][comp][ "is_turbid"],
 90                                                                                                      str(objects[obj][comp]["leaf_density"]),
 91                                                                                                      objects[obj][comp]["lad"],
 92                                                                                                      str(objects[obj][ comp][ "hotspot_factor"])))
 93            fs.write("""\nlandscape.add_object(obj)""")
 94
 95        fs.write("\n\n# Instances")
 96        fs.write("\n# If you do not intend to change scene structures, you should comment out this section,")
 97        fs.write("\n# and you should also comment out landscape.clear_landscape_elements()")
 98        fs.write("""\n# You can read the positions from a file and using a loop to place objects, [X Y Z Rotation]""")
 99        instances = landscape.get_instances()
100        for obj_instance in instances:
101            fs.write("""\n{}_positions = {}""".format(obj_instance, instances[obj_instance]))
102            fs.write("""\nfor pos in {}_positions:
103    if len(pos) == 4:
104        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3])
105    elif len(pos) == 7:
106        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3], rotate_axis_x=pos[4], rotate_axis_y=pos[5], rotate_axis_z=pos[6])
107    elif len(pos) == 10:
108        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3], rotate_axis_x=pos[4], rotate_axis_y=pos[5], rotate_axis_z=pos[6], scale_extent_x=pos[7], scale_extent_y=pos[8], scale_extent_z=pos[9])
109        """.format(obj_instance, obj_instance, obj_instance, obj_instance))
110
111        fs.write("\n\n# Terrain")
112        fs.write("\n# If you use default optical ,e.g., dark_soil_mollisol, and if you change the number of spectral ")
113        fs.write("\n# bands, please define your own optical properties, otherwise, there will be band number issues. ")
114        fs.write("\n# The three default optical properties have two bands only in the PyLessSDK. ")
115        terrain = landscape.get_terrain()
116        fs.write("""\nterrain = landscape.get_terrain()""")
117        fs.write("""\nterrain.set_extent_width({})""".format(terrain.get_extent_width()))
118        fs.write("""\nterrain.set_extent_height({})""".format(terrain.get_extent_height()))
119        fs.write("""\nterrain.set_terrain_type(TERRAIN_TYPE.{})""".format(terrain.terrain_type))
120        if terrain.terrain_type == TERRAIN_TYPE.MESH or terrain.terrain_type == TERRAIN_TYPE.RASTER:
121            fs.write("""\nterrain.set_terrain_file(r"{}")""".format(
122                os.path.join(sim.get_parameters_dir(), terrain.terr_file)))
123        brdf_type = terrain.get_terr_brdf_type()
124        fs.write("""\nterrain.set_terr_brdf_type(TERRAIN_BRDF_TYPE.{})""".format(
125            terrain.get_terr_brdf_type().upper().replace(" ", "_")))
126        if brdf_type == TERRAIN_BRDF_TYPE.LAMBERTIAN:
127            fs.write("""\nterrain.set_optical(r"{}")""".format(terrain.get_optical()))
128        elif brdf_type == TERRAIN_BRDF_TYPE.SOILSPECT:
129            fs.write("""\nterrain.soilSpectParams = {}""".format(terrain.soilSpectParams))
130        elif brdf_type == TERRAIN_BRDF_TYPE.ART:
131            fs.write("""\nterrain.artParams = {}""".format(terrain.artParams))
132        elif brdf_type == TERRAIN_BRDF_TYPE.RPV:
133            fs.write("""\nterrain.rpvParams = {}""".format(terrain.rpvParams))
134        elif brdf_type == TERRAIN_BRDF_TYPE.LAND_ALBEDO_MAP:
135            fs.write("""\nterrain.set_landalbedo_file(r"{}")""".format(
136                os.path.join(sim.get_parameters_dir(), terrain.get_landalbedo_file())))
137        fs.write("""\n# If you want to open the simulation with GUI, please uncomment this following line""")
138        fs.write("""\n# sim.prepare_for_ui()""")
139
140        fs.write("\n\n# Illumination")
141        illu = scene.get_illumination()
142        fs.write("""\nillu = Illumination()""")
143        fs.write("""\nillu.set_ats_percentage("{}")""".format(illu.get_ats_percentage()))
144        fs.write("""\nillu.set_sun_zenith({})""".format(illu.sun_zenith))
145        fs.write("""\nillu.set_sun_azimuth({})""".format(illu.sun_azimuth))
146        fs.write("""\nscene.set_illumination(illu)""")
147
148        fs.write("\n\n# Sensor")
149        fs.write("\n# !Note that scene.set_sensor(sensor) should be executed after sensor setup is complete!")
150        sensor = scene.get_sensor()
151        obs = scene.get_observation()
152        vp_obj = sensor.get_virtualPlane()
153        virtual_plane_str = "" if vp_obj is None else \
154            "sensor.enable_virtual_plane(True, center=(%s, %s), size=(%s, %s))" % (vp_obj["vx"], vp_obj["vy"],
155                                                                                  vp_obj["sizex"], vp_obj["sizey"])
156        if sensor.sensor_type == SensorType.ORTHOGRAPHIC:
157            param = """\nsensor = SensorOrthographic()
158sensor.set_film_type("{}")
159sensor.set_spectral_bands("{}")
160sensor.set_image_width({})
161sensor.set_image_height({})
162sensor.set_sample_per_pixel({})
163sensor.has_four_components_product = {}
164sensor.has_Fluor_Product = {}
165sensor.set_sub_region_width({})
166sensor.set_sub_region_height({})
167sensor.cover_whole_scene = {}
168sensor.set_repetitive_scene({})
169{}
170scene.set_sensor(sensor)
171obs = ObservationOrthographic()
172obs.set_obs_zenith({})
173obs.set_obs_azimuth({})
174obs.is_orthophoto_map = {}
175obs.orthophoto_relative_height = {}
176scene.set_observation(obs)
177            """.format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
178                       sensor.get_image_height(), sensor.get_sample_per_pixel(), sensor.has_four_components_product, sensor.has_Fluor_Product,
179                       sensor.sub_region_width, sensor.sub_region_height, sensor.cover_whole_scene,
180                       sensor.get_repetitive_scene(),virtual_plane_str, obs.obs_zenith, obs.obs_azimuth, obs.is_orthophoto_map,
181                       obs.orthophoto_relative_height)
182            fs.write(param)
183        elif sensor.sensor_type == SensorType.PERSPECTIVE:
184            param = """\nsensor = SensorPerspective()
185sensor.set_film_type("{}") 
186sensor.set_spectral_bands("{}") 
187sensor.set_image_width({})
188sensor.set_image_height({})
189sensor.set_fov_x({})  
190sensor.set_fov_y({})
191sensor.set_sample_per_pixel({})
192sensor.set_repetitive_scene({})
193sensor.has_Fluor_Product = {}
194{}
195scene.set_sensor(sensor)
196obs = ObservationPerspective()
197obs.set_origin(({}, {}, {}))
198obs.set_target(({}, {}, {}))
199scene.set_observation(obs)
200""".format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
201           sensor.get_image_height(), sensor.get_fov_x(), sensor.get_fov_y(),
202           sensor.get_sample_per_pixel(), sensor.get_repetitive_scene(), sensor.has_Fluor_Product, virtual_plane_str, obs.obs_o_x,
203           obs.obs_o_y, obs.obs_o_z, obs.obs_t_x, obs.obs_t_y, obs.obs_t_z)
204            fs.write(param)
205        elif sensor.sensor_type == SensorType.PHOTONTRACING:
206            param = """\nsensor = SensorPhotonTracing()
207sensor.set_spectral_bands("{}")
208sensor.enable_brf_product({})
209sensor.enable_Fluor_product({})
210sensor.set_sun_ray_resolution({})
211sensor.set_virtual_directions("{}")
212sensor.enable_fpar_product({})
213sensor.set_fpar_layer("{}")
214{}
215scene.set_sensor(sensor)
216obs = ObservationPhotonTracing()
217scene.set_observation(obs)""".format(sensor.get_spectral_bands(), sensor.BRF_product, sensor.Fluor_product, sensor.get_run_ray_resolution(),
218                                     sensor.get_virtual_directions(), sensor.fPAR_product, sensor.get_fpar_layer(),
219                                     virtual_plane_str)
220            fs.write(param)
221        elif sensor.sensor_type == SensorType.CIRCULARFISHEYE:
222            param = """\nsensor = SensorFisheye()
223sensor.set_film_type("{}")
224sensor.set_spectral_bands("{}")
225sensor.set_image_width({})
226sensor.set_image_height({})
227sensor.set_angular_fov({})
228sensor.set_projection_type("{}")
229sensor.set_sample_per_pixel({})
230sensor.set_repetitive_scene({})
231sensor.has_Fluor_Product = {}
232scene.set_sensor(sensor)
233obs = ObservationFisheye()
234obs.set_origin(({}, {}, {}))
235obs.set_target(({}, {}, {}))
236scene.set_observation(obs)""".format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
237                                     sensor.get_image_height(), sensor.get_angular_fov(), sensor.get_projection_type(),
238                                     sensor.get_sample_per_pixel(), sensor.get_repetitive_scene(), sensor.has_Fluor_Product, obs.obs_o_x,
239                                     obs.obs_o_y, obs.obs_o_z, obs.obs_t_x, obs.obs_t_y, obs.obs_t_z)
240            fs.write(param)
241        elif sensor.sensor_type == SensorType.LIDAR:
242            scanning_device = sensor.get_scanning_device()
243            if scanning_device.platform.type == "ALS":
244                param = """\nals_sensor = SensorLiDAR()
245als_sensor.set_spectral_bands("{}")
246scanning_device = ALSLiDAR()
247als_sensor.set_scanning_device(scanning_device)
248scanning_device.beam.axialDivision = {}
249scanning_device.beam.maxOrder = {}
250scanning_device.device.acquisitionPeriod = {}
251scanning_device.platform.altitude = {}
252scanning_device.platform.startX = {}
253scanning_device.platform.startY = {}
254scanning_device.platform.endX = {}
255scanning_device.platform.endY = {}
256scanning_device.platform.swathWidth = {}
257scanning_device.platform.rangeResolution = {}
258scanning_device.platform.yawResolution = {}
259scanning_device.platform.minRange = {}
260scanning_device.platform.maxRange = {}
261scanning_device.platform.pulseSpatialFile = "{}"
262scanning_device.set_lidar_sim_mode({})
263scene.set_sensor(als_sensor)
264""".format(sensor.get_spectral_bands(), scanning_device.beam.axialDivision, scanning_device.beam.maxOrder,
265           scanning_device.device.acquisitionPeriod, scanning_device.platform.altitude,
266           scanning_device.platform.startX, scanning_device.platform.startY,
267           scanning_device.platform.endX, scanning_device.platform.endY,
268           scanning_device.platform.swathWidth,
269           scanning_device.platform.rangeResolution,
270           scanning_device.platform.yawResolution,
271           scanning_device.platform.minRange,
272           scanning_device.platform.maxRange,
273           scanning_device.platform.pulseSpatialFile,
274           scanning_device.sim_mode)
275                fs.write(param)
276            elif scanning_device.platform.type == "TLS":
277                param = """\ntls_sensor = SensorLiDAR()
278tls_sensor.set_spectral_bands("{}")
279scanning_device = TLSLiDAR()
280tls_sensor.set_scanning_device(scanning_device)
281scanning_device.beam.axialDivision = {}
282scanning_device.beam.maxOrder = {}
283scanning_device.device.acquisitionPeriod = {}
284scanning_device.platform.echoDetectionMode = {}
285scanning_device.platform.centerAzimuth = {}
286scanning_device.platform.resolutionAzimuth = {}
287scanning_device.platform.deltaAzimuth = {}
288scanning_device.platform.centerZenith = {}
289scanning_device.platform.deltaZenith = {}
290scanning_device.platform.resolutionZenith = {}
291scanning_device.platform.minRange = {}
292scanning_device.platform.maxRange = {}
293scanning_device.platform.x = {}
294scanning_device.platform.y = {}
295scanning_device.platform.z = {}
296scanning_device.platform.pulseSpatialFile = "{}"
297scanning_device.set_lidar_sim_mode({})
298scene.set_sensor(tls_sensor)
299                """.format(sensor.get_spectral_bands(),
300                           scanning_device.beam.axialDivision, scanning_device.beam.maxOrder, scanning_device.device.acquisitionPeriod,
301                           scanning_device.platform.echoDetectionMode, scanning_device.platform.centerAzimuth,
302                           scanning_device.platform.resolutionAzimuth,scanning_device.platform.deltaAzimuth,
303                           scanning_device.platform.centerZenith, scanning_device.platform.deltaZenith,
304                           scanning_device.platform.resolutionZenith, scanning_device.platform.minRange,
305                           scanning_device.platform.maxRange, scanning_device.platform.x, scanning_device.platform.y,
306                           scanning_device.platform.z, scanning_device.platform.pulseSpatialFile, scanning_device.sim_mode)
307                fs.write(param)
308            elif scanning_device.platform.type == "Mono Pulse":
309                param = """\nmono_sensor = SensorLiDAR()
310mono_sensor.set_spectral_bands("{}")
311scanning_device = MonoPulseLiDAR()
312mono_sensor.set_scanning_device(scanning_device)
313scanning_device.beam.axialDivision = {}
314scanning_device.beam.maxOrder = {}
315scanning_device.device.acquisitionPeriod = {}
316scanning_device.platform.x = {}
317scanning_device.platform.y = {}
318scanning_device.platform.z = {}
319scanning_device.platform.zenith = {}
320scanning_device.platform.azimuth = {}
321scanning_device.platform.minRange = {}
322scanning_device.platform.maxRange = {}
323scanning_device.platform.pulseSpatialFile = "{}"
324scanning_device.set_lidar_sim_mode({})
325scene.set_sensor(mono_sensor)
326                """.format(sensor.get_spectral_bands(),
327                           scanning_device.beam.axialDivision, scanning_device.beam.maxOrder,
328                           scanning_device.device.acquisitionPeriod,
329                           scanning_device.platform.x,
330                           scanning_device.platform.y,
331                           scanning_device.platform.z,
332                           scanning_device.platform.zenith,
333                           scanning_device.platform.azimuth,
334                           scanning_device.platform.minRange,
335                           scanning_device.platform.maxRange,
336                           scanning_device.platform.pulseSpatialFile,
337                           scanning_device.sim_mode)
338                fs.write(param)
339
340        fs.write("\n\n# Advanced Parameter")
341
342        fs.write("""\nscene.get_advanced_params().set_number_of_cores({})  # How many CPU cores used to do simulation"""
343                 .format(scene.get_advanced_params().number_of_cores))
344
345        fs.write("\n\n# Simulation")
346        fs.write("\n# You can use sim.set_dist_file to customize the final file name")
347        fs.write("\n# You can use PostProcessing.radiance2brf to convert radiance image to BRF image")
348        fs.write("""\n# When you want to do batch-processing by changing optical properties and sun/obs geometries,
349# you can use sim.enable_runtime_modification_of_properties(True), 
350# and then modify the optical properties in a loop to do simulation, which avoids the reload of the 
351# obj files to save overall time. Please refer to Ex07 in the pyLessSDK folder for more details""")
352        fs.write("""\nsim.save_sim_project()""")
353        fs.write("""\nsim.start()\n""")
354
355        fs.close()
356
357
358if __name__ == "__main__":
359    parser = argparse.ArgumentParser()
360    parser.add_argument('-sim_dir', help="Simulation Dir.", type=str)
361    parser.add_argument('-out_script', help="output script.", type=str)
362    args = parser.parse_args()
363    generator = SDKCodeGenerator(args.sim_dir)
364    generator.generate(args.out_script)
365    print("INFO: Code is saved to:", args.out_script)
def get_less_install_path():
11def get_less_install_path():
12    p = os.path.realpath(__file__)
13    p = os.path.dirname(p)
14    p = os.path.dirname(p)
15    p = os.path.dirname(p)
16    p = os.path.dirname(p)
17    return p
class SDKCodeGenerator:
 20class SDKCodeGenerator(object):
 21    def __init__(self, sim_dir):
 22        self.sim_dir = sim_dir
 23
 24    def generate(self, out_script_path):
 25        fs = open(out_script_path, 'w', encoding='utf-8')
 26        sim_helper = SimulationHelper(get_less_install_path())  # 创建SimulationHelper,参数为LESS的安装根目录
 27        sim_helper.create_new_sim(self.sim_dir)  # 新建模拟工程
 28        sim = Simulation(self.sim_dir, sim_helper)  # 初始化Simulation对象
 29        sim.read_sim_project()  # 读取模拟工程的内容
 30        scene = sim.get_scene()  # 得到Scene
 31        landscape = scene.get_landscape()  # 得到LandScape对象
 32
 33        fs.write("""# coding: utf-8
 34# This script is automatically generated from the GUI
 35# It can generate the same simulation project with the GUI one you created
 36# You can customize this script for usages such as batch processing
 37# The generated code may not cover all functionalities from GUI, please refer to the API for more details.
 38import sys
 39sys.path.append(r"{}")
 40from SimulationHelper import SimulationHelper
 41from Simulation import Simulation
 42from Terrain import TERRAIN_TYPE, TERRAIN_BRDF_TYPE
 43from OpticalProperty import OpticalItem
 44from SceneObjects import SceneObject
 45from Sensor import *
 46from Observation import *
 47from LiDAR import ALSLiDAR, TLSLiDAR, LiDARSimMode, MonoPulseLiDAR
 48from Illumination import Illumination
 49import os
 50
 51sim_helper = SimulationHelper(r"{}")  # Create SimulationHelper, the parameters is the path to LESS installation folder
 52sim_helper.create_new_sim(r"{}")  # Create a new simulation, if already exists, it skips
 53sim = Simulation(r"{}", sim_helper)  # Initialize a Simulation
 54sim.read_sim_project()  # Read the content of the simulation
 55scene = sim.get_scene()  # Read the scene
 56landscape = scene.get_landscape()  # Get the Landscape
 57# If you want to keep scene structures unchanged, you should comment out the following line
 58landscape.clear_landscape_elements()  # Clear existing objects and instances(must be run when you want change scene structures)
 59landscape.clear_user_defined_optical_properties()  # Clear optical properties defined by users
 60        """.format(os.path.dirname(os.path.realpath(__file__)), get_less_install_path(), self.sim_dir, self.sim_dir))
 61
 62        fs.write("\n# Optical properties")
 63        for op_item in landscape.get_all_op_items():
 64            if op_item.get_op_name() not in ["birch_branch", "dark_soil_mollisol", "birch_leaf_green"]:
 65                fs.write(
 66                    """\nop_item = OpticalItem("{}", "{}", {}, {})""".format(op_item.get_op_name(), op_item.get_op_value(), op_item.get_op_type(), op_item.get_op_model_params()))
 67                fs.write("""\nlandscape.add_op_item(op_item)  # Add optical properties""")
 68
 69        fs.write("\n\n# Objects")
 70        fs.write("\n# If yo do not intend to change scene structures, you should comment out this section to "
 71                 "avoid importing objs for each simulation,")
 72        fs.write("\n# and you should also comment out landscape.clear_landscape_elements()")
 73        objects = landscape.get_objects()
 74        for obj in objects:
 75            fs.write("""\nobj = SceneObject(r"{}")  # Define an object""".format(obj))
 76            for comp in objects[obj]:
 77                comp_path = os.path.join(sim.get_parameters_dir(), comp)
 78                if not objects[obj][comp]["is_turbid"]:
 79                    fs.write("""\nobj.add_component_from_file(r"{}", "{}")""".format(comp_path,
 80                                                                                     objects[obj][comp]["op_name"]))
 81                else:
 82                    fs.write(
 83                        """\nobj.add_component_from_file(r"{}", "{}", temperature="{}", color="{}",
 84                                is_turbid={}, leaf_density={}, lad="{}", hotspot_factor={})""".format(comp_path,
 85                                                                                                      objects[obj][
 86                                                                                                          comp][
 87                                                                                                          "op_name"],
 88                                                                                                      objects[obj][comp]["temperature"],
 89                                                                                                      objects[obj][comp]["color"],
 90                                                                                                      objects[obj][comp][ "is_turbid"],
 91                                                                                                      str(objects[obj][comp]["leaf_density"]),
 92                                                                                                      objects[obj][comp]["lad"],
 93                                                                                                      str(objects[obj][ comp][ "hotspot_factor"])))
 94            fs.write("""\nlandscape.add_object(obj)""")
 95
 96        fs.write("\n\n# Instances")
 97        fs.write("\n# If you do not intend to change scene structures, you should comment out this section,")
 98        fs.write("\n# and you should also comment out landscape.clear_landscape_elements()")
 99        fs.write("""\n# You can read the positions from a file and using a loop to place objects, [X Y Z Rotation]""")
100        instances = landscape.get_instances()
101        for obj_instance in instances:
102            fs.write("""\n{}_positions = {}""".format(obj_instance, instances[obj_instance]))
103            fs.write("""\nfor pos in {}_positions:
104    if len(pos) == 4:
105        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3])
106    elif len(pos) == 7:
107        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3], rotate_axis_x=pos[4], rotate_axis_y=pos[5], rotate_axis_z=pos[6])
108    elif len(pos) == 10:
109        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3], rotate_axis_x=pos[4], rotate_axis_y=pos[5], rotate_axis_z=pos[6], scale_extent_x=pos[7], scale_extent_y=pos[8], scale_extent_z=pos[9])
110        """.format(obj_instance, obj_instance, obj_instance, obj_instance))
111
112        fs.write("\n\n# Terrain")
113        fs.write("\n# If you use default optical ,e.g., dark_soil_mollisol, and if you change the number of spectral ")
114        fs.write("\n# bands, please define your own optical properties, otherwise, there will be band number issues. ")
115        fs.write("\n# The three default optical properties have two bands only in the PyLessSDK. ")
116        terrain = landscape.get_terrain()
117        fs.write("""\nterrain = landscape.get_terrain()""")
118        fs.write("""\nterrain.set_extent_width({})""".format(terrain.get_extent_width()))
119        fs.write("""\nterrain.set_extent_height({})""".format(terrain.get_extent_height()))
120        fs.write("""\nterrain.set_terrain_type(TERRAIN_TYPE.{})""".format(terrain.terrain_type))
121        if terrain.terrain_type == TERRAIN_TYPE.MESH or terrain.terrain_type == TERRAIN_TYPE.RASTER:
122            fs.write("""\nterrain.set_terrain_file(r"{}")""".format(
123                os.path.join(sim.get_parameters_dir(), terrain.terr_file)))
124        brdf_type = terrain.get_terr_brdf_type()
125        fs.write("""\nterrain.set_terr_brdf_type(TERRAIN_BRDF_TYPE.{})""".format(
126            terrain.get_terr_brdf_type().upper().replace(" ", "_")))
127        if brdf_type == TERRAIN_BRDF_TYPE.LAMBERTIAN:
128            fs.write("""\nterrain.set_optical(r"{}")""".format(terrain.get_optical()))
129        elif brdf_type == TERRAIN_BRDF_TYPE.SOILSPECT:
130            fs.write("""\nterrain.soilSpectParams = {}""".format(terrain.soilSpectParams))
131        elif brdf_type == TERRAIN_BRDF_TYPE.ART:
132            fs.write("""\nterrain.artParams = {}""".format(terrain.artParams))
133        elif brdf_type == TERRAIN_BRDF_TYPE.RPV:
134            fs.write("""\nterrain.rpvParams = {}""".format(terrain.rpvParams))
135        elif brdf_type == TERRAIN_BRDF_TYPE.LAND_ALBEDO_MAP:
136            fs.write("""\nterrain.set_landalbedo_file(r"{}")""".format(
137                os.path.join(sim.get_parameters_dir(), terrain.get_landalbedo_file())))
138        fs.write("""\n# If you want to open the simulation with GUI, please uncomment this following line""")
139        fs.write("""\n# sim.prepare_for_ui()""")
140
141        fs.write("\n\n# Illumination")
142        illu = scene.get_illumination()
143        fs.write("""\nillu = Illumination()""")
144        fs.write("""\nillu.set_ats_percentage("{}")""".format(illu.get_ats_percentage()))
145        fs.write("""\nillu.set_sun_zenith({})""".format(illu.sun_zenith))
146        fs.write("""\nillu.set_sun_azimuth({})""".format(illu.sun_azimuth))
147        fs.write("""\nscene.set_illumination(illu)""")
148
149        fs.write("\n\n# Sensor")
150        fs.write("\n# !Note that scene.set_sensor(sensor) should be executed after sensor setup is complete!")
151        sensor = scene.get_sensor()
152        obs = scene.get_observation()
153        vp_obj = sensor.get_virtualPlane()
154        virtual_plane_str = "" if vp_obj is None else \
155            "sensor.enable_virtual_plane(True, center=(%s, %s), size=(%s, %s))" % (vp_obj["vx"], vp_obj["vy"],
156                                                                                  vp_obj["sizex"], vp_obj["sizey"])
157        if sensor.sensor_type == SensorType.ORTHOGRAPHIC:
158            param = """\nsensor = SensorOrthographic()
159sensor.set_film_type("{}")
160sensor.set_spectral_bands("{}")
161sensor.set_image_width({})
162sensor.set_image_height({})
163sensor.set_sample_per_pixel({})
164sensor.has_four_components_product = {}
165sensor.has_Fluor_Product = {}
166sensor.set_sub_region_width({})
167sensor.set_sub_region_height({})
168sensor.cover_whole_scene = {}
169sensor.set_repetitive_scene({})
170{}
171scene.set_sensor(sensor)
172obs = ObservationOrthographic()
173obs.set_obs_zenith({})
174obs.set_obs_azimuth({})
175obs.is_orthophoto_map = {}
176obs.orthophoto_relative_height = {}
177scene.set_observation(obs)
178            """.format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
179                       sensor.get_image_height(), sensor.get_sample_per_pixel(), sensor.has_four_components_product, sensor.has_Fluor_Product,
180                       sensor.sub_region_width, sensor.sub_region_height, sensor.cover_whole_scene,
181                       sensor.get_repetitive_scene(),virtual_plane_str, obs.obs_zenith, obs.obs_azimuth, obs.is_orthophoto_map,
182                       obs.orthophoto_relative_height)
183            fs.write(param)
184        elif sensor.sensor_type == SensorType.PERSPECTIVE:
185            param = """\nsensor = SensorPerspective()
186sensor.set_film_type("{}") 
187sensor.set_spectral_bands("{}") 
188sensor.set_image_width({})
189sensor.set_image_height({})
190sensor.set_fov_x({})  
191sensor.set_fov_y({})
192sensor.set_sample_per_pixel({})
193sensor.set_repetitive_scene({})
194sensor.has_Fluor_Product = {}
195{}
196scene.set_sensor(sensor)
197obs = ObservationPerspective()
198obs.set_origin(({}, {}, {}))
199obs.set_target(({}, {}, {}))
200scene.set_observation(obs)
201""".format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
202           sensor.get_image_height(), sensor.get_fov_x(), sensor.get_fov_y(),
203           sensor.get_sample_per_pixel(), sensor.get_repetitive_scene(), sensor.has_Fluor_Product, virtual_plane_str, obs.obs_o_x,
204           obs.obs_o_y, obs.obs_o_z, obs.obs_t_x, obs.obs_t_y, obs.obs_t_z)
205            fs.write(param)
206        elif sensor.sensor_type == SensorType.PHOTONTRACING:
207            param = """\nsensor = SensorPhotonTracing()
208sensor.set_spectral_bands("{}")
209sensor.enable_brf_product({})
210sensor.enable_Fluor_product({})
211sensor.set_sun_ray_resolution({})
212sensor.set_virtual_directions("{}")
213sensor.enable_fpar_product({})
214sensor.set_fpar_layer("{}")
215{}
216scene.set_sensor(sensor)
217obs = ObservationPhotonTracing()
218scene.set_observation(obs)""".format(sensor.get_spectral_bands(), sensor.BRF_product, sensor.Fluor_product, sensor.get_run_ray_resolution(),
219                                     sensor.get_virtual_directions(), sensor.fPAR_product, sensor.get_fpar_layer(),
220                                     virtual_plane_str)
221            fs.write(param)
222        elif sensor.sensor_type == SensorType.CIRCULARFISHEYE:
223            param = """\nsensor = SensorFisheye()
224sensor.set_film_type("{}")
225sensor.set_spectral_bands("{}")
226sensor.set_image_width({})
227sensor.set_image_height({})
228sensor.set_angular_fov({})
229sensor.set_projection_type("{}")
230sensor.set_sample_per_pixel({})
231sensor.set_repetitive_scene({})
232sensor.has_Fluor_Product = {}
233scene.set_sensor(sensor)
234obs = ObservationFisheye()
235obs.set_origin(({}, {}, {}))
236obs.set_target(({}, {}, {}))
237scene.set_observation(obs)""".format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
238                                     sensor.get_image_height(), sensor.get_angular_fov(), sensor.get_projection_type(),
239                                     sensor.get_sample_per_pixel(), sensor.get_repetitive_scene(), sensor.has_Fluor_Product, obs.obs_o_x,
240                                     obs.obs_o_y, obs.obs_o_z, obs.obs_t_x, obs.obs_t_y, obs.obs_t_z)
241            fs.write(param)
242        elif sensor.sensor_type == SensorType.LIDAR:
243            scanning_device = sensor.get_scanning_device()
244            if scanning_device.platform.type == "ALS":
245                param = """\nals_sensor = SensorLiDAR()
246als_sensor.set_spectral_bands("{}")
247scanning_device = ALSLiDAR()
248als_sensor.set_scanning_device(scanning_device)
249scanning_device.beam.axialDivision = {}
250scanning_device.beam.maxOrder = {}
251scanning_device.device.acquisitionPeriod = {}
252scanning_device.platform.altitude = {}
253scanning_device.platform.startX = {}
254scanning_device.platform.startY = {}
255scanning_device.platform.endX = {}
256scanning_device.platform.endY = {}
257scanning_device.platform.swathWidth = {}
258scanning_device.platform.rangeResolution = {}
259scanning_device.platform.yawResolution = {}
260scanning_device.platform.minRange = {}
261scanning_device.platform.maxRange = {}
262scanning_device.platform.pulseSpatialFile = "{}"
263scanning_device.set_lidar_sim_mode({})
264scene.set_sensor(als_sensor)
265""".format(sensor.get_spectral_bands(), scanning_device.beam.axialDivision, scanning_device.beam.maxOrder,
266           scanning_device.device.acquisitionPeriod, scanning_device.platform.altitude,
267           scanning_device.platform.startX, scanning_device.platform.startY,
268           scanning_device.platform.endX, scanning_device.platform.endY,
269           scanning_device.platform.swathWidth,
270           scanning_device.platform.rangeResolution,
271           scanning_device.platform.yawResolution,
272           scanning_device.platform.minRange,
273           scanning_device.platform.maxRange,
274           scanning_device.platform.pulseSpatialFile,
275           scanning_device.sim_mode)
276                fs.write(param)
277            elif scanning_device.platform.type == "TLS":
278                param = """\ntls_sensor = SensorLiDAR()
279tls_sensor.set_spectral_bands("{}")
280scanning_device = TLSLiDAR()
281tls_sensor.set_scanning_device(scanning_device)
282scanning_device.beam.axialDivision = {}
283scanning_device.beam.maxOrder = {}
284scanning_device.device.acquisitionPeriod = {}
285scanning_device.platform.echoDetectionMode = {}
286scanning_device.platform.centerAzimuth = {}
287scanning_device.platform.resolutionAzimuth = {}
288scanning_device.platform.deltaAzimuth = {}
289scanning_device.platform.centerZenith = {}
290scanning_device.platform.deltaZenith = {}
291scanning_device.platform.resolutionZenith = {}
292scanning_device.platform.minRange = {}
293scanning_device.platform.maxRange = {}
294scanning_device.platform.x = {}
295scanning_device.platform.y = {}
296scanning_device.platform.z = {}
297scanning_device.platform.pulseSpatialFile = "{}"
298scanning_device.set_lidar_sim_mode({})
299scene.set_sensor(tls_sensor)
300                """.format(sensor.get_spectral_bands(),
301                           scanning_device.beam.axialDivision, scanning_device.beam.maxOrder, scanning_device.device.acquisitionPeriod,
302                           scanning_device.platform.echoDetectionMode, scanning_device.platform.centerAzimuth,
303                           scanning_device.platform.resolutionAzimuth,scanning_device.platform.deltaAzimuth,
304                           scanning_device.platform.centerZenith, scanning_device.platform.deltaZenith,
305                           scanning_device.platform.resolutionZenith, scanning_device.platform.minRange,
306                           scanning_device.platform.maxRange, scanning_device.platform.x, scanning_device.platform.y,
307                           scanning_device.platform.z, scanning_device.platform.pulseSpatialFile, scanning_device.sim_mode)
308                fs.write(param)
309            elif scanning_device.platform.type == "Mono Pulse":
310                param = """\nmono_sensor = SensorLiDAR()
311mono_sensor.set_spectral_bands("{}")
312scanning_device = MonoPulseLiDAR()
313mono_sensor.set_scanning_device(scanning_device)
314scanning_device.beam.axialDivision = {}
315scanning_device.beam.maxOrder = {}
316scanning_device.device.acquisitionPeriod = {}
317scanning_device.platform.x = {}
318scanning_device.platform.y = {}
319scanning_device.platform.z = {}
320scanning_device.platform.zenith = {}
321scanning_device.platform.azimuth = {}
322scanning_device.platform.minRange = {}
323scanning_device.platform.maxRange = {}
324scanning_device.platform.pulseSpatialFile = "{}"
325scanning_device.set_lidar_sim_mode({})
326scene.set_sensor(mono_sensor)
327                """.format(sensor.get_spectral_bands(),
328                           scanning_device.beam.axialDivision, scanning_device.beam.maxOrder,
329                           scanning_device.device.acquisitionPeriod,
330                           scanning_device.platform.x,
331                           scanning_device.platform.y,
332                           scanning_device.platform.z,
333                           scanning_device.platform.zenith,
334                           scanning_device.platform.azimuth,
335                           scanning_device.platform.minRange,
336                           scanning_device.platform.maxRange,
337                           scanning_device.platform.pulseSpatialFile,
338                           scanning_device.sim_mode)
339                fs.write(param)
340
341        fs.write("\n\n# Advanced Parameter")
342
343        fs.write("""\nscene.get_advanced_params().set_number_of_cores({})  # How many CPU cores used to do simulation"""
344                 .format(scene.get_advanced_params().number_of_cores))
345
346        fs.write("\n\n# Simulation")
347        fs.write("\n# You can use sim.set_dist_file to customize the final file name")
348        fs.write("\n# You can use PostProcessing.radiance2brf to convert radiance image to BRF image")
349        fs.write("""\n# When you want to do batch-processing by changing optical properties and sun/obs geometries,
350# you can use sim.enable_runtime_modification_of_properties(True), 
351# and then modify the optical properties in a loop to do simulation, which avoids the reload of the 
352# obj files to save overall time. Please refer to Ex07 in the pyLessSDK folder for more details""")
353        fs.write("""\nsim.save_sim_project()""")
354        fs.write("""\nsim.start()\n""")
355
356        fs.close()
SDKCodeGenerator(sim_dir)
21    def __init__(self, sim_dir):
22        self.sim_dir = sim_dir
sim_dir
def generate(self, out_script_path):
 24    def generate(self, out_script_path):
 25        fs = open(out_script_path, 'w', encoding='utf-8')
 26        sim_helper = SimulationHelper(get_less_install_path())  # 创建SimulationHelper,参数为LESS的安装根目录
 27        sim_helper.create_new_sim(self.sim_dir)  # 新建模拟工程
 28        sim = Simulation(self.sim_dir, sim_helper)  # 初始化Simulation对象
 29        sim.read_sim_project()  # 读取模拟工程的内容
 30        scene = sim.get_scene()  # 得到Scene
 31        landscape = scene.get_landscape()  # 得到LandScape对象
 32
 33        fs.write("""# coding: utf-8
 34# This script is automatically generated from the GUI
 35# It can generate the same simulation project with the GUI one you created
 36# You can customize this script for usages such as batch processing
 37# The generated code may not cover all functionalities from GUI, please refer to the API for more details.
 38import sys
 39sys.path.append(r"{}")
 40from SimulationHelper import SimulationHelper
 41from Simulation import Simulation
 42from Terrain import TERRAIN_TYPE, TERRAIN_BRDF_TYPE
 43from OpticalProperty import OpticalItem
 44from SceneObjects import SceneObject
 45from Sensor import *
 46from Observation import *
 47from LiDAR import ALSLiDAR, TLSLiDAR, LiDARSimMode, MonoPulseLiDAR
 48from Illumination import Illumination
 49import os
 50
 51sim_helper = SimulationHelper(r"{}")  # Create SimulationHelper, the parameters is the path to LESS installation folder
 52sim_helper.create_new_sim(r"{}")  # Create a new simulation, if already exists, it skips
 53sim = Simulation(r"{}", sim_helper)  # Initialize a Simulation
 54sim.read_sim_project()  # Read the content of the simulation
 55scene = sim.get_scene()  # Read the scene
 56landscape = scene.get_landscape()  # Get the Landscape
 57# If you want to keep scene structures unchanged, you should comment out the following line
 58landscape.clear_landscape_elements()  # Clear existing objects and instances(must be run when you want change scene structures)
 59landscape.clear_user_defined_optical_properties()  # Clear optical properties defined by users
 60        """.format(os.path.dirname(os.path.realpath(__file__)), get_less_install_path(), self.sim_dir, self.sim_dir))
 61
 62        fs.write("\n# Optical properties")
 63        for op_item in landscape.get_all_op_items():
 64            if op_item.get_op_name() not in ["birch_branch", "dark_soil_mollisol", "birch_leaf_green"]:
 65                fs.write(
 66                    """\nop_item = OpticalItem("{}", "{}", {}, {})""".format(op_item.get_op_name(), op_item.get_op_value(), op_item.get_op_type(), op_item.get_op_model_params()))
 67                fs.write("""\nlandscape.add_op_item(op_item)  # Add optical properties""")
 68
 69        fs.write("\n\n# Objects")
 70        fs.write("\n# If yo do not intend to change scene structures, you should comment out this section to "
 71                 "avoid importing objs for each simulation,")
 72        fs.write("\n# and you should also comment out landscape.clear_landscape_elements()")
 73        objects = landscape.get_objects()
 74        for obj in objects:
 75            fs.write("""\nobj = SceneObject(r"{}")  # Define an object""".format(obj))
 76            for comp in objects[obj]:
 77                comp_path = os.path.join(sim.get_parameters_dir(), comp)
 78                if not objects[obj][comp]["is_turbid"]:
 79                    fs.write("""\nobj.add_component_from_file(r"{}", "{}")""".format(comp_path,
 80                                                                                     objects[obj][comp]["op_name"]))
 81                else:
 82                    fs.write(
 83                        """\nobj.add_component_from_file(r"{}", "{}", temperature="{}", color="{}",
 84                                is_turbid={}, leaf_density={}, lad="{}", hotspot_factor={})""".format(comp_path,
 85                                                                                                      objects[obj][
 86                                                                                                          comp][
 87                                                                                                          "op_name"],
 88                                                                                                      objects[obj][comp]["temperature"],
 89                                                                                                      objects[obj][comp]["color"],
 90                                                                                                      objects[obj][comp][ "is_turbid"],
 91                                                                                                      str(objects[obj][comp]["leaf_density"]),
 92                                                                                                      objects[obj][comp]["lad"],
 93                                                                                                      str(objects[obj][ comp][ "hotspot_factor"])))
 94            fs.write("""\nlandscape.add_object(obj)""")
 95
 96        fs.write("\n\n# Instances")
 97        fs.write("\n# If you do not intend to change scene structures, you should comment out this section,")
 98        fs.write("\n# and you should also comment out landscape.clear_landscape_elements()")
 99        fs.write("""\n# You can read the positions from a file and using a loop to place objects, [X Y Z Rotation]""")
100        instances = landscape.get_instances()
101        for obj_instance in instances:
102            fs.write("""\n{}_positions = {}""".format(obj_instance, instances[obj_instance]))
103            fs.write("""\nfor pos in {}_positions:
104    if len(pos) == 4:
105        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3])
106    elif len(pos) == 7:
107        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3], rotate_axis_x=pos[4], rotate_axis_y=pos[5], rotate_axis_z=pos[6])
108    elif len(pos) == 10:
109        landscape.place_object("{}", x=pos[0], y=pos[1], z=pos[2], rotate=pos[3], rotate_axis_x=pos[4], rotate_axis_y=pos[5], rotate_axis_z=pos[6], scale_extent_x=pos[7], scale_extent_y=pos[8], scale_extent_z=pos[9])
110        """.format(obj_instance, obj_instance, obj_instance, obj_instance))
111
112        fs.write("\n\n# Terrain")
113        fs.write("\n# If you use default optical ,e.g., dark_soil_mollisol, and if you change the number of spectral ")
114        fs.write("\n# bands, please define your own optical properties, otherwise, there will be band number issues. ")
115        fs.write("\n# The three default optical properties have two bands only in the PyLessSDK. ")
116        terrain = landscape.get_terrain()
117        fs.write("""\nterrain = landscape.get_terrain()""")
118        fs.write("""\nterrain.set_extent_width({})""".format(terrain.get_extent_width()))
119        fs.write("""\nterrain.set_extent_height({})""".format(terrain.get_extent_height()))
120        fs.write("""\nterrain.set_terrain_type(TERRAIN_TYPE.{})""".format(terrain.terrain_type))
121        if terrain.terrain_type == TERRAIN_TYPE.MESH or terrain.terrain_type == TERRAIN_TYPE.RASTER:
122            fs.write("""\nterrain.set_terrain_file(r"{}")""".format(
123                os.path.join(sim.get_parameters_dir(), terrain.terr_file)))
124        brdf_type = terrain.get_terr_brdf_type()
125        fs.write("""\nterrain.set_terr_brdf_type(TERRAIN_BRDF_TYPE.{})""".format(
126            terrain.get_terr_brdf_type().upper().replace(" ", "_")))
127        if brdf_type == TERRAIN_BRDF_TYPE.LAMBERTIAN:
128            fs.write("""\nterrain.set_optical(r"{}")""".format(terrain.get_optical()))
129        elif brdf_type == TERRAIN_BRDF_TYPE.SOILSPECT:
130            fs.write("""\nterrain.soilSpectParams = {}""".format(terrain.soilSpectParams))
131        elif brdf_type == TERRAIN_BRDF_TYPE.ART:
132            fs.write("""\nterrain.artParams = {}""".format(terrain.artParams))
133        elif brdf_type == TERRAIN_BRDF_TYPE.RPV:
134            fs.write("""\nterrain.rpvParams = {}""".format(terrain.rpvParams))
135        elif brdf_type == TERRAIN_BRDF_TYPE.LAND_ALBEDO_MAP:
136            fs.write("""\nterrain.set_landalbedo_file(r"{}")""".format(
137                os.path.join(sim.get_parameters_dir(), terrain.get_landalbedo_file())))
138        fs.write("""\n# If you want to open the simulation with GUI, please uncomment this following line""")
139        fs.write("""\n# sim.prepare_for_ui()""")
140
141        fs.write("\n\n# Illumination")
142        illu = scene.get_illumination()
143        fs.write("""\nillu = Illumination()""")
144        fs.write("""\nillu.set_ats_percentage("{}")""".format(illu.get_ats_percentage()))
145        fs.write("""\nillu.set_sun_zenith({})""".format(illu.sun_zenith))
146        fs.write("""\nillu.set_sun_azimuth({})""".format(illu.sun_azimuth))
147        fs.write("""\nscene.set_illumination(illu)""")
148
149        fs.write("\n\n# Sensor")
150        fs.write("\n# !Note that scene.set_sensor(sensor) should be executed after sensor setup is complete!")
151        sensor = scene.get_sensor()
152        obs = scene.get_observation()
153        vp_obj = sensor.get_virtualPlane()
154        virtual_plane_str = "" if vp_obj is None else \
155            "sensor.enable_virtual_plane(True, center=(%s, %s), size=(%s, %s))" % (vp_obj["vx"], vp_obj["vy"],
156                                                                                  vp_obj["sizex"], vp_obj["sizey"])
157        if sensor.sensor_type == SensorType.ORTHOGRAPHIC:
158            param = """\nsensor = SensorOrthographic()
159sensor.set_film_type("{}")
160sensor.set_spectral_bands("{}")
161sensor.set_image_width({})
162sensor.set_image_height({})
163sensor.set_sample_per_pixel({})
164sensor.has_four_components_product = {}
165sensor.has_Fluor_Product = {}
166sensor.set_sub_region_width({})
167sensor.set_sub_region_height({})
168sensor.cover_whole_scene = {}
169sensor.set_repetitive_scene({})
170{}
171scene.set_sensor(sensor)
172obs = ObservationOrthographic()
173obs.set_obs_zenith({})
174obs.set_obs_azimuth({})
175obs.is_orthophoto_map = {}
176obs.orthophoto_relative_height = {}
177scene.set_observation(obs)
178            """.format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
179                       sensor.get_image_height(), sensor.get_sample_per_pixel(), sensor.has_four_components_product, sensor.has_Fluor_Product,
180                       sensor.sub_region_width, sensor.sub_region_height, sensor.cover_whole_scene,
181                       sensor.get_repetitive_scene(),virtual_plane_str, obs.obs_zenith, obs.obs_azimuth, obs.is_orthophoto_map,
182                       obs.orthophoto_relative_height)
183            fs.write(param)
184        elif sensor.sensor_type == SensorType.PERSPECTIVE:
185            param = """\nsensor = SensorPerspective()
186sensor.set_film_type("{}") 
187sensor.set_spectral_bands("{}") 
188sensor.set_image_width({})
189sensor.set_image_height({})
190sensor.set_fov_x({})  
191sensor.set_fov_y({})
192sensor.set_sample_per_pixel({})
193sensor.set_repetitive_scene({})
194sensor.has_Fluor_Product = {}
195{}
196scene.set_sensor(sensor)
197obs = ObservationPerspective()
198obs.set_origin(({}, {}, {}))
199obs.set_target(({}, {}, {}))
200scene.set_observation(obs)
201""".format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
202           sensor.get_image_height(), sensor.get_fov_x(), sensor.get_fov_y(),
203           sensor.get_sample_per_pixel(), sensor.get_repetitive_scene(), sensor.has_Fluor_Product, virtual_plane_str, obs.obs_o_x,
204           obs.obs_o_y, obs.obs_o_z, obs.obs_t_x, obs.obs_t_y, obs.obs_t_z)
205            fs.write(param)
206        elif sensor.sensor_type == SensorType.PHOTONTRACING:
207            param = """\nsensor = SensorPhotonTracing()
208sensor.set_spectral_bands("{}")
209sensor.enable_brf_product({})
210sensor.enable_Fluor_product({})
211sensor.set_sun_ray_resolution({})
212sensor.set_virtual_directions("{}")
213sensor.enable_fpar_product({})
214sensor.set_fpar_layer("{}")
215{}
216scene.set_sensor(sensor)
217obs = ObservationPhotonTracing()
218scene.set_observation(obs)""".format(sensor.get_spectral_bands(), sensor.BRF_product, sensor.Fluor_product, sensor.get_run_ray_resolution(),
219                                     sensor.get_virtual_directions(), sensor.fPAR_product, sensor.get_fpar_layer(),
220                                     virtual_plane_str)
221            fs.write(param)
222        elif sensor.sensor_type == SensorType.CIRCULARFISHEYE:
223            param = """\nsensor = SensorFisheye()
224sensor.set_film_type("{}")
225sensor.set_spectral_bands("{}")
226sensor.set_image_width({})
227sensor.set_image_height({})
228sensor.set_angular_fov({})
229sensor.set_projection_type("{}")
230sensor.set_sample_per_pixel({})
231sensor.set_repetitive_scene({})
232sensor.has_Fluor_Product = {}
233scene.set_sensor(sensor)
234obs = ObservationFisheye()
235obs.set_origin(({}, {}, {}))
236obs.set_target(({}, {}, {}))
237scene.set_observation(obs)""".format(sensor.get_film_type(), sensor.get_spectral_bands(), sensor.get_image_width(),
238                                     sensor.get_image_height(), sensor.get_angular_fov(), sensor.get_projection_type(),
239                                     sensor.get_sample_per_pixel(), sensor.get_repetitive_scene(), sensor.has_Fluor_Product, obs.obs_o_x,
240                                     obs.obs_o_y, obs.obs_o_z, obs.obs_t_x, obs.obs_t_y, obs.obs_t_z)
241            fs.write(param)
242        elif sensor.sensor_type == SensorType.LIDAR:
243            scanning_device = sensor.get_scanning_device()
244            if scanning_device.platform.type == "ALS":
245                param = """\nals_sensor = SensorLiDAR()
246als_sensor.set_spectral_bands("{}")
247scanning_device = ALSLiDAR()
248als_sensor.set_scanning_device(scanning_device)
249scanning_device.beam.axialDivision = {}
250scanning_device.beam.maxOrder = {}
251scanning_device.device.acquisitionPeriod = {}
252scanning_device.platform.altitude = {}
253scanning_device.platform.startX = {}
254scanning_device.platform.startY = {}
255scanning_device.platform.endX = {}
256scanning_device.platform.endY = {}
257scanning_device.platform.swathWidth = {}
258scanning_device.platform.rangeResolution = {}
259scanning_device.platform.yawResolution = {}
260scanning_device.platform.minRange = {}
261scanning_device.platform.maxRange = {}
262scanning_device.platform.pulseSpatialFile = "{}"
263scanning_device.set_lidar_sim_mode({})
264scene.set_sensor(als_sensor)
265""".format(sensor.get_spectral_bands(), scanning_device.beam.axialDivision, scanning_device.beam.maxOrder,
266           scanning_device.device.acquisitionPeriod, scanning_device.platform.altitude,
267           scanning_device.platform.startX, scanning_device.platform.startY,
268           scanning_device.platform.endX, scanning_device.platform.endY,
269           scanning_device.platform.swathWidth,
270           scanning_device.platform.rangeResolution,
271           scanning_device.platform.yawResolution,
272           scanning_device.platform.minRange,
273           scanning_device.platform.maxRange,
274           scanning_device.platform.pulseSpatialFile,
275           scanning_device.sim_mode)
276                fs.write(param)
277            elif scanning_device.platform.type == "TLS":
278                param = """\ntls_sensor = SensorLiDAR()
279tls_sensor.set_spectral_bands("{}")
280scanning_device = TLSLiDAR()
281tls_sensor.set_scanning_device(scanning_device)
282scanning_device.beam.axialDivision = {}
283scanning_device.beam.maxOrder = {}
284scanning_device.device.acquisitionPeriod = {}
285scanning_device.platform.echoDetectionMode = {}
286scanning_device.platform.centerAzimuth = {}
287scanning_device.platform.resolutionAzimuth = {}
288scanning_device.platform.deltaAzimuth = {}
289scanning_device.platform.centerZenith = {}
290scanning_device.platform.deltaZenith = {}
291scanning_device.platform.resolutionZenith = {}
292scanning_device.platform.minRange = {}
293scanning_device.platform.maxRange = {}
294scanning_device.platform.x = {}
295scanning_device.platform.y = {}
296scanning_device.platform.z = {}
297scanning_device.platform.pulseSpatialFile = "{}"
298scanning_device.set_lidar_sim_mode({})
299scene.set_sensor(tls_sensor)
300                """.format(sensor.get_spectral_bands(),
301                           scanning_device.beam.axialDivision, scanning_device.beam.maxOrder, scanning_device.device.acquisitionPeriod,
302                           scanning_device.platform.echoDetectionMode, scanning_device.platform.centerAzimuth,
303                           scanning_device.platform.resolutionAzimuth,scanning_device.platform.deltaAzimuth,
304                           scanning_device.platform.centerZenith, scanning_device.platform.deltaZenith,
305                           scanning_device.platform.resolutionZenith, scanning_device.platform.minRange,
306                           scanning_device.platform.maxRange, scanning_device.platform.x, scanning_device.platform.y,
307                           scanning_device.platform.z, scanning_device.platform.pulseSpatialFile, scanning_device.sim_mode)
308                fs.write(param)
309            elif scanning_device.platform.type == "Mono Pulse":
310                param = """\nmono_sensor = SensorLiDAR()
311mono_sensor.set_spectral_bands("{}")
312scanning_device = MonoPulseLiDAR()
313mono_sensor.set_scanning_device(scanning_device)
314scanning_device.beam.axialDivision = {}
315scanning_device.beam.maxOrder = {}
316scanning_device.device.acquisitionPeriod = {}
317scanning_device.platform.x = {}
318scanning_device.platform.y = {}
319scanning_device.platform.z = {}
320scanning_device.platform.zenith = {}
321scanning_device.platform.azimuth = {}
322scanning_device.platform.minRange = {}
323scanning_device.platform.maxRange = {}
324scanning_device.platform.pulseSpatialFile = "{}"
325scanning_device.set_lidar_sim_mode({})
326scene.set_sensor(mono_sensor)
327                """.format(sensor.get_spectral_bands(),
328                           scanning_device.beam.axialDivision, scanning_device.beam.maxOrder,
329                           scanning_device.device.acquisitionPeriod,
330                           scanning_device.platform.x,
331                           scanning_device.platform.y,
332                           scanning_device.platform.z,
333                           scanning_device.platform.zenith,
334                           scanning_device.platform.azimuth,
335                           scanning_device.platform.minRange,
336                           scanning_device.platform.maxRange,
337                           scanning_device.platform.pulseSpatialFile,
338                           scanning_device.sim_mode)
339                fs.write(param)
340
341        fs.write("\n\n# Advanced Parameter")
342
343        fs.write("""\nscene.get_advanced_params().set_number_of_cores({})  # How many CPU cores used to do simulation"""
344                 .format(scene.get_advanced_params().number_of_cores))
345
346        fs.write("\n\n# Simulation")
347        fs.write("\n# You can use sim.set_dist_file to customize the final file name")
348        fs.write("\n# You can use PostProcessing.radiance2brf to convert radiance image to BRF image")
349        fs.write("""\n# When you want to do batch-processing by changing optical properties and sun/obs geometries,
350# you can use sim.enable_runtime_modification_of_properties(True), 
351# and then modify the optical properties in a loop to do simulation, which avoids the reload of the 
352# obj files to save overall time. Please refer to Ex07 in the pyLessSDK folder for more details""")
353        fs.write("""\nsim.save_sim_project()""")
354        fs.write("""\nsim.start()\n""")
355
356        fs.close()