48 mNativeMesh.reset(
new QgsMesh() );
52 mTriangularMesh->update( mNativeMesh.get() );
66 if ( !mTriangularMesh )
69 if ( min_value > max_value )
71 double tmp = max_value;
72 max_value = min_value;
76 QVector<QgsGeometry> multiPolygon;
79 populateCache( index, method );
80 const QVector<QgsMeshVertex> vertices = mTriangularMesh->vertices();
81 const QVector<int> &trianglesToNativeFaces = mTriangularMesh->trianglesToNativeFaces();
84 for (
int i = 0; i < mTriangularMesh->triangles().size(); ++i )
89 int nativeIndex = trianglesToNativeFaces.at( i );
90 if ( !mScalarActiveFaceFlagValues.
active( nativeIndex ) )
93 const QgsMeshFace &triangle = mTriangularMesh->triangles().at( i );
94 const int indices[3] =
101 const QVector<QgsMeshVertex> coords =
103 vertices.at( indices[0] ),
104 vertices.at( indices[1] ),
105 vertices.at( indices[2] )
108 const double values[3] =
110 mDatasetValues.at( indices[0] ),
111 mDatasetValues.at( indices[1] ),
112 mDatasetValues.at( indices[2] )
116 if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
120 if ( ( ( min_value > values[0] ) && ( min_value > values[1] ) && ( min_value > values[2] ) ) ||
121 ( ( max_value < values[0] ) && ( max_value < values[1] ) && ( max_value < values[2] ) ) )
124 const bool valueInRange[3] =
126 ( min_value <= values[0] ) &&( max_value >= values[0] ),
127 ( min_value <= values[1] ) &&( max_value >= values[1] ),
128 ( min_value <= values[2] ) &&( max_value >= values[2] )
132 if ( valueInRange[0] && valueInRange[1] && valueInRange[2] )
134 QVector<QgsMeshVertex> ring = coords;
135 ring.push_back( coords[0] );
136 std::unique_ptr< QgsLineString > ext = qgis::make_unique< QgsLineString> ( coords );
137 std::unique_ptr< QgsPolygon > poly = qgis::make_unique< QgsPolygon >();
138 poly->setExteriorRing( ext.release() );
139 multiPolygon.push_back(
QgsGeometry( std::move( poly ) ) );
144 QVector<QgsMeshVertex> ring;
145 for (
int i = 0; i < 3; ++i )
147 const int j = ( i + 1 ) % 3;
149 if ( valueInRange[i] )
151 if ( valueInRange[j] )
154 if ( !ring.contains( coords[i] ) )
155 ring.push_back( coords[i] );
156 if ( !ring.contains( coords[j] ) )
157 ring.push_back( coords[j] );
162 if ( !ring.contains( coords[i] ) )
163 ring.push_back( coords[i] );
165 double value = max_value;
166 if ( values[i] > values[j] )
170 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
172 if ( !ring.contains( xy ) )
173 ring.push_back( xy );
178 if ( valueInRange[j] )
181 double value = max_value;
182 if ( values[i] < values[j] )
187 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
189 if ( !ring.contains( xy ) )
190 ring.push_back( xy );
193 if ( !ring.contains( coords[j] ) )
194 ring.push_back( coords[j] );
201 double value1 = max_value;
202 double value2 = max_value;
203 if ( values[i] < values[j] )
205 if ( ( min_value < values[i] ) || ( max_value > values[j] ) )
213 if ( ( min_value < values[j] ) || ( max_value > values[i] ) )
220 const double fraction1 = ( value1 - values[i] ) / ( values[j] - values[i] );
222 if ( !ring.contains( xy1 ) )
223 ring.push_back( xy1 );
225 const double fraction2 = ( value2 - values[i] ) / ( values[j] - values[i] );
227 if ( !ring.contains( xy2 ) )
228 ring.push_back( xy2 );
234 if ( ring.size() > 2 )
236 std::unique_ptr< QgsLineString > ext = qgis::make_unique< QgsLineString> ( ring );
237 std::unique_ptr< QgsPolygon > poly = qgis::make_unique< QgsPolygon >();
238 poly->setExteriorRing( ext.release() );
239 multiPolygon.push_back(
QgsGeometry( std::move( poly ) ) );
244 if ( multiPolygon.isEmpty() )
261 if ( !mTriangularMesh )
265 QSet<QPair<int, int>> exactEdges;
268 populateCache( index, method );
269 QVector<QgsMeshVertex> vertices = mTriangularMesh->vertices();
270 const QVector<int> &trianglesToNativeFaces = mTriangularMesh->trianglesToNativeFaces();
273 for (
int i = 0; i < mTriangularMesh->triangles().size(); ++i )
278 int nativeIndex = trianglesToNativeFaces.at( i );
279 if ( !mScalarActiveFaceFlagValues.
active( nativeIndex ) )
282 const QgsMeshFace &triangle = mTriangularMesh->triangles().at( i );
284 const int indices[3] =
291 const QVector<QgsMeshVertex> coords =
293 vertices.at( indices[0] ),
294 vertices.at( indices[1] ),
295 vertices.at( indices[2] )
298 const double values[3] =
300 mDatasetValues.at( indices[0] ),
301 mDatasetValues.at( indices[1] ),
302 mDatasetValues.at( indices[2] )
306 if ( std::isnan( values[0] ) || std::isnan( values[1] ) || std::isnan( values[2] ) )
310 if ( ( ( value > values[0] ) && ( value > values[1] ) && ( value > values[2] ) ) ||
311 ( ( value < values[0] ) && ( value < values[1] ) && ( value < values[2] ) ) )
321 for (
int i = 0; i < 3; ++i )
323 const int j = ( i + 1 ) % 3;
325 if ( ( ( value > values[i] ) && ( value > values[j] ) ) ||
326 ( ( value < values[i] ) && ( value < values[j] ) ) )
332 if ( exactEdges.contains( { indices[i], indices[j] } ) || exactEdges.contains( { indices[j], indices[i] } ) )
338 exactEdges.insert( { indices[i], indices[j] } );
339 std::unique_ptr<QgsLineString> line(
new QgsLineString( coords[i], coords[j] ) );
340 multiLineString->addGeometry( line.release() );
352 const double fraction = ( value - values[i] ) / ( values[j] - values[i] );
355 if ( std::isnan( tmp.
x() ) )
363 std::unique_ptr<QgsLineString> line(
new QgsLineString( tmp, xy ) );
364 multiLineString->addGeometry( line.release() );
371 if ( multiLineString->isEmpty() )
385 if ( mCachedIndex != index )
388 int count = scalarDataOnVertices ? mNativeMesh->vertices.count() : mNativeMesh->faces.count();
399 mDatasetValues = QgsMeshLayerUtils::calculateMagnitudes( vals );
403 mDatasetValues = QVector<double>( count, std::numeric_limits<double>::quiet_NaN() );
410 mNativeMesh->faces.count() );
413 if ( ( !scalarDataOnVertices ) )
415 mDatasetValues = QgsMeshLayerUtils::interpolateFromFacesData(
418 mTriangularMesh.get(),
419 &mScalarActiveFaceFlagValues,