Running cascaded pipelines in script
Disclaimer: The code in this post is written on version 10.2.101000.0 of Simplygon. Should you encounter this post running a different version, some of the API calls might differ. However, the core concepts should still remain valid.
Introduction
Many scripted Simplygon workflows start with a pipeline that is exported from one of our integrations. In this post will give you a very straight forward step-by-step that shows how to create a scripted optimization with cascaded pipelines.
1. Export a cascaded pipeline
We will export a simple three step LOD chain where each step is a 50% reduction from the previous step. After that we will save the file as 3LODs.json in the folder where will develop our script. For instructions on how to use the UI in Maya you can look at Getting started - UI in our documentation.
We will also create a simple sphere in Maya as test asset and export that into sphere.fbx in the same directory.
2. Create the template script
We'll create Python file called cascaded_pipeline.py. As always in our posts we use this template to start our script:
from simplygon10 import simplygon_loader
from simplygon10 import Simplygon
def process_file(sg, pipeline_file, asset_file):
def main():
sg = simplygon_loader.init_simplygon()
print(sg.GetVersion())
process_file(sg, "3LODs.json", "sphere.fbx")
del sg
if __name__== "__main__":
main()
3. Load the pipeline
Let's start by loading the pipeline in the process_file function. This code will do the trick:
pipeline_serializer = sg.CreatePipelineSerializer()
pipeline = pipeline_serializer.LoadPipelineFromFile(pipeline_file)
Here's the documentation about PipelineSerializer.
4. Run the pipeline
There is a function called RunSceneFromFile which is really helpful when we're running a single optimization process. For cascaded pipelines we need to decide on how to output the results, so we will be using RunScene instead. Before we can call that function we need to load the asset into a scene. This can be done with the help of a SceneImporter. Let's add the code:
importer = sg.CreateSceneImporter()
importer.SetImportFilePath(asset_file)
if importer.RunImport():
scene = importer.GetScene()
pipeline.RunScene(scene, Simplygon.EPipelineRunMode_RunInThisProcess)
This is enough to try the script out, but we still need to export the results.
4. Exporting the results
Now we can export the results into separate files. We do this by looping through the cascaded pipelines and export the results from each of the sub pipelines. Let's create the exporting function like this:
def export_output(sg, pipeline, base_name, LOD_index):
exporter = sg.CreateSceneExporter()
exporter.SetScene(pipeline.GetProcessedScene())
exporter.SetExportFilePath( '%s_LOD%s.fbx' % (base_name, LOD_index) )
exporter.RunExport()
for i in range(0, pipeline.GetCascadedPipelineCount()):
export_output(sg, pipeline.GetCascadedPipelineByIndex(i), base_name, LOD_index+1)
In this code we use the Graphics Exporter to export the output (using GetProcessedScene) from the first pipeline. Then we loop through all the child pipelines using GetCascadedPipelineCount and GetCascadedPipelineByIndex. In our case the pipeline is pretty much a list, but you can create pipelines so that they are trees. This could be useful if you want to create several different types of LOD chains for you assets, for example when targeting several different platforms.
Just one thing remains. To call export_output after the processing. Let's just add this line at the bottom of process_file.
export_output(sg, pipeline, asset_file.split('.')[0], 1)
The script
Here is the complete script.
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
from simplygon10 import simplygon_loader
from simplygon10 import Simplygon
def export_output(sg, pipeline, base_name, LOD_index):
exporter = sg.CreateSceneExporter()
exporter.SetScene(pipeline.GetProcessedScene())
export_path = '%s_LOD%s.fbx' % (base_name, LOD_index)
print(export_path)
exporter.SetExportFilePath( export_path )
exporter.Run()
for i in range(0, pipeline.GetCascadedPipelineCount()):
export_output(sg, pipeline.GetCascadedPipelineByIndex(i), base_name, LOD_index+1)
def process_file(sg, pipeline_file, asset_file):
pipeline_serializer = sg.CreatePipelineSerializer()
pipeline = pipeline_serializer.LoadPipelineFromFile(pipeline_file)
importer = sg.CreateSceneImporter()
importer.SetImportFilePath(asset_file)
importer.Run()
scene = importer.GetScene()
pipeline.RunScene(scene, Simplygon.EPipelineRunMode_RunInThisProcess)
export_output(sg, pipeline, asset_file.split('.')[0], 1)
def main():
sg = simplygon_loader.init_simplygon()
print(sg.GetVersion())
process_file(sg, "3LODs.json", "sphere.fbx")
del sg
if __name__== "__main__":
main()