# Copyright (c) Microsoft Corporation. 
# Licensed under the MIT license. 

import math
import os
import sys
import glob
import gc
import threading

from pathlib import Path
from simplygon import simplygon_loader
from simplygon import Simplygon


def RunReduction(sg: Simplygon.ISimplygon):
    sgSceneImporter = sg.CreateSceneImporter()
    sgSceneImporter.SetImportFilePath( "../Assets/ObscuredTeapot/Teapot.obj" )
    if not sgSceneImporter.RunImport():
        raise Exception("Failed to load ObscuredTeapot/Teapot.obj.")
    sgScene = sgSceneImporter.GetScene()

    # Create the reduction pipeline. 
    sgReductionPipeline = sg.CreateReductionPipeline()

    sgReductionSettings = sgReductionPipeline.GetReductionSettings()
    sgVisibilitySettings = sgReductionPipeline.GetVisibilitySettings()

    # Set reduction target to triangle ratio with a ratio of 50%. 
    sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition_All, True, False, False, False )
    sgReductionSettings.SetReductionTargetTriangleRatio( 0.5 )

    # Add a camera to the scene. We'll use this later as a visibility camera. 
    sgSceneSelectionSetTable = sgScene.GetSelectionSetTable()
    sgCameraSelectionSet = sg.CreateSelectionSet()
    sgCameraSelectionSet.SetName("Camera")
    sgCameraSceneCamera = sg.CreateSceneCamera()
    sgCameraSceneCamera.SetCustomSphereCameraPath(4, 90, 180, 90)
    sgScene.GetRootNode().AddChild(sgCameraSceneCamera)
    sgCameraSelectionSet.AddItem(sgCameraSceneCamera.GetNodeGUID())
    sgSceneSelectionSetTable.AddSelectionSet(sgCameraSelectionSet)

    # Use the camera previously added. 
    sgVisibilitySettings.SetCameraSelectionSetName( "Camera" )

    # Enabled GPU based visibility calculations. 
    sgVisibilitySettings.SetComputeVisibilityMode( Simplygon.EComputeVisibilityMode_DirectX )

    # Disabled conservative mode. 
    sgVisibilitySettings.SetConservativeMode( False )

    # Remove all non visible geometry. 
    sgVisibilitySettings.SetCullOccludedGeometry( True )

    # Skip filling nonvisible regions. 
    sgVisibilitySettings.SetFillNonVisibleAreaThreshold( 0.0 )

    # Don't remove non occluding triangles. 
    sgVisibilitySettings.SetRemoveTrianglesNotOccludingOtherTriangles( False )

    # Remove all back facing triangles. 
    sgVisibilitySettings.SetUseBackfaceCulling( True )

    # Don't use visibility weights. 
    sgVisibilitySettings.SetUseVisibilityWeightsInReducer( False )

    # Start the reduction pipeline. 
    sgReductionPipeline.RunScene(sgScene, Simplygon.EPipelineRunMode_RunInThisProcess)

    # Get the processed scene. 
    sgProcessedScene = sgReductionPipeline.GetProcessedScene()

    sgSceneExporter = sg.CreateSceneExporter()
    sgSceneExporter.SetScene(sgProcessedScene)
    sgSceneExporter.SetExportFilePath( "ReductionOutput.fbx" )
    if not sgSceneExporter.RunExport():
        raise Exception("Failed to save ReductionOutput.fbx.")


if __name__ == '__main__':
    sg = simplygon_loader.init_simplygon()

    RunReduction(sg)

    sg = None
    gc.collect()

