49 mTriangularMesh.
update( &mNativeMesh );
54 const QVector<double> &datasetValues,
56 mTriangularMesh( triangularMesh )
57 , mNativeMesh( nativeMesh )
58 , mDatasetValues( datasetValues )
59 , mScalarActiveFaceFlagValues( scalarActiveFaceFlagValues )
75 populateCache( index, method );
82 if ( min_value > max_value )
84 const double tmp = max_value;
85 max_value = min_value;
89 QVector<QgsGeometry> multiPolygon;
92 const QVector<QgsMeshVertex> vertices = mTriangularMesh.
vertices();
96 for (
int i = 0; i < mTriangularMesh.
triangles().size(); ++i )
101 const int nativeIndex = trianglesToNativeFaces.at( i );
102 if ( !mScalarActiveFaceFlagValues.
active( nativeIndex ) )
106 const int indices[3] =
113 const QVector<QgsMeshVertex> coords =
115 vertices.at( indices[0] ),
116 vertices.at( indices[1] ),
117 vertices.at( indices[2] )
120 const double values[3] =
122 mDatasetValues.at( indices[0] ),
123 mDatasetValues.at( indices[1] ),
124 mDatasetValues.at( indices[2] )
128 if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
132 if ( ( ( min_value > values[0] ) && ( min_value > values[1] ) && ( min_value > values[2] ) ) ||
133 ( ( max_value < values[0] ) && ( max_value < values[1] ) && ( max_value < values[2] ) ) )
136 const bool valueInRange[3] =
138 ( min_value <= values[0] ) &&( max_value >= values[0] ),
139 ( min_value <= values[1] ) &&( max_value >= values[1] ),
140 ( min_value <= values[2] ) &&( max_value >= values[2] )
144 if ( valueInRange[0] && valueInRange[1] && valueInRange[2] )
146 QVector<QgsMeshVertex> ring = coords;
147 ring.push_back( coords[0] );
148 std::unique_ptr< QgsLineString > ext = std::make_unique< QgsLineString> ( coords );
149 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
150 poly->setExteriorRing( ext.release() );
151 multiPolygon.push_back(
QgsGeometry( std::move( poly ) ) );
156 QVector<QgsMeshVertex> ring;
157 for (
int i = 0; i < 3; ++i )
159 const int j = ( i + 1 ) % 3;
161 if ( valueInRange[i] )
163 if ( valueInRange[j] )
166 if ( !ring.contains( coords[i] ) )
167 ring.push_back( coords[i] );
168 if ( !ring.contains( coords[j] ) )
169 ring.push_back( coords[j] );
174 if ( !ring.contains( coords[i] ) )
175 ring.push_back( coords[i] );
177 double value = max_value;
178 if ( values[i] > values[j] )
182 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
184 if ( !ring.contains( xy ) )
185 ring.push_back( xy );
190 if ( valueInRange[j] )
193 double value = max_value;
194 if ( values[i] < values[j] )
199 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
201 if ( !ring.contains( xy ) )
202 ring.push_back( xy );
205 if ( !ring.contains( coords[j] ) )
206 ring.push_back( coords[j] );
213 double value1 = max_value;
214 double value2 = max_value;
215 if ( values[i] < values[j] )
217 if ( ( min_value < values[i] ) || ( max_value > values[j] ) )
225 if ( ( min_value < values[j] ) || ( max_value > values[i] ) )
232 const double fraction1 = ( value1 - values[i] ) / ( values[j] - values[i] );
234 if ( !ring.contains( xy1 ) )
235 ring.push_back( xy1 );
237 const double fraction2 = ( value2 - values[i] ) / ( values[j] - values[i] );
239 if ( !ring.contains( xy2 ) )
240 ring.push_back( xy2 );
246 if ( ring.size() > 2 )
248 std::unique_ptr< QgsLineString > ext = std::make_unique< QgsLineString> ( ring );
249 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
250 poly->setExteriorRing( ext.release() );
251 multiPolygon.push_back(
QgsGeometry( std::move( poly ) ) );
256 if ( multiPolygon.isEmpty() )
276 populateCache( index, method );
284 QSet<QPair<int, int>> exactEdges;
287 const QVector<QgsMeshVertex> vertices = mTriangularMesh.
vertices();
291 for (
int i = 0; i < mTriangularMesh.
triangles().size(); ++i )
296 const int nativeIndex = trianglesToNativeFaces.at( i );
297 if ( !mScalarActiveFaceFlagValues.
active( nativeIndex ) )
302 const int indices[3] =
309 const QVector<QgsMeshVertex> coords =
311 vertices.at( indices[0] ),
312 vertices.at( indices[1] ),
313 vertices.at( indices[2] )
316 const double values[3] =
318 mDatasetValues.at( indices[0] ),
319 mDatasetValues.at( indices[1] ),
320 mDatasetValues.at( indices[2] )
324 if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
328 if ( ( ( value > values[0] ) && ( value > values[1] ) && ( value > values[2] ) ) ||
329 ( ( value < values[0] ) && ( value < values[1] ) && ( value < values[2] ) ) )
339 for (
int i = 0; i < 3; ++i )
341 const int j = ( i + 1 ) % 3;
343 if ( ( ( value > values[i] ) && ( value > values[j] ) ) ||
344 ( ( value < values[i] ) && ( value < values[j] ) ) )
350 if ( exactEdges.contains( { indices[i], indices[j] } ) || exactEdges.contains( { indices[j], indices[i] } ) )
356 exactEdges.insert( { indices[i], indices[j] } );
357 std::unique_ptr<QgsLineString> line(
new QgsLineString( coords[i], coords[j] ) );
358 multiLineString->addGeometry( line.release() );
370 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
373 if ( std::isnan( tmp.
x() ) )
381 std::unique_ptr<QgsLineString> line(
new QgsLineString( tmp, xy ) );
382 multiLineString->addGeometry( line.release() );
389 if ( multiLineString->isEmpty() )
406 if ( mCachedIndex != index )
409 const int count = scalarDataOnVertices ? mNativeMesh.
vertices.count() : mNativeMesh.
faces.count();
420 mDatasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
424 mDatasetValues = QVector<double>( count, std::numeric_limits<double>::quiet_NaN() );
431 mNativeMesh.
faces.count() );
434 if ( ( !scalarDataOnVertices ) )
436 mDatasetValues = QgsMeshLayerUtils::interpolateFromFacesData(
440 &mScalarActiveFaceFlagValues,