80 if ( min_value > max_value )
82 const double tmp = max_value;
83 max_value = min_value;
87 QVector<QgsGeometry> multiPolygon;
90 const QVector<QgsMeshVertex> vertices = mTriangularMesh.
vertices();
91 const QVector<int> &trianglesToNativeFaces = mTriangularMesh.trianglesToNativeFaces();
94 for (
int i = 0; i < mTriangularMesh.triangles().size(); ++i )
99 const int nativeIndex = trianglesToNativeFaces.at( i );
100 if ( !mScalarActiveFaceFlagValues.active( nativeIndex ) )
103 const QgsMeshFace &triangle = mTriangularMesh.triangles().at( i );
104 const int indices[3] = {
110 const QVector<QgsMeshVertex> coords = {
111 vertices.at( indices[0] ),
112 vertices.at( indices[1] ),
113 vertices.at( indices[2] )
116 const double values[3] = {
117 mDatasetValues.at( indices[0] ),
118 mDatasetValues.at( indices[1] ),
119 mDatasetValues.at( indices[2] )
123 if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
127 if ( ( ( min_value > values[0] ) && ( min_value > values[1] ) && ( min_value > values[2] ) ) || ( ( max_value < values[0] ) && ( max_value < values[1] ) && ( max_value < values[2] ) ) )
130 const bool valueInRange[3] = {
131 ( min_value <= values[0] ) && ( max_value >= values[0] ),
132 ( min_value <= values[1] ) && ( max_value >= values[1] ),
133 ( min_value <= values[2] ) && ( max_value >= values[2] )
137 if ( valueInRange[0] && valueInRange[1] && valueInRange[2] )
139 QVector<QgsMeshVertex> ring = coords;
140 ring.push_back( coords[0] );
141 auto ext = std::make_unique<QgsLineString>( coords );
142 auto poly = std::make_unique<QgsPolygon>();
143 poly->setExteriorRing( ext.release() );
144 multiPolygon.push_back(
QgsGeometry( std::move( poly ) ) );
149 QVector<QgsMeshVertex> ring;
150 for (
int i = 0; i < 3; ++i )
152 const int j = ( i + 1 ) % 3;
154 if ( valueInRange[i] )
156 if ( valueInRange[j] )
159 if ( !ring.contains( coords[i] ) )
160 ring.push_back( coords[i] );
161 if ( !ring.contains( coords[j] ) )
162 ring.push_back( coords[j] );
167 if ( !ring.contains( coords[i] ) )
168 ring.push_back( coords[i] );
170 double value = max_value;
171 if ( values[i] > values[j] )
175 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
177 if ( !ring.contains( xy ) )
178 ring.push_back( xy );
183 if ( valueInRange[j] )
186 double value = max_value;
187 if ( values[i] < values[j] )
192 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
194 if ( !ring.contains( xy ) )
195 ring.push_back( xy );
198 if ( !ring.contains( coords[j] ) )
199 ring.push_back( coords[j] );
205 double value1 = max_value;
206 double value2 = max_value;
207 if ( values[i] < values[j] )
209 if ( ( min_value < values[i] ) || ( max_value > values[j] ) )
217 if ( ( min_value < values[j] ) || ( max_value > values[i] ) )
224 const double fraction1 = ( value1 - values[i] ) / ( values[j] - values[i] );
226 if ( !ring.contains( xy1 ) )
227 ring.push_back( xy1 );
229 const double fraction2 = ( value2 - values[i] ) / ( values[j] - values[i] );
231 if ( !ring.contains( xy2 ) )
232 ring.push_back( xy2 );
238 if ( ring.size() > 2 )
240 auto ext = std::make_unique<QgsLineString>( ring );
241 auto poly = std::make_unique<QgsPolygon>();
242 poly->setExteriorRing( ext.release() );
243 multiPolygon.push_back(
QgsGeometry( std::move( poly ) ) );
248 if ( multiPolygon.isEmpty() )
272 auto multiLineString = std::make_unique<QgsMultiLineString>();
273 QSet<QPair<int, int>> exactEdges;
276 const QVector<QgsMeshVertex> vertices = mTriangularMesh.vertices();
277 const QVector<int> &trianglesToNativeFaces = mTriangularMesh.trianglesToNativeFaces();
280 for (
int i = 0; i < mTriangularMesh.triangles().size(); ++i )
285 const int nativeIndex = trianglesToNativeFaces.at( i );
286 if ( !mScalarActiveFaceFlagValues.active( nativeIndex ) )
289 const QgsMeshFace &triangle = mTriangularMesh.triangles().at( i );
291 const int indices[3] = {
297 const QVector<QgsMeshVertex> coords = {
298 vertices.at( indices[0] ),
299 vertices.at( indices[1] ),
300 vertices.at( indices[2] )
303 const double values[3] = {
304 mDatasetValues.at( indices[0] ),
305 mDatasetValues.at( indices[1] ),
306 mDatasetValues.at( indices[2] )
310 if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
314 if ( ( ( value > values[0] ) && ( value > values[1] ) && ( value > values[2] ) ) || ( ( value < values[0] ) && ( value < values[1] ) && ( value < values[2] ) ) )
324 for (
int i = 0; i < 3; ++i )
326 const int j = ( i + 1 ) % 3;
328 if ( ( ( value > values[i] ) && ( value > values[j] ) ) || ( ( value < values[i] ) && ( value < values[j] ) ) )
334 if ( exactEdges.contains( { indices[i], indices[j] } ) || exactEdges.contains( { indices[j], indices[i] } ) )
340 exactEdges.insert( { indices[i], indices[j] } );
341 auto line = std::make_unique<QgsLineString>( coords[i], coords[j] );
342 multiLineString->addGeometry( line.release() );
354 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
357 if ( std::isnan( tmp.
x() ) )
365 auto line = std::make_unique<QgsLineString>( tmp, xy );
366 multiLineString->addGeometry( line.release() );
373 if ( multiLineString->isEmpty() )