Example #1
0
bool TriangulatorAdaptor::triangulate(int *triangleIndexes) {
    int XX, YY;
    from3DTo2D(XX, YY);

    map<pair<double, double> , int> coorToPosMap; // coordinate to position map
    for (int i = 0; i < polygon.size(); i++) {
        coorToPosMap.insert(
                pair<pair<double, double> , int>(
                        pair<double, double>(polygon[i][XX], polygon[i][YY]), i));
    }

    TPPLPoly poly;
    poly.Init(polygon.size());
    for (int i = 0; i < polygon.size(); i++) {
        poly[i].x = polygon[i][XX];
        poly[i].y = polygon[i][YY];
    }

    if (poly.GetOrientation() == TPPL_CW) {
        isClockwise = true;
        poly.Invert(); // polygon has to be counter-clockwise
    } else if(poly.GetOrientation() == TPPL_CCW) {
        isClockwise = false;
    } else {
    	return false;
    }

    list<TPPLPoly> triangles;

    TPPLPartition triangulator; // see http://code.google.com/p/polypartition/
    int success = triangulator.Triangulate_OPT(&poly, &triangles);
    if (success != 1) {
        cout << "Error: polygon cannot be triangulated!" << endl;
        cout << "Polygon:" << endl;
        for (int i=0; i<polygon.size(); i++) {
            cout << polygon[i][0] << "   " << polygon[i][1] << "   " << polygon[i][2] << endl;
        }
		return false;
    }
    //assert(success == 1);
    assert(triangles.size() +2 == polygon.size());
    int count = 0;
    for (list<TPPLPoly>::iterator it = triangles.begin(); it != triangles.end(); it++) {
        if (!isClockwise) {
            for (int j = 0; j < 3; j++) {
                triangleIndexes[count * 3 + j] = coorToPosMap[pair<double, double>((*it)[j].x,
                        (*it)[j].y)];
            }
        } else {
            for (int j = 0; j < 3; j++) {
                triangleIndexes[count * 3 + 2 - j] = coorToPosMap[pair<double, double>((*it)[j].x,
                        (*it)[j].y)];
            }
        }
        count++;
    }
    assert(count == triangles.size());
    return true;
}
Example #2
0
// Initialize polypartition TPPLPoly from a list of indices and vertices
//
// verts     - 3D polygon vertex vectors
// xind,yind - Indices of 3D vectors to extract as x and y coordinates for 2D
//             triangulation computation.
// inds,size - Array of indices into the `verts` list
// isHole    - Value for the hole flag, and to determine the orientation
static void initTPPLPoly(TPPLPoly& poly,
                         const std::vector<float>& verts,
                         int xind, int yind,
                         const GLuint* inds, int size,
                         bool isHole)
{
    // Check for explicitly closed polygons (last and first vertices equal) and
    // discard the last vertex in these cases.  This is a pretty stupid
    // convention, but the OGC have blessed it and now we've got a bunch of
    // geospatial formats (kml, WKT, GeoJSON) which require it.  Sigh.
    // http://gis.stackexchange.com/questions/10308/why-do-valid-polygons-repeat-the-same-start-and-end-point/10309#10309
    if (inds[0] == inds[size-1] ||
        (verts[3*inds[0]+0] == verts[3*inds[size-1]+0] &&
         verts[3*inds[0]+1] == verts[3*inds[size-1]+1] &&
         verts[3*inds[0]+2] == verts[3*inds[size-1]+2]))
    {
        g_logger.warning_limited("Ignoring duplicate final vertex in explicitly closed polygon");
        size -= 1;
    }
    // Copy into polypartition data structure
    poly.Init(size);
    for (int i = 0; i < size; ++i)
    {
        poly[i].x = verts[3*inds[i]+xind];
        poly[i].y = verts[3*inds[i]+yind];
        poly[i].id = inds[i];
    }
    int orientation = poly.GetOrientation();
    // Invert so that outer = ccw, holes = cw
    if ((orientation == TPPL_CW) ^ isHole)
        poly.Invert();
    poly.SetHole(isHole);
}
Example #3
0
void make_poly(float* buf, int pnt_sz, TPPLPoly& poly)
{
	poly.Init(pnt_sz);

	for (int k(0); k < pnt_sz; k++)
	{
		poly[k].x = buf[2 * k];
		poly[k].y = buf[2 * k + 1];
	}

	if (poly.GetOrientation() == TPPL_CW)
	{
		poly.SetHole(true);
	}

}