Skip to content
On this page

Data classes

Array types

The Simplygon API provides several array container types. These array types are named IArray, where denotes the type of elements stored in the array. The most commonly used array types are IRealArray and IRidArray that are used for most of the communication between the user and the API.

The arrays store the elements as tuples of user-specified size. This is used extensively in Simplygon to store e.g. 3D vectors in an array, where each vector is stored in a tuple, and the number of tuples in the array equals the number of vectors.

The offset in the array to a certain item in a tuple can be computed as:

offset = tupleindex * tuplesize + itemindex

The array interface also provides an interface for working directly with the tuples.

Arrays

Data types

There are data classes for each array type, e.g. there is an spRealData for the spRealArray and so on. The data objects exist to ensure proper range checking is used when accessing the Simplygon array data. Having the data object allows us to fetch or set data at a certain location in the array.

For instance, calling the spRealArray::GetData(spRealData) or the spRealArray::GetTuple(int, spRealData) function will give the data object the pointer to the array's data. Once the Data object has been initialized with the array pointer, calling the data object's GetItemCount() will return the array's total data count or its tuple size, depending on which one of GetData() or GetTuple() was called.

Example - Array creation

The following code shows how to create an array and fill it with some vector data.

cpp
void ArrayExample()
{
    // Create an array of real values (floating point)
    spRealArray arr = sg->CreateRealArray();

    // Setup the array to contain two 3D vectors.
    // Tuple size must be set before the tuple count.
    arr->SetTupleSize(3);
    arr->SetTupleCount(2);

    // The vector data.
    const real a[3] = { 0.0f, 1.0f, 0.0f };
    const real b[3] = { 1.0f, 0.0f, 0.0f };

    // Set the values of the elements in the array.
    arr->SetTuple(0, a);
    arr->SetTuple(1, b);
}
csharp
public void ArrayExample()
{
    // Create an array of real values (floating point)
    spRealArray arr = sg.CreateRealArray();

    // Setup the array to contain two 3D vectors.
    // Tuple size must be set before the tuple count.
    arr.SetTupleSize(3);
    arr.SetTupleCount(2);

    // The vector data.
    float[] a = { 0.0f, 1.0f, 0.0f };
    float[] b = { 1.0f, 0.0f, 0.0f };

    // Set the values of the elements in the array.
    arr.SetTuple(0, a);
    arr.SetTuple(1, b);
}
python
def array_example():
    # Create an array of real values (floating point)
    arr = sg.CreateRealArray()

    # Setup the array to contain two 3D vectors.
    # Tuple size must be set before the tuple count.
    arr.SetTupleSize(3)
    arr.SetTupleCount(2)

    # The vector data.
    a = [0.0, 1.0, 0.0]
    b = [1.0, 0.0, 0.0]

    # Set the values of the elements in the array.
    arr.SetTuple(0, a)
    arr.SetTuple(1, b)

Example - Array iteration

The following code listing shows how to iterate over all the tuple elements in an array and printing each tuple on its own line.

cpp
void PrintRealArray(spRealArray arr)
{
    const unsigned int tupleCount = arr->GetTupleCount();
    const unsigned int tupleSize = arr->GetTupleSize();
    for( unsigned int tuple = 0; tuple < tupleCount; ++tuple )
    {
        for( unsigned int elem = 0; elem < tupleSize; ++elem )
        {
            // Compute the offset to the item.
            unsigned int offset = tuple * tupleSize + elem;

            std::cout << arr->GetItem(offset) << ",";
        }
        std::cout << std::endl;
    }
}
csharp
void PrintRealArray(spRealArray arr)
{
    // Get the number of tuples (TupleCount) and number of items per tuple (TupleSize)
    uint tupleCount = arr.GetTupleCount();
    uint tupleSize = arr.GetTupleSize();

    // Iterate over all tuples
    for (uint tuple = 0; tuple < tupleCount; ++tuple)
    {
        // Print all elements in this tuple
        for (uint elem = 0; elem < tupleSize; ++elem)
        {
            // Compute the offset to the item.
            uint offset = tuple * tupleSize + elem;

            // Print item
            System.Console.Write( " " + arr.GetItem((int)offset) + "," );
        }
        // Newline
        System.Console.Write("\n");
    }
}
python
def print_real_array(arr):
    # Get the number of tuples (TupleCount) and number of items per tuple (TupleSize)
    tuple_count = arr.GetTupleCount()
    tuple_size = arr.GetTupleSize()

    # Iterate over all tuples
    for tuple in range(tuple_count):
        # Print all elements in this tuple
        for elem in range(tuple_size):
            # Compute the offset to the item.
            itemOffset = (tuple * tuple_size) + elem

            # Print item
            sys.stdout.write('{},'.format(arr.GetItem(itemOffset)))

        # Newline
        sys.stdout.write('\n')

Example - Using a Data object

The following code shows how to use a Data object to fetch the raw data from an array. This is automatically modified into a standard array in Python and C#.

cpp
void PrintRealArray(spRealArray arr)
{
    int tuple_count = arr->GetTupleCount();
    int tuple_size = arr->GetTupleSize();

    // The following code uses a Data object to fetch the whole array at once
    spRealData arr_data = arr->GetData();
    for( int tuple = 0; tuple < tuple_count; tuple++ )
    {
        for( int i = 0; i < tuple_size; i++ )
        {
            std::cout << " " arr_data[tuple*tuple_size + i];
        }
        std::cout << std::endl;
    }
    // The following code uses a Data object to fetch one tuple at a time.
    for( int tuple = 0; tuple < tuple_count; tuple++ )
    {
        spRealData arr_tuple = arr->GetTuple( tuple );
        for( int i = 0; i < tuple_size; ++i )
            std::cout << " " << arr_tuple[i];

        std::cout << std::endl;
    }
}
csharp
void PrintRealArray(spRealArray arr)
{
    uint tuple_count = arr.GetTupleCount();
    uint tuple_size = arr.GetTupleSize();

    // The following code uses a Data object and cast to array using ToArray() to fetch the whole array at once
    float[] arr_data = arr.GetData().ToArray();
    for (int tuple = 0; tuple < tuple_count; tuple++)
    {
        for (int i = 0; i < tuple_size; i++)
        {
            System.Console.Write( " " + arr_data[tuple * tuple_size + i] );
        }
        System.Console.Write("\n");
    }
    // The following code uses a Data object to fetch one tuple at a time.
    for (int tuple = 0; tuple < tuple_count; tuple++)
    {
        float[] arr_tuple = arr.GetTuple(tuple).ToArray();
        for (int i = 0; i < tuple_size; ++i)
        {
            System.Console.Write(" " + arr_tuple[i);
        }
        System.Console.Write("\n");
    }
}
python
def print_real_array(arr):
    # Get the number of tuples (TupleCount) and number of items per tuple (TupleSize)
    tuple_count = arr.GetTupleCount()
    tuple_size = arr.GetTupleSize()

    # The following code uses a Data object to fetch the whole array at once
    arr_data = arr.GetData()

    # Iterate over all tuples
    for tuple in range(tuple_count):
        # print all elements in this tuple
        for elem in range(tuple_size):
            # Compute the offset to the item.
            item_offset = (tuple * tuple_size) + elem
            # Print item
            sys.stdout.write('{} '.format(arr_data[item_offset]))
        sys.stdout.write('\n')

    # The following code uses a Data object to fetch one tuple at a time.
    for tuple in range(tuple_count):
        arr_tuple = arr.GetTuple(tuple)

        # Print all elements in this tuple
        for elem in range(tuple_size):
            # Print item
            sys.stdout.write('{} '.format(arr_tuple[elem]))

        sys.stdout.write('\n')

Object collection types

The Simplygon API provides a special container type for storing Simplygon objects. These container types are referred to as object collections.

The collection types use the same naming scheme as the array types. The most generic object collection type is named IObjectCollection and is capable of storing anything that derives from the Simplygon IObject class and implements the required interface.

The object containers use the rhandle type for referencing items in them so iteration over the elements is done using the GetFirstItem and GetNextItem methods. For simplicity, there are some collections derived from IObjectCollection, such as IGeometryDataCollection, that keeps object of type IGeometryData. These derived classes has methods for directly retrieving the object type, such as GetGeometryData instead of using GetItemsObject, and then casting the returned pointer.

Object collection

Example - Working with object collections

This example shows how to work with object collections.

cpp
void CollectionExample()
{
    spObjectCollection objects = sg->CreateObjectCollection();
    // Fill the object collection with different types of arrays.
    objects->AddObject( sg->CreateRealArray() );
    objects->AddObject( sg->CreateRidArray() );
    objects->AddObject( sg->CreateBoolArray() );
    // Now iterate over all the entries in the container.
    for(rhandle h = objects->GetFirstItem(); h; h = objects->GetNextItem(h))
    {
        spObject obj = objects->GetItemsObject(h);
        std::cout << "This object is a " << obj->GetClass() << std::endl;
    }
}
csharp
void CollectionExample()
{
    spObjectCollection objects = sg.CreateObjectCollection();

    // Fill the object collection with different types of arrays.
    objects.AddObject(sg.CreateRealArray());
    objects.AddObject(sg.CreateRidArray());
    objects.AddObject(sg.CreateBoolArray());

    // Now iterate over all the entries in the container.
    for (var h = objects.GetFirstItem(); h != null ; h = objects.GetNextItem(h))
    {
        spObject obj = objects.GetItemsObject(h);
        System.Console.WriteLine("This object is a " + obj.GetClass() );
    }
}
python
def CollectionExample():
    # Create an object collection
    objects = sg.CreateObjectCollection()

    # Fill the object collection with different types of arrays.
    objects.AddObject(sg.CreateRealArray())
    objects.AddObject(sg.CreateRidArray())
    objects.AddObject(sg.CreateBoolArray())

    # Now iterate over all the entries in the container.
    h = objects.GetFirstItem()
    while h != None:
        # Get the object of this item in the collection
        ob = objects.GetItemsObject(h)
        # Print the type of the object
        print('This object is a {}'.format(ob.GetClass()))
        # Move the iterator h to point at the next item in the collection
        h = objects.GetNextItem(h)

    # The output from running this will be:
    # IRealArray
    # IRidArray
    # IBoolArray

Field data objects

Field data objects are properties stored in arrays either per triangle, vertex or triangle corner. Examples of array data stored per vertex is: coordinates, texture coordinates (continuous between triangles), bone IDs and bone weights. Vertex and material IDs are examples of information stored per triangle. Corners store normals and texture coordinates when they are discontinuous between triangles.

The user can create data arrays and decide if they are per vertex, triangle or corner. The data is stored in arrays with the tuple count being the size of the field it's assigned to. For instance, the vertex coordinates data array has a tuple count of the number of vertices and tuple size three (because of 3d Cartesian coordinates).

Per vertex fields