I'm trying to use J. Shewchuk's mesh generation library Triangle in a C++ program. To do this I first downloaded triangle.h and triangle.c from the Triangle website. Then, in triangle.c I included these defines
#define NO_TIMER
#define TRILIBRARY
#define ANSI_DECLARATORS
I then compiled this into a library file, Triangle.lib, and put this in my C++ project's lib folder (and linked to it). I also copied triangle.h into my project's include folder and modified it to be wrapped with extern "C"
. With this my project compiles fine and can use the functions from triangle.h.
I then copied the example found in tricall.h into my project as follows:
#define REAL double
struct triangulateio in, mid, out, vorout;
in.numberofpoints = 4;
in.numberofpointattributes = 1;
in.pointlist = (REAL*)malloc(in.numberofpoints * 2 * sizeof(REAL));
in.pointlist[0] = 0.0;
in.pointlist[1] = 0.0;
in.pointlist[2] = 1.0;
in.pointlist[3] = 0.0;
in.pointlist[4] = 1.0;
in.pointlist[5] = 10.0;
in.pointlist[6] = 0.0;
in.pointlist[7] = 10.0;
in.pointattributelist = (REAL*)malloc(in.numberofpoints * in.numberofpointattributes * sizeof(REAL));
in.pointattributelist[0] = 0.0;
in.pointattributelist[1] = 1.0;
in.pointattributelist[2] = 11.0;
in.pointattributelist[3] = 10.0;
in.pointmarkerlist = (int*)malloc(in.numberofpoints * sizeof(int));
in.pointmarkerlist[0] = 0;
in.pointmarkerlist[1] = 2;
in.pointmarkerlist[2] = 0;
in.pointmarkerlist[3] = 0;
in.numberofsegments = 0;
in.numberofholes = 0;
in.numberofregions = 1;
in.regionlist = (REAL*)malloc(in.numberofregions * 4 * sizeof(REAL));
in.regionlist[0] = 0.5;
in.regionlist[1] = 5.0;
in.regionlist[2] = 7.0;
in.regionlist[3] = 0.1;
/* Make necessary initializations so that Triangle can return a */
/* triangulation in `mid' and a voronoi diagram in `vorout'. */
mid.pointlist = (REAL*)NULL; /* Not needed if -N switch used. */
mid.pointattributelist = (REAL*)NULL;
mid.pointmarkerlist = (int*)NULL; /* Not needed if -N or -B switch used. */
mid.trianglelist = (int*)NULL; /* Not needed if -E switch used. */
mid.triangleattributelist = (REAL*)NULL;
mid.neighborlist = (int*)NULL; /* Needed only if -n switch used. */
mid.segmentlist = (int*)NULL;
mid.segmentmarkerlist = (int*)NULL;
mid.edgelist = (int*)NULL; /* Needed only if -e switch used. */
mid.edgemarkerlist = (int*)NULL; /* Needed if -e used and -B not used. */
vorout.pointlist = (REAL*)NULL; /* Needed only if -v switch used. */
vorout.pointattributelist = (REAL*)NULL;
vorout.edgelist = (int*)NULL; /* Needed only if -v switch used. */
vorout.normlist = (REAL*)NULL; /* Needed only if -v switch used. */
triangulate(const_cast<char*>("pczAevn"), &in, &mid, &vorout);
However, I get an error on the last line where I call triangulate. The error is "Exception thrown: write access violation. vertexloop was 0x8E064FF0", and comes from line 14130 in triangle.c
x = vertexloop[0] = pointlist[coordindex++];
Any idea why this error is occurring? Is my approach to including the C code in my C++ program the right way to do so?
Fortunately I've found a C++ version of the code on Github by libigl https://github.com/libigl/triangle. As before, need to include:
#define NO_TIMER
#define TRILIBRARY
#define ANSI_DECLARATORS
In triangle.cpp
. Also now including the source files directly in my project instead of compiling to a separate library. With this, no longer get the memory read address error. Looking at the difference between triangle.cpp
and triangle.c
libigl has added this line:
/* Define the size large enough to store and operate on a pointer. */
#define INT_PTR unsigned long long
And everywhere in triangle.c
that previously had a pointer to unsigned long
has been replaced with INT_PTR
. I suspect this has fixed what was initially causing the error.