Using the API

<< Click to Display Table of Contents >>

Navigation:  Simplygon API 7.1 User guide >

Using the API

Simplygon provides a C++ interface for integration into projects. This section provides an overview of how to use the API together with common development environments and explains the important concepts in the API. In all the following examples, the sg variable is assumed to be a global pointer to the Simplygon API object.

 

Header and library files

The Simplygon library header and library files are located in the Simplygon API installation directory. The full interface of the Simplygon API is defined in the header file SimplygonSDK.h. Any source file that uses the API should include this file. The actual code of the Simplygon API is implemented as a shared library (.dll, .so on Linux), and has to be loaded at run time. For ease of use, the SimplygonSDKLoader.cpp source file is included. This file implements example loading and initialization, and should be compiled into the application which is using the Simplygon API. The SimplygonSDKLoader.cpp source may be customized to the users specific needs, such as locating the shared library using different registry settings, or environment variables of the user application. The header file SimplygonSDKLoader.h defines the interface of the loader, and also includes the SimplygonSDK.h header file by default.

 

Dependencies

When Simplygon is installed, the required dependencies are installed along with it. If a machine is using the Simplygon DLL without having run the setup, it will need the required dependencies:

Visual C++ 2015 redistributable

DirectX redistributable

 

Initializing and deinitializing the API

The API provides an initialization function that must be run before any class in the API can be used. The initialization function creates a pointer to a ISimplygonSDK 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.

 

Example

The following code demonstrates how to initialize and deinitialize the API.

 
ISimplygonSDK * sg = 0;
// initialize the SDK
int retval = SimplygonSDK::Initialize(&sg);
// make sure the SDK initialized correctly
if( retval != SimplygonSDK::SG_ERROR_NOERROR )
{
   // ... failed to initialize, check the error message ...
}
// ... do some processing using the SDK ...
// deinitialize the SDK again.
SimplygonSDK::Deinitialize();
 

Global settings

In addition to the per-processing-object settings, there are also global settings which apply to all processes originating from a specific Simplygon instance. These settings are set using strings and contain advanced parameters. Setting global settings in the Simplygon instance affects all processes spawned from the Simplygon singleton.

DefaultTBNType What type of tangent calculation will be used in all simplygon processing.

TempFileDirectory The directory where Simplygon will store temporary files during processing. Setting this will change from the default temp directory to the specified one.

LogicalCoreLimit This determines the max number of cores simplygon will utilize when processing.

LogToFile If this is true, Simplygon will output text to file instead of stdout (only applicable in debugging scenarios since Simplygon normally does not log anything).

ValidateProcessing If this is true, Simplygon will run extra testing internally to find any bad data or bad results that might happen. This is for debugging purposes and will slow down the processing time significantly.

ValidateProcessingAssertOnError If this is true, Simplygon will abort if the ValidateProcessing found something wrong.

ValidateProcessingDebugLevel This value can be 0, 1 or 2. 0 will run the least amount of checks, and 2 will run the most amount of checks (and thus be the slowest of them all).

ValidateProcessingOutputDirectory The directory where Simplygon will store output files from the ValidateProcessing.

 

Thread-local settings

Thread-local settings are set in the same way as global settings, but only apply to the current thread when running in a multi-threaded environment.

LogFileName The path of the output log for this thread, if LogToFile is true.

 

Example

The following example shows how to set global and thread-local settings.

 
void SetGlobalSettings( ISimplygonSDK* sg )
{
   sg->SetGlobalSetting( "DefaultTBNType" , SG_TANGENTSPACEMETHOD_ORTHONORMAL );
 
   sg->SetGlobalSetting("LogToFile", true);
   sg->SetGlobalSetting("TempFileDirectory", (intptr_t)"C:\\MyTempFolder\\");
   sg->SetThreadLocalSetting("LogFileName", (intptr_t)"C:\\DebugOutput.txt");
}
 

The IObject interface and RTTI

Most of the interface provided by the Simplygon API are derived from the IObject interface. The IObject interface provides methods for retrieving class information and also provide reference counting that is used by the smart pointer types. The GetClassmethod provided by the IObject interface provides a way of retrieving the name of the class of which the object is an instance of. The IsClassA method allows a user to query whether a specific class is part of the inheritance tree of an object. This information allow for the safe casting of object types using the SafeCast method, which will automatically check whether the types are compatible using IsClassA.

 

Example

This example shows how to work with the IObject interface and perform safe casts between different classes derived the IObject class.

 
void ObjectExample()
{
   spRealArray arr = sg->CreateRealArray();
   // Test the type.
   std::cout << arr->GetClass() << std::endl;
   std::cout << arr->IsClassA("IRealArray") << std::endl;
   std::cout << arr->IsClassA("IBoolArray") << std::endl;
   std::cout << arr->IsClassA("IObject")    << std::endl;
   // This will output:
   // IRealArray
   // true
   // false
   // true
   // Upcasts are always safe in C++.
   spObject obj(arr);
   // Safe downcast using SafeCast. The SafeCast method
   // will return a pointer only if the object is,
   // or is derived from, IRealArray.
   spRealArray arr2( IRealArray::SafeCast(obj) );
}

Smart pointers

Most Simplygon classes provide smart pointers to simplify the object lifetime management. Only classes that are derived from IObject and implement the required interfaces can be used together with the smart pointer type. These pointer types automatically deallocate objects when they go out of scope or are reset unless the object is referenced by another smart pointer. These pointer types share the same name as the classes they reference, but have the prefix sp instead of I, such as spObject instead of IObject.

 
void SmartPointerExample()
{ // Function scope..  
   MyClass *myobject = NULL;
   // Create an object and assign its address to a smart pointer.
   spRidArray arr = sg->CreateRidArray();
   if( flag1 )
   { // 2nd scope...
     
       // Have another smart pointer point to the same object.
       // The object now has 2 references.
       spValueArray arr2( arr );
     
       // ... use arr2 ...
       if( flag2 )
       { // 3rd scope
         
           // A custom object is created that also keeps
           // a reference to the object. The reference
           // count is now 3.
           myobject = new MyClass( arr );
       }
       // arr2 goes out of scope. The
       // object now has 2 references.
   }
   // The custom object is deleted and reference count
   // decreases to 1.
   if( myobject )
       delete myobject;
   // Now arr goes out of scope, the object
   // has 0 references and is removed.
}

Error handling

Simplygon reports processing errors through the error handling class rerrorhandler. A user can derive a class from rerrorhandler, which then will receive processing errors, and handle them appropriately.

 
// A custom error handler.
class MyErrorHandler : public SimplygonSDK::rerrorhandler  
{  
public:  
   // The HandleError receives processing errors.
   virtual void HandleError(
                   IObject *object ,
                   const char *interfacename ,
                   const char *methodname ,
                   rid errortype,
                   const char *errortext
               );
};
// The global error handler object.
MyErrorHandler error_handler_object;
void RegisterErrorHandler( ISimplygonSDK *sg )
{
   // Register the error handler with Simplygon.
   // This will replace any current handler.
   sg->SetErrorHandler(&error_handler_object);
}
 

Event handling

Simplygon uses an event system to report e.g. processing progress. By implementing and registering an event callback object, the calling function can receive event updates from the system. An example of this is shown below.

 
// Progress observer class that prints progress to stdout.
class progress_observer : public robserver   
{   
    public:       
        virtual void Execute(
            IObject *subject ,
            rid EventId ,
            void *EventParameterBlock ,
            unsigned int EventParameterBlockSize )
        {           
            // Only care for progress events.
            if( EventId == SG_EVENT_PROGRESS )
            {
                // Get the progress in percent.
                int val = *((int*)EventParameterBlock);
                // Tell the process to continue.
                // This is required by the progress event.
                *((int*)EventParameterBlock) = 1;
                // Output the progress update.
                printf( "Progress: %d%%\n" , val );
            }
        }   
} progress_observer_object;
void RegisterEventObserver( spObject subject )
{
    // Register the event observer class with the subject.
    // Tell it we want progress events only.
    subject->AddObserver( &progress_observer_object , SG_EVENT_PROGRESS );
}
   

Deep Copy and New Copy

The Simplygon API provides two important copy methods. The DeepCopy method used to copy one object to another and NewCopywhich does a deep copy of the object into a new object which is returned. The deep and new copy methods are present in classes derived from IArray and ISceneNode, the IGeometryData class, the IPackedGeometryData class and the IImageData class. The IMatrix4x4 class contains only the DeepCopy method.

 

void DeepCopyNewCopy()
{  
   spRealArray arr = sg->CreateRealArray();
   spRealArray arr_ids = sg->CreateRealArray();
   // ... some work done on arr_ids ...
   // Create a new copy of arr_ids.
   spRealArray arr_ids_cpy = arr_ids->NewCopy(true);
   //  elements of arr_ids into arr.
   arr->DeepCopy(arr_ids);
}