# Simple reduction - Simplygon Python API

This section includes an example of how to use the Simplygon Python API to optimize the scene. Note that some of these API examples can be done using Pipelines, if some features are not exposed in Pipelines or that some custom behavior is required then Simplygon API is the way to go.

The first part exports the selected Maya scene to file. The second part sets up a reduction processor and optimizes the previously saved scene. The third part imports the processed scene back into Maya. The export and import could be done manually if preferred.

import maya.cmds as cmds
from simplygon import simplygon_loader
from simplygon import Simplygon
import gc

def reduce_exported_scene(sg):
    # Set Maya's handedness setting
    sg.SetGlobalDefaultTangentCalculatorTypeSetting(Simplygon.ETangentSpaceMethod_OrthonormalRightHanded)

    # Load the scene from file
    lodScene = sg.CreateScene()
    lodScene.LoadFromFile('D:/Assets/ExportedScene.sb')

    # Create the reduction-processor, and set which scene to reduce
    reductionProcessor = sg.CreateReductionProcessor()
    reductionProcessor.SetScene(lodScene)

    # The reduction settings object contains settings pertaining to the actual decimation
    reductionSettings = reductionProcessor.GetReductionSettings()

    # Try, when possible to reduce symmetrically
    reductionSettings.SetKeepSymmetry(True)

    # Auto-detect the symmetry plane, if one exists. Can, if required, be set manually instead
    reductionSettings.SetUseAutomaticSymmetryDetection(True)

    # Drastically increases the quality of the LODs normals, at the cost of extra processing time
    reductionSettings.SetUseHighQualityNormalCalculation(True)

    # Choose between "fast" and "consistent" processing
    reductionSettings.SetReductionHeuristics(Simplygon.EReductionHeuristics_Consistent)

    # The reduction stops when any of the targets below is reached
    reductionSettings.SetReductionTargetStopCondition(Simplygon.EStopCondition_Any)

    # Selects which targets should be considered when reducing
    reductionSettings.SetReductionTargetTriangleRatioEnabled(True)
    reductionSettings.SetReductionTargetTriangleCountEnabled(True)
    reductionSettings.SetReductionTargetMaxDeviationEnabled(True)
    reductionSettings.SetReductionTargetOnScreenSizeEnabled(True)

    # Targets at 50% of the original triangle count
    reductionSettings.SetReductionTargetTriangleRatio(0.5)

    # Targets when only 10 triangle remains
    reductionSettings.SetReductionTargetTriangleCount(10)

    # Targets when an error of the specified size has been reached. As set here it never happens
    reductionSettings.SetReductionTargetMaxDeviation(1e27)

    # Targets when the LOD is optimized for the selected on screen pixel size
    reductionSettings.SetReductionTargetOnScreenSize(50)

    # The repair settings object contains settings to fix the geometries
    repairSettings = reductionProcessor.GetRepairSettings()
    repairSettings.SetTJuncDist(0.0)  # Removes t-junctions with distance 0.0f
    repairSettings.SetWeldDist(0.0)  # Welds overlapping vertices

    # The normal calculation settings deal with the normal-specific reduction settings
    normalSettings = reductionProcessor.GetNormalCalculationSettings()

    # If True, this will turn off normal handling in the reducer and recalculate them all
    # afterwards instead.
    normalSettings.SetReplaceNormals(False)

    # Run the actual processing.
    # After this, the set geometry will have been reduced according to the settings
    reductionProcessor.RunProcessing()

    # Save the processed scene to file
    lodScene.SaveToFile('D:/Assets/ProcessedScene.sb')


# Load Maya scene
cmds.file(f=True, new=True)
cmds.file('D:/Assets/MyScene.fbx', i=True, mergeNamespacesOnClash=True,
          namespace=':', importFrameRate=True)

# Clear previous export mapping
bResult = cmds.Simplygon(cgm=True)

# Select all objects
cmds.select(all=True)

# Export scene to file
bResult = cmds.Simplygon(exp='D:/Assets/ExportedScene.sb', cte=False)

# Initialize Simplygon
sg = simplygon_loader.init_simplygon()

# reduce exported scene
reduce_exported_scene(sg)

# Import processed file into Maya, LOD-index = 1, CopyTextures = False, LinkMaterials = True
bResult = cmds.Simplygon(imp='D:/Assets/ProcessedScene.sb',
                         cte=False, lma=True, mnf="My_{MeshName}_LOD{LODIndex}", ili=1)

# De-initialize Simplygon
sg = None
gc.collect()