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.
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.
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);
}
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);
}
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.
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;
}
}
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");
}
}
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#.
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;
}
}
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");
}
}
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.
Example - Working with object collections
This example shows how to work with object collections.
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;
}
}
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() );
}
}
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).