Creating a simple triangulation

Download the source code for this example.

//////////////////////////////////////////////////////////////////////////////
//
// Name        : VulcanSDK_triangulation_example.cpp
// Description : A basic example of using the Vulcan SDK with triangulations
//
// Maptek Pty Ltd, 2020
//
//////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <string.h>
#include <float.h>

#include "mtkExportedApi_ReadWrite.h"

int RunTriangulationExample(char* filename)
{
   int status, i;
   char newFilename[MTK_BUFFER_SIZE];
   char texture_file[MTK_BUFFER_SIZE];
   MTK_Triangulation *triang;
   int numPoints, numAttributes;
   double pointX, pointY, pointZ;
   double maxX, maxY, maxZ;
   char* extension;

   printf("Initialising API using Maptek Extend licence...");
   // Setup environment variable 'VULCAN' for this process to a 
   // Vulcan installation directory for dependencies and licencing. 
   MTK_SetVulcanEnvironmentVariable("C:/Program Files/Maptek/Vulcan 12.0.3");
   // Initialise library using client-side Maptek Extend licence
   if (MTK_API_InitExtend())
   {
      HandleError();
      return 1;
   }
   printf("done\n");

   printf("Opening triangulation %s...", filename);
   triang = MTK_Triangulation_Open(filename);
   if (!triang)
   {
      HandleError();
      return 1;
   }
   printf("done\n");

   status = MTK_Triangulation_IsValid(triang);
   if (status != 1)
   {
      if (status == -1)
      {
         HandleError();
      }
      else
      {
         printf("Triangulation %s is not valid.\n", filename);
      }
      return 1;
   }
   printf("Triangulation %s is valid\n", filename);

   numPoints = MTK_Triangulation_NumPoints(triang);
   if (numPoints == -1)
   {
      HandleError();
      return 1;
   }
   printf("Triangulation %s has %d points\n", filename, numPoints);

   // Check if the triangulation has a texture
   if (MTK_Triangulation_GetTexture(triang, texture_file))
   {
      HandleError();
      return 1;
   }
   else
   {
      printf("Triangulation %s has a texture file: '%s'\n", filename, 
             texture_file);
   }

   int iTextured = MTK_Triangulation_IsTextured(triang);
   if (iTextured == -1)
   {
      HandleError();
      return 1;
   }
   else
   {
      if (iTextured == 1)
      {
         printf("Triangulation %s has texture turned on\n", filename);
      }
      else
      {
         printf("Triangulation %s has texture turned off\n", filename);
      }
   }

   // Create buffer for holding attribute names
   char** names = (char**)malloc(sizeof(char*) * MTK_BUFFER_SIZE); 
   for (int i = 0; i < MTK_BUFFER_SIZE; ++i)
   {
      names[i] = (char*)malloc(sizeof(char) * MTK_BUFFER_SIZE);
   }

   if (MTK_Triangulation_GetAttributeNames(triang, names, &numAttributes))
   {
      HandleError();
      return 1;
   }

   printf("Triangulation %s has %d attributes\n", filename, numAttributes);

   printf("Printing out all attributes of type DOUBLE:\n");
   for (int i = 0; i < numAttributes; ++i)
   {
      MTK_Triangulation_AttributeType type;
      if (MTK_Triangulation_GetAttributeType(triang, names[i], &type))
      {
         HandleError();
         continue;
      }

      if (type == TRI_ATTRIBUTE_DOUBLE)
      {
         double dval;
         if (!MTK_Triangulation_GetAttributeAsDouble(triang, names[i], &dval))
         {
            printf("Triangulation attribute %s (type DOUBLE) has value:" 
                   " %.10f\n", names[i], dval);
         }
         else
         {
            char error[MTK_BUFFER_SIZE];
            MTK_API_GetError(error);
            printf("%s (Triangulation attribute %s)\n", error, names[i]);
         }
      }
   }

   // Free the attribute names buffer
   for (int i = 0; i < MTK_BUFFER_SIZE; ++i)
   {
      free(names[i]);
   }
   free(names);

   // This code finds the 'highest' point in the triangulation, then adds a
   //    small box a bit 'above' that point to the triangulation
   printf("Adding small box to triangulation...");

   maxX = -DBL_MAX; maxY = -DBL_MAX; maxZ = -DBL_MAX;
   for (i = 0; i < numPoints; ++i)
   {
      status = MTK_Triangulation_GetPoint(
                  triang, i, &pointX, &pointY, &pointZ
               );
      if (status)
      {
         HandleError();
         return 1;
      }

      if (pointX > maxX)
      {
         maxX = pointX;
      }
      if (pointY > maxY)
      {
         maxY = pointY;
      }
      if (pointZ > maxZ)
      {
         maxZ = pointZ;
      }
   }

   maxX += 50; maxY += 50; maxZ += 50; // '50' is completely arbitrary
   MTK_Triangulation_AddPoint(triang, maxX, maxY, maxZ);                // numPoints
   MTK_Triangulation_AddPoint(triang, maxX + 50, maxY, maxZ);           // numPoints + 1
   MTK_Triangulation_AddPoint(triang, maxX + 50, maxY + 50, maxZ);      // numPoints + 2
   MTK_Triangulation_AddPoint(triang, maxX, maxY + 50, maxZ);           // numPoints + 3
   MTK_Triangulation_AddPoint(triang, maxX, maxY, maxZ + 50);           // numPoints + 4
   MTK_Triangulation_AddPoint(triang, maxX + 50, maxY, maxZ + 50);      // numPoints + 5
   MTK_Triangulation_AddPoint(triang, maxX + 50, maxY + 50, maxZ + 50); // numPoints + 6
   MTK_Triangulation_AddPoint(triang, maxX, maxY + 50, maxZ + 50);      // numPoints + 7

   MTK_Triangulation_AddTriangle(triang, numPoints, numPoints + 1, numPoints + 2);
   MTK_Triangulation_AddTriangle(triang, numPoints, numPoints + 3, numPoints + 2);
   MTK_Triangulation_AddTriangle(triang, numPoints, numPoints + 4, numPoints + 7);
   MTK_Triangulation_AddTriangle(triang, numPoints, numPoints + 3, numPoints + 7);
   MTK_Triangulation_AddTriangle(triang, numPoints + 4, numPoints + 5, numPoints + 6);
   MTK_Triangulation_AddTriangle(triang, numPoints + 4, numPoints + 7, numPoints + 6);
   MTK_Triangulation_AddTriangle(triang, numPoints + 1, numPoints + 5, numPoints + 6);
   MTK_Triangulation_AddTriangle(triang, numPoints + 1, numPoints + 2, numPoints + 6);
   MTK_Triangulation_AddTriangle(triang, numPoints, numPoints + 1, numPoints + 5);
   MTK_Triangulation_AddTriangle(triang, numPoints, numPoints + 4, numPoints + 5);
   MTK_Triangulation_AddTriangle(triang, numPoints + 3, numPoints + 2, numPoints + 6);
   MTK_Triangulation_AddTriangle(triang, numPoints + 3, numPoints + 7, numPoints + 6);

   printf("done\n");

   // This code adds an attribute to the triangulation
   printf("Adding an attribute to triangulation...");

   if (MTK_Triangulation_AddAttributeString(triang, "TestAttr", "Added Box"))
   {
      HandleError();
      return 1;
   }

   printf("done\n");

   // This code adds a texture to the triangulation
   printf("Adding a texture to triangulation...");

   if (MTK_Triangulation_SetTexture(triang, "sample_texture.jpg", 1))
   {
      HandleError();
      return 1;
   }

   printf("done\n");

   strncpy(newFilename, filename, MTK_BUFFER_SIZE - 1);
   newFilename[MTK_BUFFER_SIZE - 1] = '\0';
   extension = strstr(newFilename, ".00t");
   if (extension && strlen(newFilename) < MTK_BUFFER_SIZE - 9)
   {
      strcpy(extension, "_with_box.00t");
   }
   else
   {
      strcpy(newFilename, "NewTriMadeFromExampleWithABox.00t");
   }

   printf("Saving triangulation as %s...", newFilename);
   if (MTK_Triangulation_Save(triang, newFilename))
   {
      HandleError();
      return 1;
   }
   printf("done\n");

   if (MTK_Triangulation_Close(triang))
   {
      HandleError();
      return 1;
   }
			
   MTK_API_Terminate();
   return 0;
}
			
static void HandleError()
{
	char error[MTK_BUFFER_SIZE];
	MTK_API_GetError(error);
	printf("%s\n", error);
	MTK_API_Terminate();
}