//========================================================================================================
// Plugin for EQUINOX-3D
//
// Simple plugin code example that:
// - Creates a Model
// - Adds a Mesh to it, and adds 3 Vertices to the Mesh
// - Adds a PolyGroup to the Mesh
// - Adds a single triangle to the PolyGroup
// - Adds the Model to the main Scene and calls the required update functions
//
// AUTHOR:  Gabor Nagy
// DATE:    2025-Mar-12 22:31:08
//
// You are free to modify and redistribute this code.
// To avoid cluttering the UI, example plugins are not loaded by default, when EQUINOX-3D is started.
// You can manually load them from the Plugin manager, or you can edit your Plugins/Plugins.list file,
// and comment out (e.g. with a trailing "#") or remove the "Load = FALSE;" line for a plugin.
//
// EQUINOX-3D and contained libraries are Copyright (C) 2014-2026 by Gabor Nagy. All rights reserved.
//========================================================================================================
#include <assert.h>
#include <stdio.h>

#include <ELists.h>
#include <EMalloc.h>
#include <EPlugins.h>

#include <E3D/Scene.h>

#include <E3D/UI/Panel.h>
#include <E3D/UI/StatusPanel.h>

#include <Xe/PushButton.h>

char*             E_PluginInfo = "Simple Polygon example";  // This shows up in the information dialog box of the plugin manager (System->Plugins)

static EPlugin*   _Plugin = NULL;

static XeDWidget	  _Buttons[2];static int  _Buttons_Count = 0;  // We collect buttons into an array here, so we can easily free them when the plugin exits


// Don't forget to add this to Plugins/Plugins.list, so EQUINOX-3D actually loads your plugin!
/*
{
Name	= Examples/Simple Polygon;
Object	= Examples/SimplePolygon;
}
*/


//========================================================
// ToolBar icon and menu button callback handler
//========================================================
static void _CB(XeWidget PW, EPointer PClientData, EPointer PCallData) {
    E3dScene *LScene = E3d_Scene;  // E3d_Scene is one of the few global variables. It points to the current Scene (the highest level container of the world) used by the application (EQUINOX-3D)
    E3dModel *LModel;
    E_New(E3dModel, LModel);
    if (LModel == NULL) {
        printf("%s() %s:%d  Could not create Model\n", __FUNCTION__, __FILE__, __LINE__);
        fflush(stdout);
        return;
    }


    EObject_SetName(LModel, E3dScene_GetUniqueNodeName(LScene, "Simple Model"),
                    FALSE);  // This will guarantee that our new Model has a unique name. Handy, if you add a bunch of these, by clicking on the button many times.
//EObject_SetName(LModel, EStrDup(LScene, "Simple Model"), FALSE);                     // This will simply set the name


    E3dMesh *LMesh;
    E_New(E3dMesh, LMesh);
    E3dModel_ObjectAppend(LModel, (E3dObject*)LMesh, FALSE);

// We could also the above two steps this with just one call.
// Note that this is a function that takes a dynamic class pointer, so you can pass classes defined in plugins as well.
//
//E3dModel_AddObject(LModel, E3dMesh_class);


// Let's get a unique name for the Mesh too. Note that this is an E3dObject derivative, which is distintct from E3dModel (E3dNode derivative), so name uniqueness is checked separately.
// It's just a convention to have capitalized names for Models and lower case names for Objects (Lights, Cameras, Geometries, etc.)
//
    EObject_SetName(LMesh, E3dScene_GetUniqueObjectName(LScene, "Simple Mesh"), FALSE);


// Add 5 Vertices to the Mesh and set their positions (the status flags are initialized to E3dVtxDEFAULT by E3dMesh_VerticesAdd)
// We'll make this a concave pentagon, just to show off that EQX has no trouble with such things.
// Polygons can even have holes!
//
    E3dVertex *LVertices = E3dMesh_VerticesAdd(LMesh, 26);
    E3dVertex *LVertex = LVertices;
    const E3dVertexSize LVertexSize = LMesh->VertexSize;

// We could just do LVertex->Position.X =, LVertex->Position.Y =..., but this is more convenient
// The '_s' suffix of the setter macro just means "struct", (as opposed to '_p', meaning pointer to struct)
//
    //0-5
    LVertex->Position = E3dCoord3_s(1.0, 0.000, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.5, 0.866, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.5, 0.866, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-1.0, 0.000, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.5, -0.866, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.5, -0.866, 0.5);
    EStruct_Inc(LVertex, LVertexSize);

    //-6-11
    LVertex->Position = E3dCoord3_s(1.0, 0.000, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.5, 0.866, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.5, 0.866, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-1.0, 0.000, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.5, -0.866, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.5, -0.866, -0.5);
    EStruct_Inc(LVertex, LVertexSize);

    //12-19
    LVertex->Position = E3dCoord3_s(0.125, 0.555, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.125, 0.305, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.125, 0.305, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.125, 0.555, -0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.125, 0.555, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.125, 0.305, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.125, 0.305, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.125, 0.555, 0.5);
    EStruct_Inc(LVertex, LVertexSize);

    //20-22
    LVertex->Position = E3dCoord3_s(0.0, 0.055, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.15, -0.205, 0.5);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.15, -0.205, 0.5);
    EStruct_Inc(LVertex, LVertexSize);

    //23-25
    LVertex->Position = E3dCoord3_s(0.0, 0.055, 0.25);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(-0.15, -0.205, 0.25);
    EStruct_Inc(LVertex, LVertexSize);
    LVertex->Position = E3dCoord3_s(0.15, -0.205, 0.25);
    EStruct_Inc(LVertex, LVertexSize);








// Finally, add the Polygon
// You can also directly manipulate the LPolyGroup->Polygons array, if you need high performance.
// Just make sure LPolyGroup->Polygons_Count is valid, when you are done.
//

// Add the Vertices to the Polygon (VertexNodes, to be exact).
// EQUINOX-3D, as most advanced 3D modeling and CAD systems, use a shared Vertex array on the Mesh, for the *positions* of the Vertices.
// This has 2 main advantages, vs. storing positions on the Polygon Vertices (a.k.a. "disconnected Polygon soup", yikes!):
// - You save memory (sometimes, a lot) when several Polygons share a Vertex ('high valence' Vertex)
// - You get *exact* Vertex identity checks, by comparing integer Vertex indices, rather than the ugly and expensive business of comparing float/double triplets (thou shalt not compare floats for identity, lest you will be cursed with bugs, due to rounding errors!)

// A VertexNode of a Polygon, always has an index to the appropriate Mesh Vertex, as well as other, optional Vertex attributes.
// EQUINOX-3D allows a completely flexible system for Vertex attributes, so the size of a VertexNode may vary.
// LPolyGroup->VertexNodeSize indicates how many bytes each VertexNode has on a given PolyGroup.
// For example, each VertexNode on the Polygons of a PolyGroup may have a vertex index, a normal, a tangent, 3 sets of texture coordinates and a pair of U,V coordinates (not to be confused with texture coordinates (S,T)
// This allows for 3 different texture mappings on this PolyGroup, plus a set of UV coordinats that may be used to generate one or more of the texture coorinate sets (UV mapping), or to distribute grass blades on the surface, etc.
// Another PolyGroup on the same Mesh may have a different set of vertex attributes.
//

// When you create a PolyGroup, its Vertex attribute list defaults to just a Vertex index and a vertex flags (no normals, texture coordinates (ST), tangents etc.)

// Now, allocate and set the Polygon's VertexNodes
//
    if (0) {
        E3dPolyGroup *LPolyGroup = E3dMesh_PolyGroupAdd(LMesh);
        E3dPolygon *LPolygon = E3dPolyGroup_AddPolygons(LPolyGroup, 8);

// Easy way: use this convenience function to create the Polygon.
// Note that this will only set the Vertex index. It's great for quick geometry prototyping when you don't need texture coordinates, vertex normals etc.
//
//	E3dPolygon_SetVa(LPolygon, LPolyGroup->VertexNodeSize, 5,  0, 1, 2, 3, 4);  // 5 Vertices and the index of each Vertex in the Mesh

// Create the Polygon with a 4-sided hole in it:
        E3dPolygon_SetVa(LPolygon, LPolyGroup->VertexNodeSize, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                         11, -4, 6, 7, 8, 9, -4, 10, 11, 12, 13);    //5 Vertices in the exterior contour and 4 in the hole
    } else {
// More advanded way: manually allocate and set the Polygon's VertexNodes
// We step through VertexNodes with EStruct_Inc(LVertexNode, LPolyGroup->VertexNodeSize) instead of just LVertexNode++ because they may have any size.
//
        {
// Outside
//
            E3dPolyGroup *LPolyGroup = E3dMesh_PolyGroupAdd(LMesh);
            EObject_SetName(LPolyGroup, EStrDup("OutsidePG"), FALSE);
            const EIndex LVertexNodeSize = LPolyGroup->VertexNodeSize;
            E3dPolygon *LPolygon = E3dPolyGroup_AddPolygons(LPolyGroup, 8);

            {
// Front hexagon
//
// Allocate VertexNodes and clear them to 0, so we don't leave things uninitialized
//
// Gabor's note: LNVertexNodes was wrong. It should be exterior Vertices + contour separators + hole Vertices. With a hexagon outline and 1 square hole, it's 6 + 1 + 4 = 11
                const EIndex    LNVertexNodes = 15;
                E3dVertexNode*  LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode*  LVertexNode = LVertexNodes;

// Gabor's note: This is an *alternative* to directly manipulating VertexNodes. Don't use both at the same time. :)
//                E3dPolygon_SetVa(LPolygon, LVertexNodeSize, LNVertexNodes, 0, 1, 2, 3, 4, 5, -4, 15, 14, 13, 12 -4, 16, 17, 18, 19 );

                LVertexNode->VertexID = 0;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 1;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 2;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 3;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 4;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 5;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

// Gabor's note: Specifying a hole is no different than with E3dPolygon_SetVa(). You just set the VertexID like this:
                LVertexNode->VertexID = -4;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 16;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 17;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 18;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 19;EStruct_Inc(LVertexNode, LVertexNodeSize);


// Gabor's note: I left specifying the 2nd hole to you, to practice :)
// BTW, these indices are wrong. They point to they index the Vertices of the top hole in the back.
                LVertexNode->VertexID = -3;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 20;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 21;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 22;EStruct_Inc(LVertexNode, LVertexNodeSize);




                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
// Gabor's note: Corrected these, too:
                LPolygon->NumOfVertices = 13;                  // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 6;
                LPolygon++;
            }

            {
// Back hexagon
//
                const EIndex LNVertexNodes = 11;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 11;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 10;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 9;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 8;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 7;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 6;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LVertexNode->VertexID = -4;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 15;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 14;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 13;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 12;EStruct_Inc(LVertexNode, LVertexNodeSize);



                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 10;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 6;
                LPolygon++;
            }

// Quad side faces
//
            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 0;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 6;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 7;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 1;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }


            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 1;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 7;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 8;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 2;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }

            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 2;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 8;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 9;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 3;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }

            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 3;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 9;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 10;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 4;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }

            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 4;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 10;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 11;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 5;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }

            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 6;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 0;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 5;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 11;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }


            //Front Face hole Top
            /*{
                const EIndex    LNVertexNodes = 4;E3dVertexNode*  LVertexNodes = (E3dVertexNode*)EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode*  LVertexNode = LVertexNodes;


                LVertexNode->VertexID = 15;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 14;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 13;EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 12;EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }*/
            //Back Face hole Top
            /*{
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;


                LVertexNode->VertexID = 16;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 17;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 18;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 19;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }*/




            LPolyGroup->Polygons.Count = LPolygon - LPolyGroup->Polygons.Items;

            E3dPolyGroup_PrintInfo(LPolyGroup, 0, LMesh->Vertices.Items, LMesh->Vertices.Count, LMesh->VertexSize, NULL,
                                   0);
        }
    }

// Inside cut-out
//
    if (0) {
        E3dPolyGroup *LPolyGroup = E3dMesh_PolyGroupAdd(LMesh);
        E3dPolygon *LPolygon = E3dPolyGroup_AddPolygons(LPolyGroup, 10);

// Easy way: use this convenience function to create the Polygon.
// Note that this will only set the Vertex index. It's great for quick geometry prototyping when you don't need texture coordinates, vertex normals etc.
//
//	E3dPolygon_SetVa(LPolygon, LPolyGroup->VertexNodeSize, 5,  0, 1, 2, 3, 4);  // 5 Vertices and the index of each Vertex in the Mesh

// Create the Polygon with a 4-sided hole in it:
        E3dPolygon_SetVa(LPolygon, LPolyGroup->VertexNodeSize, -16, 12, 13, 14, 15, 16, 17, 18,
                         19, 20, 21, 22, 23, 24, 25, 26, 27); //-4, 6, 7, 8, 9, -4, 10, 11, 12, 13);
    } else {
        {
            E3dPolyGroup *LPolyGroup = E3dMesh_PolyGroupAdd(LMesh);
            EObject_SetName(LPolyGroup, EStrDup("InsidePG"), FALSE);
            const EIndex LVertexNodeSize = LPolyGroup->VertexNodeSize;
            E3dPolygon *LPolygon = E3dPolyGroup_AddPolygons(LPolyGroup, 8);


            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 19;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 15;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 12;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 16;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }


            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 19;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 18;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 14;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 15;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }

            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 18;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 17;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 13;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 14;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }

            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 12;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 13;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 17;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 16;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }


            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 22;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 25;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 24;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 21;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }

            {
                const EIndex LNVertexNodes = 3;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 23;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 24;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 25;
                EStruct_Inc(LVertexNode, LVertexNodeSize);


                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 3;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 3;
                LPolygon++;
            }

            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 20;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 23;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 25;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 22;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }


            {
                const EIndex LNVertexNodes = 4;
                E3dVertexNode *LVertexNodes = (E3dVertexNode *) EMallocClr(LVertexNodeSize * LNVertexNodes);
                E3dVertexNode *LVertexNode = LVertexNodes;

                LVertexNode->VertexID = 23;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 20;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 21;
                EStruct_Inc(LVertexNode, LVertexNodeSize);
                LVertexNode->VertexID = 24;
                EStruct_Inc(LVertexNode, LVertexNodeSize);

                LPolygon->VertexNodes = LVertexNodes;
                LPolygon->NumOfVertexNodes = LNVertexNodes;    // Total number of VertexNodes, inlcuding contour separators
                LPolygon->NumOfVertices = 4;                   // Total number of Vertices (contour separators are "pseudo Vertices, so they are not counted)
                LPolygon->NumOfExteriorVertices = 4;
                LPolygon++;
            }

            LPolyGroup->Polygons.Count = LPolygon - LPolyGroup->Polygons.Items;
            E3dPolyGroup_PrintInfo(LPolyGroup, 0, LMesh->Vertices.Items, LMesh->Vertices.Count, LMesh->VertexSize, NULL, 0);
        }
    }

// Be safe and do a full update to the internal accelerators / caches of LMesh
// For performance reasons, you can change a Mesh to your heart's content, then call update once, rather than it being called for every Vertex or Polygon change.
//
    E3dObject_UpdateForDisplay((E3dObject*)LMesh,  E3dUpdateALL, E3dCallALL,  LScene);


// Add the new Model to the Scene. Note that you can build up a hierarchy before adding it to the Scene (or without ever adding it).
//
    E3dScene_NodeHrcAdd(LScene, (E3dNode*)LModel, E3dCallSCENE_CALLBACKS);


// This needs to be called, so instancing will work correctly. It's separate from E3dScene_NodeHrcAdd, for efficiency reasons
//
    E3dScene_ObjectsUpdateModelList(LScene);


// Now, call the automatic layout routine for the Schematic views in EQUINOX-3D (we added a new Model)
// TRUE means we want to automatically frame the Cameras of Schemanic views to show all hierarchies
    E3dScene_LayoutOnSchematics(LScene, TRUE);


// Finally, redraw 3D Windows that are affected by this change.
// EQUINOX-3D has a high-performance rendering system that is optimized to only redraw things that actually changed.
// These flags will tell it that we changed the scene graph, so schematic views will have to be redrawn.
// We also changed a Mesh, so 3DWindows will also need to be redrawn.
//
    E3dWindows_RedrawByChangeFlags(LScene, E3dChgHIERARCHY|E3dChgMeshSHAPE);

    E3dp_PrintMessage(ELogMESSAGE, 5000, "Added Model to the Scene");  // Message type, auto-removal timeout (ms), vararg list (like printf)
}


//========================================
// Entry point of the plugin
//========================================
int E_PluginInit(EPlugin* PPlugin)
{
    _Plugin = PPlugin;

// Use default plugin icon
//
// Location ("Create" tool panel, tooltip, )
    XePushButton_AddImg3(_Buttons[_Buttons_Count++], Plugin, "Tool->Create", "Simple Polygon example", '\0', NULL, NULL, FALSE, "Simple Polygon example", _CB, (EPointer)0);

// Add a button to the 'Create' menu as well
//
    _Buttons[_Buttons_Count++] = XePushButton_Add(Xe_App, "Menu->Create", "Simple Polygon example", '\0', NULL, NULL, FALSE, NULL, _CB, (EPointer)0);

    return(E_SUCCESS);
}


//========================================
// Exit method of the plugin
//========================================
int E_PluginExit(const EBool PExiting)
{
    if(!PExiting || Xe_GUIFreeOnExit)
    {
        int  LI = 0;for(;LI < _Buttons_Count;LI++) { XeItemFree(_Buttons[LI]); }
        _Buttons_Count = 0;
    }

    return(E_SUCCESS);
}