# Initialize and deinitialize API

This section provides an overview of how to get started with Simplygon APIs.

# C++ API

The Simplygon API loader provides an initialization function that must be run before any class in the API can be used. The initialization function creates a variable with the ISimplygon interface, which is used to create other API objects. All the return values of the initialization function are listed in the API reference for the function.

The deinitialization function must be called after all the Simplygon objects have been deallocated, i.e all smart pointers must have gone out of scope, including global pointers.

ISimplygon * sg = nullptr;

// Initialize the SDK
Simplygon::EErrorCodes initVal = Simplygon::Initialize( &sg );

// Make sure the SDK initialized correctly
if( initVal != Simplygon::EErrorCodes::NoError )
{
    // Failed to initialize, check the error message
}

// Do some processing using the SDK. Do not put smart pointers in the same scope as
// the Deinitialize call, or you must explicitly set them to null before Deinitialize
// is called. The easiest way to ensure this is to put the processing in a separate function

// Deinitialize the SDK
Simplygon::Deinitialize( sg );

The loader will by default look for the Simplygon DLL in the following directories, in order:

  • Custom paths set with Simplygon::AddSearchPath function
  • Current working directory
  • Calling process executable directory
  • Path given by the SIMPLYGON_9_PATH environment variable, which is created by the installer if it does not already exist.

# Python API

Simplygon installer installs a helper Simplygon loader Python module called simplygon_loader to the version specific site-packages directories in %appdata%\Python.

This loader module has one method; init_simplygon().

init_simplygon() method takes two optional arguments: simplygon_dll_path, which allows the user to pass the full path to the Simplygon DLL and license_data that can be used to pass license file data.

IMPORTANT NOTE

When using the Simplygon Python API, it is important to note that the garbage collector needs to be controlled explicitly to gain full control over Simplygon's deinitialization. Use import gc and run gc.collect() explicitly after assigning None to the sg variable like in the example below to be 100% sure that Simplygon can be successfully deinitialized.

from simplygon import simplygon_loader
from simplygon import Simplygon
import gc

def do_something(sg):
    # Do some processing using the SDK
    pass

# Initialize the SDK
sg = simplygon_loader.init_simplygon()

# Check if we got an error (sg is None) before continuing
if sg is None:
    # An error occured
    error = Simplygon.GetLastInitializationError()
    error_string = Simplygon.GetErrorString(error)
    sys.stderr.write('Initialization failed! {} (error {})\n'.format(error_string, error))
    # The printout above is also done internally by simplygon_loader
    # The code here is just an example on how to get information about the error

# Due to garbage collection in Python it's important that there is no Simplygon
# data that is allocated/deallocated in the same scope as the the deinitialization
# of Simplygon.
do_something(sg)

# To deinitialize Simplygon explicitly, assign None to the sg variable and then call
# Python's gc.collect() method to force a garbage collection pass
sg = None
gc.collect()

# C# API

Initialization of C# API is done calling InitSimplygon() method available in Loader class in Simplygon namespace that takes two out parameters that provides error information in case initialization fails and InitSimplygon() method returns null. The Simplygon.Loader class can be found at SIMPLYGON_9_PATH\DotNet.

Deinitialization is not needed since initialized variable will be garbage collected when it goes out of scope, hence defining scope with using in the example below.

using (ISimplygon sg = Simplygon.Loader.InitSimplygon(out simplygonErrorCode, out simplygonErrorMessage))
{
    if (simplygonErrorCode == Simplygon.EErrorCodes.NoError)
    {
        // ... do some processing using the simplygon
    }
    else 
    {
        // ...check error code out parameter simplygonErrorCode and out error message parameter simplygonErrorMessage
    }
}

# Threading

If you use Simplygon in multiple threads (for example an async call or a worker thread in a thread pool) where the lifetime of the thread is unknown, the thread termination might occur at the same time as the Simplygon DLL is being unloaded. This will cause issues when the cleanup destructors call into the DLL while it is being torn down. To mitigate this you can call the thread deinitialization explicitly when you are done using the Simplygon SDK in your threads or async calls.