GetConceptualFaceEx

This function returns a handle to the conceptual face. Be aware that different instances can return the same handles (however with possible different startIndices and noTriangles).
Argument index should be at least zero and smaller then return value of GetConceptualFaceCnt().

Syntax

//   Visual Studio for Windows
public:
__int64 __declspec(dllexport) __stdcall GetConceptualFaceEx(
            __int64             owlInstance,
            __int64             index,
            __int64             * startIndexTriangles,
            __int64             * noIndicesTriangles,
            __int64             * startIndexLines,
            __int64             * noIndicesLines,
            __int64             * startIndexPoints,
            __int64             * noIndicesPoints,
            __int64             * startIndexFacePolygons,
            __int64             * noIndicesFacePolygons,
            __int64             * startIndexConceptualFacePolygons,
            __int64             * noIndicesConceptualFacePolygons
        );

//   Linux, OS-X and non-Visual Studio Windows solutions
public:
int64_t GetConceptualFaceEx(
            int64_t             owlInstance,
            int64_t             index,
            int64_t             * startIndexTriangles,
            int64_t             * noIndicesTriangles,
            int64_t             * startIndexLines,
            int64_t             * noIndicesLines,
            int64_t             * startIndexPoints,
            int64_t             * noIndicesPoints,
            int64_t             * startIndexFacePolygons,
            int64_t             * noIndicesFacePolygons,
            int64_t             * startIndexConceptualFacePolygons,
            int64_t             * noIndicesConceptualFacePolygons
        );    

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 index

Size: 64 bit / 8 byte (value)
This is the index (0 based) of the face in the set of conceptual faces available.

Property startIndexTriangles

Size: 32 bit / 4 byte (reference)
The first index in the indices array representing a Triangle by a reference in the vertices array.

Property noIndicesTriangles

Size: 32 bit / 4 byte (reference)
The number of lines within this conceptual face has exactly one third of the number in this noIndicesTriangles, each individual index from startIndexTriangles references a vertex element in the vertices array, the references could be duplicated. Each triple of references represents one triangle.

Property startIndexLines

Size: 32 bit / 4 byte (reference)
The first index in the indices array representing a Line by a reference in the vertices array.

Property noIndicesLines

Size: 32 bit / 4 byte (reference)
The number of lines within this conceptual face has exactly half of the number in this noIndicesLines, each individual index from startIndexLines references a vertex element in the vertices array, the references could be duplicated. Each tuple of references represents one line.

Property startIndexPoints

Size: 32 bit / 4 byte (reference)
The first index in the indices array representing a Point by a reference in the vertices array.

Property noIndicesPoints

Size: 32 bit / 4 byte (reference)
The number of points within this conceptual face exactly matched this noIndicesPoints, each individual index from startIndexPoints references a vertex element in the vertices array, the references could be duplicated.

Property startIndexFacePolygons

Size: 32 bit / 4 byte (reference)
The first index in the indices array representing the polygon for that specific face (a face is always placed / defined in exactly 1 plane). SetFormat(..) has several options to structure how these polygons are exported with / without repeating line segments, line segments per line segment or list of vertex references ending with -1 (outer polygon) or -2 (inner polygon) [default]. For example by default a Cylinder has 38 faces, top and bottom have each one polygon with 37 points (first and last point the same) and surrounding face polygons represent rectangles (i.e. 6 elements including the last / first point being the same and -1 as ending).

Property noIndicesFacePolygons

Size: 32 bit / 4 byte (reference)
The number of indices in the indices array for the face polygons. For example in default SetFormat(..) setting a square polygon represented by 6 indices, for example [0, 1, 2, 3, 0, -1] where the vertices array has at least 4 vertex elements.

Property startIndexConceptualFacePolygons

Size: 32 bit / 4 byte (reference)
The first index in the indices array representing the polygon for that specific conceptual face. SetFormat(..) has several options to structure how these polygons are exported with / without repeating line segments, line segments per line segment or list of vertex references ending with -1 (outer polygon) or -2 (inner polygon) [default]. For example by default a Cylinder has three conceptual faces, top and bottom have each one polygon and surrounding polygon has two polygons.

Property noIndicesConceptualFacePolygons

Size: 32 bit / 4 byte (reference)
The number of indices in the indices array for the conceptual face polgyons. For example in default SetFormat(..) setting a square polygon represented by 6 indices, for example [0, 1, 2, 3, 0, -1] where the vertices array has at least 4 vertex elements.

Example

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

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

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

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

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

...

int64_t model = CreateModel();

if (model) {
    //
    //  Classes
    //
    int64_t classCollection = GetClassByName(model, "Collection"),
            classCylinder = GetClassByName(model, "Cylinder"),
            classLine3D = GetClassByName(model, "Line3D"),
            classPoint3D = GetClassByName(model, "Point3D");

    //
    //  Object Properties (relations)
    //
    int64_t propertyObjects = GetPropertyByName(model, "objects");

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

    //
    //  Instances (creating)
    //
    int64_t instanceCollection = CreateInstance(classCollection, nullptr),
            instanceCylinder = CreateInstance(classCylinder, nullptr),
            instanceLine3D = CreateInstance(classLine3D, nullptr),
            instancePoint3D_I = CreateInstance(classPoint3D, nullptr),
            instancePoint3D_II = CreateInstance(classPoint3D, nullptr);

    int64_t objects[6] = { instancePoint3D_I, instanceLine3D, instanceLine3D, instancePoint3D_II, instanceCylinder, instancePoint3D_I };
    SetObjectProperty(instanceCollection, propertyObjects, objects, 6);

    double  coordinates_I[3] = { 1., 2., 3. },
            coordinates_II[3] = { 4., 5., 6. },
            length = 4.,
            points[6] = { 0., 0., -1., 5., 3., 0. },
            radius = 2.;
    int64_t segmentationParts = 36;

    SetDatatypeProperty(instanceCylinder, propertyLength, &length, 1);
    SetDatatypeProperty(instanceCylinder, propertyRadius, &radius, 1);
    SetDatatypeProperty(instanceCylinder, propertySegmentationParts, &segmentationParts, 1);
    SetDatatypeProperty(instanceLine3D, propertyPoints, points, 6);
    SetDatatypeProperty(instancePoint3D_I, propertyCoordinates, coordinates_I, 3);
    SetDatatypeProperty(instancePoint3D_II, propertyCoordinates, coordinates_II, 3);

    int64_t 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_t setting = 0,
            mask = 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_t vertexElementSizeInBytes = SetFormat(model, setting, mask);
    assert(vertexElementSizeInBytes == (3 + 3) * sizeof(float));

    ...

    int64_t vertexBufferSize = 0, indexBufferSize = 0;
    CalculateInstance(myInstance, &vertexBufferSize, &indexBufferSize, nullptr);

    if (vertexBufferSize && indexBufferSize) {
        float   * vertices = new float[(int_t) vertexBufferSize * ((int_t) vertexElementSizeInBytes / sizeof(float))];
        int32_t * indices = new int32_t[(int_t) indexBufferSize];

        UpdateInstanceVertexBuffer(myInstance, vertices);
        UpdateInstanceIndexBuffer(myInstance, indices);

        int64_t triangleCnt = 0, lineCnt = 0, pointCnt = 0,
                conceptualFaceCnt = GetConceptualFaceCnt(myInstance);
        for (int64_t index = 0; index < conceptualFaceCnt; index++) {
            int64_t startIndexTriangles = 0, noIndicesTrangles = 0,
                    startIndexLines = 0, noIndicesLines = 0,
                    startIndexPoints = 0, noIndicesPoints = 0;

            GetConceptualFaceEx(
                    myInstance, index,
                    &startIndexTriangles, &noIndicesTrangles,
                    &startIndexLines, &noIndicesLines,
                    &startIndexPoints, &noIndicesPoints,
                    0, 0,
                    0, 0
                );

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

        int32_t * triangleIndices = triangleCnt ? new int32_t[(int_t) 3 * triangleCnt] : nullptr,
                * lineIndices = lineCnt ? new int32_t[(int_t) 2 * lineCnt] : nullptr,
                * pointIndices = pointCnt ? new int32_t[(int_t) pointCnt] : nullptr;

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

            GetConceptualFaceEx(
                    myInstance, index,
                    &startIndexTriangles, &noIndicesTrangles,
                    &startIndexLines, &noIndicesLines,
                    &startIndexPoints, &noIndicesPoints,
                    0, 0,
                    0, 0
                );

            if (noIndicesTrangles) {
                memcpy(&triangleIndices[triangleIndicesOffset], &indices[startIndexTriangles], noIndicesTrangles * sizeof(int32_t));
                triangleIndicesOffset += noIndicesTrangles;
            }

            if (noIndicesLines) {
                memcpy(&lineIndices[lineIndicesOffset], &indices[startIndexLines], noIndicesLines * sizeof(int32_t));
                lineIndicesOffset += noIndicesLines;
            }

            if (noIndicesPoints) {
                memcpy(&pointIndices[pointIndicesOffset], &indices[startIndexPoints], noIndicesPoints * sizeof(int32_t));
                pointIndicesOffset += noIndicesPoints;
            }
        }
        delete[] indices;
        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
        //      
        //
        assert(triangleCnt == 36 * 2 + 2 * (36 - 2));   //  The collection contained 1 cylinder (with segmentation parts 36)
        assert(lineCnt == 2);                           //  The collection contained 2 lines
        assert(pointCnt == 3);                          //  The collection contained 3 points

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

        delete[] vertices;
        if (triangleIndices) { delete[] triangleIndices; }
        if (lineIndices) { delete[] lineIndices; }
        if (pointIndices) { delete[] pointIndices; }
    }

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