CalculateInstance

This function prepares the content to be ready so the buffers can be filled.
It returns the minimum size the buffers should be. This is only the case when the pointer is given, all arguments are allowed to be nullptr.

Note: This function needs to be called directly before UpdateVertexBuffer(),
    UpdateIndexBuffer() and UpdateTransformationBuffer().

Syntax

public const string enginedll = @"engine.dll";

[DllImport(enginedll, EntryPoint = "CalculateInstance")]
public static extern Int64 CalculateInstance(Int64 owlInstance, out Int64 vertexBufferSize, out Int64 indexBufferSize, out Int64 transformationBufferSize);

[DllImport(enginedll, EntryPoint = "CalculateInstance")]
public static extern Int64 CalculateInstance(Int64 owlInstance, out Int64 vertexBufferSize, out Int64 indexBufferSize, IntPtr transformationBufferSize);

[DllImport(enginedll, EntryPoint = "CalculateInstance")]
public static extern Int64 CalculateInstance(Int64 owlInstance, out Int64 vertexBufferSize, IntPtr indexBufferSize, out Int64 transformationBufferSize);

[DllImport(enginedll, EntryPoint = "CalculateInstance")]
public static extern Int64 CalculateInstance(Int64 owlInstance, out Int64 vertexBufferSize, IntPtr indexBufferSize, IntPtr transformationBufferSize);

[DllImport(enginedll, EntryPoint = "CalculateInstance")]
public static extern Int64 CalculateInstance(Int64 owlInstance, IntPtr vertexBufferSize, out Int64 indexBufferSize, out Int64 transformationBufferSize);

[DllImport(enginedll, EntryPoint = "CalculateInstance")]
public static extern Int64 CalculateInstance(Int64 owlInstance, IntPtr vertexBufferSize, out Int64 indexBufferSize, IntPtr transformationBufferSize);

[DllImport(enginedll, EntryPoint = "CalculateInstance")]
public static extern Int64 CalculateInstance(Int64 owlInstance, IntPtr vertexBufferSize, IntPtr indexBufferSize, out Int64 transformationBufferSize);

[DllImport(enginedll, EntryPoint = "CalculateInstance")]
public static extern Int64 CalculateInstance(Int64 owlInstance, IntPtr vertexBufferSize, IntPtr indexBufferSize, IntPtr transformationBufferSize);

public static Int64 CalculateInstance(Int64 owlInstance, out Int64 vertexBufferSize, out Int64 indexBufferSize)
        {
            return CalculateInstance(owlInstance, out vertexBufferSize, out indexBufferSize, IntPtr.Zero);
        }    

Property owlInstance

Size: 64 bit / 8 byte (value)
The handle to the specific instance in the design tree. The instance handle is static within one open model but is most probably different when the same instance is opened in another model. The instance is always exactly of one unique class.

Property vertexBufferSize

Size: 64 bit / 8 byte (reference)
The calculated size that is required for the vertex buffer. This only returns a value if it has a non-zero input value.

Property indexBufferSize

Size: 64 bit / 8 byte (reference)
The calculated size that is required for the index buffer. The host will require to allocate the index buffer, depending on SetFormat(), this will be 4 bytes * indexBufferSize (32 bit integer) or 8 bytes * indexBufferSize (64 bit integer).

Property transformationBufferSize

Size: 64 bit / 8 byte (reference)
the calculated size that is required for the transformation buffer

Example (based on pure API calls)

Here you can find code snippits that show how the API call CalculateInstance can be used.

using RDF;      //  include at least engine.cs within your solution

const Int64 flagbit0 = 1;                           // 2^^0                          0000.0000..0000.0001
const Int64 flagbit1 = 2;                           // 2^^1                          0000.0000..0000.0010
const Int64 flagbit2 = 4;                           // 2^^2                          0000.0000..0000.0100
const Int64 flagbit3 = 8;                           // 2^^3                          0000.0000..0000.1000

const Int64 flagbit4 = 16;                          // 2^^4                          0000.0000..0001.0000
const Int64 flagbit5 = 32;                          // 2^^5                          0000.0000..0010.0000
const Int64 flagbit6 = 64;                          // 2^^6                          0000.0000..0100.0000
const Int64 flagbit7 = 128;                         // 2^^7                          0000.0000..1000.0000

const Int64 flagbit8 = 256;                         // 2^^8                          0000.0001..0000.0000
const Int64 flagbit9 = 512;                         // 2^^9                          0000.0010..0000.0000
const Int64 flagbit10 = 1024;                       // 2^^10                         0000.0100..0000.0000
const Int64 flagbit11 = 2048;                       // 2^^11                         0000.1000..0000.0000

const Int64 flagbit12 = 4096;                       // 2^^12                         0001.0000..0000.0000
const Int64 flagbit13 = 8192;                       // 2^^13                         0010.0000..0000.0000
const Int64 flagbit14 = 16384;                      // 2^^14                         0100.0000..0000.0000
const Int64 flagbit15 = 32768;                      // 2^^15                         1000.0000..0000.0000

static void Main(string[] args)
{
    Int64   model = RDF.engine.CreateModel();

    if (model != 0)
    {
        //
        //  Classes
        //
        Int64   classCollection = RDF.engine.GetClassByName(model, "Collection"),
                classCylinder = RDF.engine.GetClassByName(model, "Cylinder"),
                classLine3D = RDF.engine.GetClassByName(model, "Line3D"),
                classPoint3D = RDF.engine.GetClassByName(model, "Point3D");

        //
        //  Object Properties (relations)
        //
        Int64   propertyObjects = RDF.engine.GetPropertyByName(model, "objects");

        //
        //  Datatype Properties (attributes)
        //
        Int64   propertyCoordinates = RDF.engine.GetPropertyByName(model, "coordinates"),
                propertyLength = RDF.engine.GetPropertyByName(model, "length"),
                propertyPoints = RDF.engine.GetPropertyByName(model, "points"),
                propertyRadius = RDF.engine.GetPropertyByName(model, "radius"),
                propertySegmentationParts = RDF.engine.GetPropertyByName(model, "segmentationParts");

        //
        //  Instances (creating)
        //
        Int64   instanceCollection = RDF.engine.CreateInstance(classCollection, (string) null),
                instanceCylinder = RDF.engine.CreateInstance(classCylinder, (string) null),
                instanceLine3D = RDF.engine.CreateInstance(classLine3D, (string) null),
                instancePoint3D_I = RDF.engine.CreateInstance(classPoint3D, (string) null),
                instancePoint3D_II = RDF.engine.CreateInstance(classPoint3D, (string) null);

        Int64[] objects = { instancePoint3D_I, instanceLine3D, instanceLine3D, instancePoint3D_II, instanceCylinder, instancePoint3D_I };
        RDF.engine.SetObjectProperty(instanceCollection, propertyObjects, ref objects[0], 6);

        double[]    coordinates_I = { 1.0, 2.0, 3.0 },
                    coordinates_II = { 4.0, 5.0, 6.0 },
                    points = { 0.0, 0.0, -1.0, 5.0, 3.0, 0.0 };
        double      length = 4.0,
                    radius = 2.0;
        Int64       segmentationParts = 36;

        RDF.engine.SetDatatypeProperty(instanceCylinder, propertyLength, ref length, 1);
        RDF.engine.SetDatatypeProperty(instanceCylinder, propertyRadius, ref radius, 1);
        RDF.engine.SetDatatypeProperty(instanceCylinder, propertySegmentationParts, ref segmentationParts, 1);
        RDF.engine.SetDatatypeProperty(instanceLine3D, propertyPoints, ref points[0], 6);
        RDF.engine.SetDatatypeProperty(instancePoint3D_I, propertyCoordinates, ref coordinates_I[0], 3);
        RDF.engine.SetDatatypeProperty(instancePoint3D_II, propertyCoordinates, ref coordinates_II[0], 3);

        Int64   myInstance = instanceCollection;

        ...
        ...     //  create, load or edit myInstance, in this case a simple Collection is used as input
        ...

        //
        //  Initializing the mask with all possible options
        //
        Int64   setting = 0,
                mask = RDF.engine.GetFormat(0, 0);

        setting += 0 * flagbit2;        //    SINGLE / DOUBLE PRECISION (float / double)
        setting += 0 * flagbit3;        //    32 / 63 BIT INDEX ARRAY (int32_t / int64_t)

        setting += 1 * flagbit4;        //    OFF / ON VECTORS (x, y, z) 
        setting += 1 * flagbit5;        //    OFF / ON NORMALS (Nx, Ny, Nz)

        setting += 1 * flagbit8;        //    OFF / ON TRIANGLES
        setting += 1 * flagbit9;        //    OFF / ON LINES
        setting += 1 * flagbit10;       //    OFF / ON POINTS

        setting += 0 * flagbit12;       //    OFF / ON WIREFRAME FACES
        setting += 0 * flagbit13;       //    OFF / ON WIREFRAME CONCEPTUAL FACES

        Int64   vertexElementSizeInBytes = RDF.engine.SetFormat(model, setting, mask);
        System.Diagnostics.Debug.Assert(vertexElementSizeInBytes == (3 + 3) * sizeof(float));

        ...

        Int64   vertexBufferSize = 0, indexBufferSize = 0;
        RDF.engine.CalculateInstance(myInstance, out vertexBufferSize, out indexBufferSize, (IntPtr) 0);

        if (vertexBufferSize != 0 && indexBufferSize != 0)
        {
            float[] vertices = new float[vertexBufferSize * (vertexElementSizeInBytes / sizeof(float))];
            Int32[] indices = new Int32[indexBufferSize];

            RDF.engine.UpdateInstanceVertexBuffer(myInstance, ref vertices[0]);
            RDF.engine.UpdateInstanceIndexBuffer(myInstance, ref indices[0]);

            Int64   triangleCnt = 0, lineCnt = 0, pointCnt = 0,
                    conceptualFaceCnt = RDF.engine.GetConceptualFaceCnt(myInstance);
            for (Int64 index = 0; index < conceptualFaceCnt; index++)
            {
                Int64   startIndexTriangles = 0, noIndicesTriangles = 0,
                        startIndexLines = 0, noIndicesLines = 0,
                        startIndexPoints = 0, noIndicesPoints = 0;

                RDF.engine.GetConceptualFace(
                        myInstance, index,
                        out startIndexTriangles, out noIndicesTriangles,
                        out startIndexLines, out noIndicesLines,
                        out startIndexPoints, out noIndicesPoints,
                        (IntPtr) 0, (IntPtr) 0,
                        (IntPtr) 0, (IntPtr) 0
                    );

                //  
                //  Calculate space required for arrays
                //
                triangleCnt += noIndicesTriangles / 3;
                lineCnt += noIndicesLines / 2;
                pointCnt += noIndicesPoints;
            }

            Int32[] triangleIndices = (triangleCnt != 0) ? new Int32[3 * triangleCnt] : null,
                    lineIndices = (lineCnt != 0) ? new Int32[2 * lineCnt] : null,
                    pointIndices = (pointCnt != 0) ? new Int32[pointCnt] : null;

            Int64   triangleIndicesOffset = 0, lineIndicesOffset = 0, pointIndicesOffset = 0;
            for (Int64 index = 0; index < conceptualFaceCnt; index++)
            {
                Int64   startIndexTriangles = 0, noIndicesTriangles = 0,
                        startIndexLines = 0, noIndicesLines = 0,
                        startIndexPoints = 0, noIndicesPoints = 0;

                RDF.engine.GetConceptualFace(
                        myInstance, index,
                        out startIndexTriangles, out noIndicesTriangles,
                        out startIndexLines, out noIndicesLines,
                        out startIndexPoints, out noIndicesPoints,
                        (IntPtr) 0, (IntPtr) 0,
                        (IntPtr) 0, (IntPtr) 0
                    );

                if (noIndicesTriangles != 0)
                {
                    Array.Copy(indices, startIndexTriangles, triangleIndices, triangleIndicesOffset, noIndicesTriangles);
                    triangleIndicesOffset += noIndicesTriangles;
                }

                if (noIndicesLines != 0)
                {
                    Array.Copy(indices, startIndexLines, lineIndices, lineIndicesOffset, noIndicesLines);
                    lineIndicesOffset += noIndicesLines;
                }

                if (noIndicesPoints != 0)
                {
                    Array.Copy(indices, startIndexPoints, pointIndices, pointIndicesOffset, noIndicesPoints);
                    pointIndicesOffset += noIndicesPoints;
                }
            }
            System.Diagnostics.Debug.Assert(triangleIndicesOffset == triangleCnt * 3 && lineIndicesOffset == lineCnt * 2 && pointIndicesOffset == pointCnt);

            //
            //  Now the index arrays for triagles, lines and points are ready
            //      triangleIndices
            //      lineIndices
            //      pointIndices
            //  all three are using the same vertex array
            //      vertices
            //

            //
            //  Based on the Collection we should find
            //      
            //
            System.Diagnostics.Debug.Assert(triangleCnt == 36 * 2 + 2 * (36 - 2));  //  The collection contained 1 cylinder (with segmentation parts 36)
            System.Diagnostics.Debug.Assert(lineCnt == 2);                          //  The collection contained 2 lines
            System.Diagnostics.Debug.Assert(pointCnt == 3);                         //  The collection contained 3 points

            ...
            ...     //  use the vertex and index array for visualization, QTO, conversion etc.
            ...
        }

        //
        //  The resulting model can be viewed in 3D-Editor.exe
        //
        RDF.engine.SaveModel(model, "c:\\created\\myFile.bin");
        RDF.engine.CloseModel(model);
    }
}