# 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 RunAggregation(sg: Simplygon.ISimplygon):
    sgSceneImporter = sg.CreateSceneImporter()
    sgSceneImporter.SetImportFilePath( "../Assets/ObscuredTeapot/ObscuredTeapot.obj" )
    if not sgSceneImporter.RunImport():
        raise Exception("Failed to load ObscuredTeapot/ObscuredTeapot.obj.")
    sgScene = sgSceneImporter.GetScene()

    # Create the aggregation processor. 
    sgAggregationProcessor = sg.CreateAggregationProcessor()

    sgAggregationProcessor.SetScene( sgScene )

    sgAggregationSettings = sgAggregationProcessor.GetAggregationSettings()
    sgVisibilitySettings = sgAggregationProcessor.GetVisibilitySettings()

    # Merge all geometries into a single geometry. 
    sgAggregationSettings.SetMergeGeometries( True )

    # Add a selection set to the scene. We'll use this later as a occluder. 
    sgSceneSelectionSetTable = sgScene.GetSelectionSetTable()
    sgOccluderSelectionSet = sg.CreateSelectionSet()
    sgOccluderSelectionSet.SetName("Occluder")
    sgRootBox002 = sgScene.GetNodeFromPath("Root/Box002")
    if sgRootBox002 is not None:
        sgOccluderSelectionSet.AddItem(sgRootBox002.GetNodeGUID())
    sgSceneSelectionSetTable.AddSelectionSet(sgOccluderSelectionSet)

    # Use the occluder previously added. 
    sgVisibilitySettings.SetOccluderSelectionSetName( "Occluder" )

    # 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 aggregation process. 
    sgAggregationProcessor.RunProcessing()

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


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

    RunAggregation(sg)

    sg = None
    gc.collect()

