#3700 Add visual picking marker and improve map results

* Fix "off by half a cell" errors and improve smoothness using averaging and interpolation
This commit is contained in:
Gaute Lindkvist
2018-11-15 21:40:10 +01:00
parent 71f90b1337
commit 42d3e65416
8 changed files with 497 additions and 204 deletions

View File

@@ -31,7 +31,7 @@ RivContourMapProjectionPartMgr::RivContourMapProjectionPartMgr(RimContourMapProj
//--------------------------------------------------------------------------------------------------
void RivContourMapProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform) const
{
cvf::ref<cvf::DrawableGeo> drawable = createDrawable(displayCoordTransform);
cvf::ref<cvf::DrawableGeo> drawable = createProjectionMapDrawable(displayCoordTransform);
if (drawable.notNull() && drawable->boundingBox().isValid())
{
cvf::ref<cvf::Part> part = new cvf::Part;
@@ -55,7 +55,7 @@ void RivContourMapProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList
{
caf::MeshEffectGenerator meshEffectGen(cvf::Color3::BLACK);
meshEffectGen.setLineWidth(1.0f);
meshEffectGen.createAndConfigurePolygonOffsetRenderState(caf::PO_2);
meshEffectGen.createAndConfigurePolygonOffsetRenderState(caf::PO_1);
cvf::ref<cvf::Effect> effect = meshEffectGen.generateCachedEffect();
cvf::ref<cvf::Part> part = new cvf::Part;
@@ -69,28 +69,79 @@ void RivContourMapProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivContourMapProjectionPartMgr::appendPickPointVisToModel(cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform) const
{
cvf::ref<cvf::DrawableGeo> drawable = createPickPointVisDrawable(displayCoordTransform);
if (drawable.notNull() && drawable->boundingBox().isValid())
{
caf::MeshEffectGenerator meshEffectGen(cvf::Color3::MAGENTA);
meshEffectGen.setLineWidth(2.0f);
meshEffectGen.createAndConfigurePolygonOffsetRenderState(caf::PO_2);
cvf::ref<cvf::Effect> effect = meshEffectGen.generateCachedEffect();
cvf::ref<cvf::Part> part = new cvf::Part;
part->setDrawable(drawable.p());
part->setEffect(effect.p());
part->setSourceInfo(new RivMeshLinesSourceInfo(m_contourMapProjection.p()));
model->addPart(part.p());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Vec2fArray> RivContourMapProjectionPartMgr::createTextureCoords() const
{
cvf::Vec2ui patchSize = m_contourMapProjection->surfaceGridSize();
cvf::Vec2ui patchSize = m_contourMapProjection->vertexGridSize();
cvf::ref<cvf::Vec2fArray> textureCoords = new cvf::Vec2fArray(m_contourMapProjection->vertexCount());
cvf::ref<cvf::Vec2fArray> textureCoords = new cvf::Vec2fArray(m_contourMapProjection->numberOfVertices());
for (uint j = 0; j < patchSize.y(); ++j)
#pragma omp parallel for
for (int j = 0; j < static_cast<int>(patchSize.y()); ++j)
{
for (uint i = 0; i < patchSize.x(); ++i)
for (int i = 0; i < static_cast<int>(patchSize.x()); ++i)
{
if (m_contourMapProjection->hasResultAt(i, j))
if (m_contourMapProjection->hasResultAtVertex(i, j))
{
double value = m_contourMapProjection->value(i, j);
(*textureCoords)[i + j * patchSize.x()] =
m_contourMapProjection->legendConfig()->scalarMapper()->mapToTextureCoord(value);
double value = m_contourMapProjection->valueAtVertex(i, j);
cvf::Vec2f textureCoord = m_contourMapProjection->legendConfig()->scalarMapper()->mapToTextureCoord(value);
textureCoord.y() = 0.0;
(*textureCoords)[i + j * patchSize.x()] = textureCoord;
}
else
{
(*textureCoords)[i + j * patchSize.x()] = cvf::Vec2f(1.0, 1.0);
RiaWeightedMeanCalculator<double> calc;
for (int jj = j - 1; jj <= j + 1; ++jj)
{
for (int ii = i - 1; ii <= i + 1; ++ii)
{
if (jj >= 0 && ii >= 0 && jj < static_cast<int>(patchSize.y()) && ii < static_cast<int>(patchSize.x()))
{
if (!(ii == i && jj == j) && m_contourMapProjection->hasResultAtVertex(ii, jj))
{
double value = m_contourMapProjection->valueAtVertex(ii, jj);
calc.addValueAndWeight(value, 1. / std::sqrt((i - ii)*(i - ii) + (j - jj)*(j - jj)));
}
}
}
}
if (calc.validAggregatedWeight())
{
const double maxTheoreticalWeightSum = 4.0 + 4.0 / std::sqrt(2.0);
double value = calc.weightedMean();
cvf::Vec2f textureCoord = m_contourMapProjection->legendConfig()->scalarMapper()->mapToTextureCoord(value);
textureCoord.y() = 1.0 - calc.aggregatedWeight() / maxTheoreticalWeightSum;
(*textureCoords)[i + j * patchSize.x()] = textureCoord;
}
else
{
(*textureCoords)[i + j * patchSize.x()] = cvf::Vec2f(0.0, 1.0);
}
}
}
}
@@ -100,46 +151,16 @@ cvf::ref<cvf::Vec2fArray> RivContourMapProjectionPartMgr::createTextureCoords()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivContourMapProjectionPartMgr::removeTrianglesWithNoResult(cvf::UIntArray* vertices) const
{
std::vector<cvf::uint> trianglesWithResult;
for (size_t n = 0; n < vertices->size(); n += 3)
{
bool anyInvalid = false;
for (size_t t = 0; !anyInvalid && t < 3; ++t)
{
cvf::uint vertexNumber = (*vertices)[n + t];
cvf::Vec2ui ij = m_contourMapProjection->ijFromGridIndex(vertexNumber);
if (!m_contourMapProjection->hasResultAt(ij.x(), ij.y()))
{
anyInvalid = true;
}
}
for (size_t t = 0; !anyInvalid && t < 3; ++t)
{
cvf::uint vertexNumber = (*vertices)[n + t];
trianglesWithResult.push_back(vertexNumber);
}
}
(*vertices) = cvf::UIntArray(trianglesWithResult);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivContourMapProjectionPartMgr::createDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const
cvf::ref<cvf::DrawableGeo> RivContourMapProjectionPartMgr::createProjectionMapDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const
{
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray;
m_contourMapProjection->generateVertices(vertexArray.p(), displayCoordTransform);
cvf::Vec2ui patchSize = m_contourMapProjection->surfaceGridSize();
cvf::Vec2ui patchSize = m_contourMapProjection->vertexGridSize();
// Surface
cvf::ref<cvf::UIntArray> faceList = new cvf::UIntArray;
cvf::GeometryUtils::tesselatePatchAsTriangles(patchSize.x(), patchSize.y(), 0u, true, faceList.p());
removeTrianglesWithNoResult(faceList.p());
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_TRIANGLES, faceList.p());
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
@@ -179,3 +200,33 @@ std::vector<cvf::ref<cvf::DrawableGeo>> RivContourMapProjectionPartMgr::createCo
}
return contourDrawables;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo>
RivContourMapProjectionPartMgr::createPickPointVisDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const
{
cvf::ref<cvf::DrawableGeo> geo = nullptr;
cvf::ref<cvf::Vec3fArray> pickPointPolygon = m_contourMapProjection->generatePickPointPolygon(displayCoordTransform);
if (pickPointPolygon.notNull() && pickPointPolygon->size() > 0u)
{
std::vector<cvf::uint> indices;
indices.reserve(pickPointPolygon->size());
for (cvf::uint j = 0; j < pickPointPolygon->size(); ++j)
{
indices.push_back(j);
}
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES);
cvf::ref<cvf::UIntArray> indexArray = new cvf::UIntArray(indices);
indexedUInt->setIndices(indexArray.p());
geo = new cvf::DrawableGeo;
geo->addPrimitiveSet(indexedUInt.p());
geo->setVertexArray(pickPointPolygon.p());
}
return geo;
}

View File

@@ -36,13 +36,16 @@ public:
void appendProjectionToModel(cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform) const;
void appendPickPointVisToModel(cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform) const;
cvf::ref<cvf::Vec2fArray> createTextureCoords() const;
void removeTrianglesWithNoResult(cvf::UIntArray* uintArray) const;
private:
cvf::ref<cvf::DrawableGeo> createDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
cvf::ref<cvf::DrawableGeo> createProjectionMapDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
std::vector<cvf::ref<cvf::DrawableGeo>> createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const;
cvf::ref<cvf::DrawableGeo> createPickPointVisDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
private:
caf::PdmPointer<RimContourMapProjection> m_contourMapProjection;
caf::PdmPointer<RimContourMapView> m_parentContourMap;