Skip to content
On this page

Simplygon Pipeline functions

The Simplygon Max plug-in exports a number of global MaxScript / Python functions. The following sections lists Simplygon Pipeline functions and examples, general Simplygon functions and Simplygon Shading Network functions are listed separately. It is recommended to read Pipeline concepts before proceeding.

Supported Pipelines

Pipeline (API)ComponentsLevel of supportDescription
ReductionPipelineReductionProcessor
MaterialCaster
Almost completeReduces the geometries
Possibility to maintain original materials
Possibility to bake materials
AggregationPipelineAggregationProcessor
MaterialCaster
Almost completeAggregates / combines geometries
Possibility to maintain original materials
Possibility to bake materials
RemeshingPipelineRemeshingProcessor
MaterialCaster
Almost completeCreates a replacement geometry
Can not preserve original materials
Possibility to bake materials
BillboardCloudPipelineImpostorProcessor
MaterialCaster
GoodCreates multiple static billboards (outer shell)
Possibility to bake materials
BillboardCloudVegetationPipelineImpostorProcessor
MaterialCaster
GoodCreates multiple static billboards (within volume) within a threshold
Can maintain original material in certain areas
Possibility to bake materials
FlipbookPipelineImpostorProcessor
MaterialCaster
PendingCreates a single replacement billboard to be used from multiple directions
Possibility to bake materials
ImpostorFromSingleViewPipelineImpostorProcessor
MaterialCaster
Almost completeCreates a single replacement billboard to be used from a specific view direction
Possibility to bake materials
PassthroughPipelineAlmost completeThis pipeline itself does not generate any result, but allows the user to add other pipelines as children (cascaded pipelines). All first level children of this node will be based on the same input.

Script functions

FunctionParameter(s)Description
sgsdk_RunPipelineOnSelectionint pipelineHandleOptimizes the selected asset(s) based on the pipeline object.
sgsdk_RunPipelineOnSelectionstring pipelineFilePathOptimizes the selected asset(s) based on the pipeline file.
sgsdk_RunPipelineOnFileint pipelineHandle
string inputFilePath
string outputFilePath
Optimizes the asset(s) in the specified input file and stores the result in the output file. The output file will get indexed if the Pipeline specifies a LOD chain, use sgsdk_GetProcessedOutputPaths to get the correct paths.
sgsdk_RunPipelineOnFilestring pipelineFilePath
string inputFilePath
string outputFilePath
Optimizes the asset(s) in the specified input file and stores the result in the output file. The output file will get indexed if the Pipeline specifies a LOD chain, use sgsdk_GetProcessedOutputPaths to get the correct paths.
sgsdk_CreatePipelinestring pipelineTypeCreates a pipeline of the specified type.
(see supported pipelines))
sgsdk_DeletePipelineint pipelineIdDeletes the pipeline.
(created by sgsdk_CreatePipeline or sgsdk_LoadPipeline).
sgsdk_ClonePipelineint pipelineIdClones the pipeline.
(created by sgsdk_CreatePipeline or sgsdk_LoadPipeline).
sgsdk_ClearPipelines<none>Clears all pipelines that are currently loaded.
(created by sgsdk_CreatePipeline or sgsdk_LoadPipeline).
sgsdk_LoadPipelinestring inputPathLoads a pipeline-file.
sgsdk_SavePipelineint pipelineId
string outputPath
Saves pipeline to file.
(created by sgsdk_CreatePipeline or sgsdk_LoadPipeline).
sgsdk_SetSettingint pipelineId
string parameterPath
<T> parameterValue
Sets the value of the specified pipeline parameter.
(string, bool, int, double, float)
sgsdk_GetSettingint pipelineId
string parameterPath
Gets the value of the specified pipeline parameter.
sgsdk_GetPipelineTypeint pipelineIdGets the type of the specified pipeline.
(ReductionPipeline, AggregationPipeline, RemeshingPipeline, ...)
sgsdk_GetPipelines<none>Gets all pipeline ids that are currently loaded.
(created from sgsdk_CreatePipeline or sgsdk_LoadPipeline).
sgsdk_AddMaterialCasterint pipelineId
string materialCasterType
Adds a material-caster to the specified pipeline.
(ColorCaster, NormalCaster, ...)
sgsdk_AddCascadedPipelineint pipelineId
int pipelineToAdd
Adds a cascaded pipeline to the specified pipeline.
sgsdk_SetPipelineRunModeint runModeRunInThisProcess = 0
RunInNewProcess = 1 (default)
RunDistributedUsingSimplygonGrid = 2
RunDistributedUsingIncredibuild = 3

IMPORTANT NOTE - MAPPING CHANNELS

Mapping channel indices in Max are not directly translatable to texture coordinate- and vertex color indices in Simplygon.

Simplygon stores vertex colors and texture coordinates in separate lists with individual indices (starting from 0). Passing a mapping channel index to Simplygon will most likely result weird results (incorrect field is getting used) or in an error message that states that the specified field does not exist. Negative mapping channel indices as for Alpha (-2) and Illumination (-1) will not be accepted by Simplygon.

We recommend using *Name settings instead of the *Level settings as they are not sensitive to the physical order of the fields and therefor not as prone for errors. Each exported mapping channel gets the "name" of the original mapping channel index, that applies to negative mapping channels as well.

Correct: TexCoordName = "1"

Incorrect: TexCoordLevel = 1

Examples

This section contains various Pipeline examples written in MaxScript and Python. We've left out some parts of the scripts to keep things as simple as possible.

  • from pymxs import runtime as rt must be declared at the top of each Python script.
  • reductionPipeline settings-path must be declared for both MaxScript and Python scripts where it makes sense.
  • a scene-selection is made before each sgsdk_RunPipelineOnSelection.

Create a Pipeline object

Creates a ReductionPipeline, see supported pipelines for more information.

MaxScript
reductionPipeline = sgsdk_CreatePipeline "ReductionPipeline"
python
from pymxs import runtime as rt

reductionPipeline = rt.sgsdk_CreatePipeline('ReductionPipeline')

Load / save a Pipeline object

Loads a Pipeline object from file and then saves it.

Note: Pipeline files should only be used as intermediate and are not intended to be used as presets or templates. Pipeline files are not guaranteed to be compatible with different versions of Simplygon. It is recommended to script Pipelines that saves out Pipeline files rather than loading Pipelines from file.

MaxScript
reductionPipeline = sgsdk_LoadPipeline "D:/Pipelines/reductionPipeline.json"
    sgsdk_SavePipeline reductionPipeline "D:/Pipelines/reductionPipeline.json"
python
from pymxs import runtime as rt

reductionPipeline = rt.sgsdk_LoadPipeline('D:/Pipelines/reductionPipeline.json')
rt.sgsdk_SavePipeline(reductionPipeline, 'D:/Pipelines/reductionPipeline.json')

Clone a Pipeline object

Clones an existing Pipeline object.

MaxScript
reductionPipeline = sgsdk_LoadPipeline "D:/Pipelines/reductionPipeline.json"
    clonedReductionPipeline = sgsdk_ClonePipeline reductionPipeline
python
from pymxs import runtime as rt

reductionPipeline = rt.sgsdk_LoadPipeline('D:/Pipelines/reductionPipeline.json')
clonedReductionPipeline = rt.sgsdk_ClonePipeline(reductionPipeline)

Get / Set Pipeline settings

Pipelines can be created by calling sgsdk_CreatePipeline with the type of the pipeline as argument. A Pipeline contains settings which reflects the settings for the specific Processor in the Simplygon API. A ReductionPipeline contains a ReductionProcessor which contain ReductionSettings.

MaterialCaster is a separate object resides inside Pipelines The MaterialCaster object contains settings for material baking.

To set a reduction setting for a ReductionPipeline, let's say ReductionTargetTriangleRatio, we will have to pinpoint the path to the specific setting. sgsdk_SetSetting is function we use to work with settings. The first input is the Pipeline-object, the second is the settings-path and the third is the value we want to set. Fetching a value of a setting works the same way, except that it returns the value of the given settings-path instead of setting it, the function for fetching a settings value is sgsdk_GetSetting.

A settings-path can start with a Processor, MaterialCaster, or any other first level object depending on the Pipeline. In this case we want to set a setting in the ReductionProcessor, which is the first part of the path, the second part is the settings-object which in this case is ReductionSettings. And at last, the parameter we want to set is named ReductionTargetTriangleRatio. Let's set the value of ReductionTargetTriangleRatio to 50% (0.5).

MaxScript
-- sets the ReductionTargetTriangleRatio for the given ReductionPipeline
    bResult = sgsdk_SetSetting reductionPipeline "ReductionProcessor/ReductionSettings/ReductionTargetTriangleRatio" 0.5

    -- gets the ReductionTargetTriangleRatio from the given ReductionPipeline
    reductionTargetTriangleRatio = sgsdk_GetSetting reductionPipeline "ReductionProcessor/ReductionSettings/ReductionTargetTriangleRatio"
python
from pymxs import runtime as rt

# sets the ReductionTargetTriangleRatio for the given ReductionPipeline
bResult = rt.sgsdk_SetSetting(reductionPipeline,'ReductionProcessorReductionSettings/ReductionTargetTriangleRatio', 0.5)

# gets the ReductionTargetTriangleRatio from the given ReductionPipeline
reductionTargetTriangleRatio = rt.sgsdk_GetSetting(reductionPipeline, 'ReductionProcessor/ReductionSettings/ReductionTargetTriangleRatio')

The same goes for TextureWidth and TextureHeight, which are part of the MappingImage settings-object. In most cases we only use one mapping image, thus Output0 which is allocated by default. Let's set them to 512x512 pixels.

MaxScript
-- sets the texture-width for the given ReductionPipeline
    bResult = sgsdk_SetSetting reductionPipeline "ReductionProcessor/MappingImageSettings/Output0/TextureWidth" 512 

    -- gets the texture-width for the given ReductionPipeline
    textureWidth = sgsdk_GetSetting reductionPipeline "ReductionProcessor/MappingImageSettings/Output0/TextureWidth"

    -- sets the texture-height for the given ReductionPipeline
    bResult = sgsdk_SetSetting reductionPipeline "ReductionProcessor/MappingImageSettings/Output0/TextureHeight" 512

    -- gets the texture-height for the given ReductionPipeline
    textureHeight = sgsdk_GetSetting reductionPipeline "ReductionProcessor/MappingImageSettings/Output0/TextureHeight"
python
from pymxs import runtime as rt

# sets the texture-width for the given ReductionPipeline
bResult = rt.sgsdk_SetSetting(reductionPipeline, 'ReductionProcessorMappingImageSettings/Output0/TextureWidth', 512)

# gets the texture-width for the given ReductionPipeline
textureWidth = rt.sgsdk_GetSetting(reductionPipeline, 'ReductionProcessorMappingImageSettings/Output0/TextureWidth')

# sets the texture-height for the given ReductionPipeline
bResult = rt.sgsdk_SetSetting(reductionPipeline, 'ReductionProcessorMappingImageSettings/Output0/TextureHeight', 512)

# gets the texture-height for the given ReductionPipeline
textureHeight = rt.sgsdk_GetSetting(reductionPipeline, 'ReductionProcessorMappingImageSettings/Output0/TextureHeight')

For material baking the initial object is MaterialCaster, and as there aren't any casters by default they will have to be created with sgsdk_AddMaterialCaster. There after we can use the index and settings of the caster to access its parameters.

Note: The material channels for the MaterialCaster in this example are intended for standard materials in Max such as Blinn and Phong, and might not work for other materials. Additional channels such as opacity can be added for baking, for Opacity the OpacityCaster is recommended (for correct baking of transparent surfaces).

MaxScript
-- add a ColorCaster to the given ReductionPipeline
    bCasterAdded = sgsdk_AddMaterialCaster reductionPipeline "ColorCaster"

    -- set the MaterialChannel to "Diffuse_Color" for the given ColorCaster
    bResult = sgsdk_SetSetting reductionPipeline "MaterialCaster/0/ColorCasterSettings/MaterialChannel" "Diffuse_Color"

    -- get the MaterialChannel for the given ColorCaster
    colorCaster0 = sgsdk_GetSetting reductionPipeline "MaterialCaster/0/ColorCasterSettings/MaterialChannel"

    -- add a NormalCaster to the given ReductionPipeline
    bCasterAdded = sgsdk_AddMaterialCaster reductionPipeline "NormalCaster"

    -- set the MaterialChannel to "Bump" for the given NormalCaster
    bResult = sgsdk_SetSetting reductionPipeline "MaterialCaster/1/NormalCasterSettings/MaterialChannel" "Bump"

    -- get the MaterialChannel for the given NormalCaster
    normalCaster1 = sgsdk_GetSetting reductionPipeline "MaterialCaster/1/NormalCasterSettings/MaterialChannel"

    -- set the tangent-space flag for the given NormalCaster
    bResult = sgsdk_SetSetting reductionPipeline "MaterialCaster/1/NormalCasterSettings/GenerateTangentSpaceNormals" true

    -- get the tangent-space flag for the given NormalCaster
    generateTangentSpaceNormals = sgsdk_GetSetting reductionPipeline "MaterialCaster/1/NormalCasterSettings/GenerateTangentSpaceNormals"
python
from pymxs import runtime as rt

# add a ColorCaster to the given ReductionPipeline
bCasterAdded = rt.sgsdk_AddMaterialCaster(reductionPipeline, 'ColorCaster')

# set the MaterialChannel to 'Diffuse_Color' for the given ColorCaster
bResult = rt.sgsdk_SetSetting(reductionPipeline, 'MaterialCaster/0/ColorCasterSettings/MaterialChannel', 'Diffuse_Color')

# get the MaterialChannel for the given ColorCaster
colorCaster0 = rt.sgsdk_GetSetting(reductionPipeline, 'MaterialCaster/0/ColorCasterSettings/MaterialChannel')

# add a NormalCaster to the given ReductionPipeline
bCasterAdded = rt.sgsdk_AddMaterialCaster(reductionPipeline, 'NormalCaster')

# set the MaterialChannel to 'Bump' for the given NormalCaster
bResult = rt.sgsdk_SetSetting(reductionPipeline, 'MaterialCaster/1/NormalCasterSettings/MaterialChannel', 'Bump')

# get the MaterialChannel for the given NormalCaster
normalCaster1 = rt.sgsdk_GetSetting(reductionPipeline, 'MaterialCaster/1/NormalCasterSettings/MaterialChannel')

# set the tangent-space flag for the given NormalCaster
bResult = rt.sgsdk_SetSetting(reductionPipeline, 'MaterialCaster/1/NormalCasterSettings/GenerateTangentSpaceNormals', True)

# get the tangent-space flag for the given NormalCaster
generateTangentSpaceNormals = rt.sgsdk_GetSetting(reductionPipeline, 'MaterialCaster/1/NormalCasterSettings/GenerateTangentSpaceNormals')

Cascaded Pipelines (LOD-chain)

Cascaded pipelines means that each LOD is based on the previous LOD, instead of the original asset which is the standard behavior. In this example we will load two pipelines, one with reduction (LOD1) and one with reduction and baking (LOD2). LOD1 will be based on the original asset and LOD2 will be based on LOD1.

If cascaded pipelines are used in combination with processing from/to file the output scene names will be appended with "_LOD" prefix and then indexed from 1 to *, where the index increments for each cascaded level. The output texture folder for each cascaded scene will be "Textures/LOD1" for LOD1, "Textures/LOD2" for LOD2 and so on. The output file names can be fetched with GetProcessedOutputPaths (gpp) which can then be used at import.

Creates cascaded Pipelines.

MaxScript
-- loads two different pipelines
    reductionPipeline = sgsdk_LoadPipeline "D:/Pipelines/reductionPipeline.json"
    reductionPipelineWithBaking = sgsdk_LoadPipeline "D:/Pipelines/reductionPipelineWithBaking.json"

    -- adds reduction with baking as cascaded pipeline using AddCascadedPipeline
    bResult = sgsdk_AddCascadedPipeline reductionPipeline reductionPipelineWithBaking

    -- save new cascaded pipeline to disk
    bResult = sgsdk_SavePipeline reductionPipeline "D:/Pipelines/cascadedReductionPipeline.json"
python
from pymxs import runtime as rt

# loads two different pipelines
reductionPipeline = rt.sgsdk_LoadPipeline('D:/Pipelines/reductionPipeline.json')
reductionPipelineWithBaking = rt.sgsdk_LoadPipeline('D:/Pipelines/reductionPipelineWithBaking.json')

# adds reduction with baking as cascaded pipeline using AddCascadedPipeline
bResult = rt.sgsdk_AddCascadedPipeline(reductionPipeline, reductionPipelineWithBaking)

# save new cascaded pipeline to disk
bResult = sgsdk_SavePipeline(reductionPipeline, 'D:/Pipelines/cascadedReductionPipeline.json')

Multiple LODs based on the same source (using PassthroughPipeline)

Generating multiple LODs that are based on the same source can be achieved quite easily. The first (and most commonly used method) is to simply run Simplygon multiple times on the same asset, but there is always some amount of overhead transfering data back and forth.

Another more efficient way is to set up cascaded pipelines and generate all LODs in one single call. This can be achieved using the PassthroughPipeline which purpose is to offer the user to hook up multiple child pipelines to one single source, the PassthroughPipeline itself does not generate any result. All first level children of the PassthroughPipeline will be based on the same input source.

MaxScript
-- create a passthrough pipeline
    passthroughPipelineId = sgsdk_CreatePipeline "PassthroughPipeline"
    
    -- create a reduction pipeline and set target triangle ratio to 50%
    reductionPipelineId_1 = sgsdk_CreatePipeline "ReductionPipeline"
    sgsdk_SetSetting reductionPipelineId_1 "ReductionProcessor/ReductionSettings/ReductionTargetTriangleRatio" 0.50
    
    -- create a second reduction pipeline and set target triangle ratio to 25%
    reductionPipelineId_2 = sgsdk_CreatePipeline "ReductionPipeline"
    sgsdk_SetSetting reductionPipelineId_2 "ReductionProcessor/ReductionSettings/ReductionTargetTriangleRatio" 0.25
    
    -- hook reduction pipelines up to passthrough pipeline,
    -- note: both results will be based on original asset!
    sgsdk_AddCascadedPipeline passthroughPipelineId reductionPipelineId_1
    sgsdk_AddCascadedPipeline passthroughPipelineId reductionPipelineId_2
    
    -- run Simplygon
    sgsdk_SetMeshNameFormat "{MeshName}_LOD{LODIndex}" 
    sgsdk_RunPipelineOnSelection passthroughPipelineId
python
from pymxs import runtime as rt

# create a passthrough pipeline
passthroughPipelineId = rt.sgsdk_CreatePipeline('PassthroughPipeline')

# create a reduction pipeline and set target triangle ratio to 50%
reductionPipelineId_1 = rt.sgsdk_CreatePipeline('ReductionPipeline')
rt.sgsdk_SetSetting(reductionPipelineId_1, 'ReductionProcessor/ReductionSettings/ReductionTargetTriangleRatio', 0.50)

# create a second reduction pipeline and set target triangle ratio to 25%
reductionPipelineId_2 = rt.sgsdk_CreatePipeline('ReductionPipeline')
rt.sgsdk_SetSetting(reductionPipelineId_2, 'ReductionProcessor/ReductionSettings/ReductionTargetTriangleRatio', 0.25)

# hook reduction pipelines up to passthrough pipeline,
# note: both results will be based on original asset!
rt.sgsdk_AddCascadedPipeline(passthroughPipelineId, reductionPipelineId_1)
rt.sgsdk_AddCascadedPipeline(passthroughPipelineId, reductionPipelineId_2)

# run Simplygon
rt.sgsdk_SetMeshNameFormat('{MeshName}_LOD{LODIndex}')
rt.sgsdk_RunPipelineOnSelection(passthroughPipelineId)

# clear all Pipelines that resides in memory
rt.sgsdk_ClearPipelines()

More about pipelines

For more information about Pipelines, visit the links below.