static void _makeWalls( const QgsCurve &ring, bool ccw, float extrusionHeight, QVector<float> &data, bool addNormals, double originX, double originY ) { // we need to find out orientation of the ring so that the triangles we generate // face the right direction // (for exterior we want clockwise order, for holes we want counter-clockwise order) bool is_counter_clockwise = _isRingCounterClockWise( ring ); QgsVertexId::VertexType vt; QgsPoint pt; QgsPoint ptPrev; ring.pointAt( is_counter_clockwise == ccw ? 0 : ring.numPoints() - 1, ptPrev, vt ); for ( int i = 1; i < ring.numPoints(); ++i ) { ring.pointAt( is_counter_clockwise == ccw ? i : ring.numPoints() - i - 1, pt, vt ); float x0 = ptPrev.x() - originX, y0 = ptPrev.y() - originY; float x1 = pt.x() - originX, y1 = pt.y() - originY; float z0 = ptPrev.z(); float z1 = pt.z(); // make a quad make_quad( x0, y0, z0, x1, y1, z1, extrusionHeight, data, addNormals ); ptPrev = pt; } }
static bool _isRingCounterClockWise( const QgsCurve &ring ) { double a = 0; int count = ring.numPoints(); QgsVertexId::VertexType vt; QgsPoint pt, ptPrev; ring.pointAt( 0, ptPrev, vt ); for ( int i = 1; i < count + 1; ++i ) { ring.pointAt( i % count, pt, vt ); a += ptPrev.x() * pt.y() - ptPrev.y() * pt.x(); ptPrev = pt; } return a > 0; // clockwise if a is negative }