mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
3D Well log curves: Use the new generalized interpolation for normals
* Don't have to perform the normal generation again for grid points.
This commit is contained in:
parent
1bb1b3004e
commit
b48adbbaa9
@ -113,15 +113,19 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std
|
|||||||
maxZClipHeight = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance;
|
maxZClipHeight = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> interpolatedWellPathPoints;
|
std::vector<cvf::Vec3d> wellPathNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle);
|
||||||
|
|
||||||
|
std::vector<cvf::Vec3d> interpolatedWellPathPoints;
|
||||||
|
std::vector<cvf::Vec3d> interpolatedNormals;
|
||||||
// Iterate from bottom of well path and up to be able to stop at given Z max clipping height
|
// Iterate from bottom of well path and up to be able to stop at given Z max clipping height
|
||||||
for (auto md = resultMds.rbegin(); md != resultMds.rend(); md++)
|
for (auto md = resultMds.rbegin(); md != resultMds.rend(); md++)
|
||||||
{
|
{
|
||||||
cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(*md);
|
cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(*md);
|
||||||
|
cvf::Vec3d normal = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathNormals, *md);
|
||||||
if (point.z() > maxZClipHeight) break;
|
if (point.z() > maxZClipHeight) break;
|
||||||
|
|
||||||
interpolatedWellPathPoints.push_back(point);
|
interpolatedWellPathPoints.push_back(point);
|
||||||
|
interpolatedNormals.push_back(normal.getNormalized());
|
||||||
}
|
}
|
||||||
if (interpolatedWellPathPoints.empty()) return;
|
if (interpolatedWellPathPoints.empty()) return;
|
||||||
|
|
||||||
@ -132,12 +136,6 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std
|
|||||||
std::vector<double> resultValuesForInterpolatedPoints(resultValues.end() - interpolatedWellPathPoints.size(),
|
std::vector<double> resultValuesForInterpolatedPoints(resultValues.end() - interpolatedWellPathPoints.size(),
|
||||||
resultValues.end());
|
resultValues.end());
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> pairsOfWellPathPoints;
|
|
||||||
RigWellPathGeometryTools::calculatePairsOfClosestSamplingPointsAlongWellPath(wellPathGeometry(), interpolatedWellPathPoints, &pairsOfWellPathPoints);
|
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> pointNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, pairsOfWellPathPoints, RigWellPathGeometryTools::LINE_SEGMENTS);
|
|
||||||
if (interpolatedWellPathPoints.size() != pointNormals.size()) return;
|
|
||||||
|
|
||||||
double maxResult = -HUGE_VAL;
|
double maxResult = -HUGE_VAL;
|
||||||
double minResult = HUGE_VAL;
|
double minResult = HUGE_VAL;
|
||||||
|
|
||||||
@ -153,7 +151,7 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std
|
|||||||
|
|
||||||
double plotRangeToResultRangeFactor = planeWidth / (maxResult - minResult);
|
double plotRangeToResultRangeFactor = planeWidth / (maxResult - minResult);
|
||||||
|
|
||||||
for (size_t i = 0; i < pointNormals.size(); i++)
|
for (size_t i = 0; i < interpolatedNormals.size(); i++)
|
||||||
{
|
{
|
||||||
double scaledResult = 0;
|
double scaledResult = 0;
|
||||||
|
|
||||||
@ -164,7 +162,7 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std
|
|||||||
}
|
}
|
||||||
|
|
||||||
(*vertices)[i] = cvf::Vec3f(
|
(*vertices)[i] = cvf::Vec3f(
|
||||||
displayCoordTransform->transformToDisplayCoord(interpolatedWellPathPoints[i] + scaledResult * pointNormals[i]));
|
displayCoordTransform->transformToDisplayCoord(interpolatedWellPathPoints[i] + scaledResult * interpolatedNormals[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<size_t, size_t>> valuesIntervals =
|
std::vector<std::pair<size_t, size_t>> valuesIntervals =
|
||||||
|
@ -92,42 +92,17 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform*
|
|||||||
|
|
||||||
std::map< DrawableId, cvf::ref<cvf::DrawableGeo> > drawables;
|
std::map< DrawableId, cvf::ref<cvf::DrawableGeo> > drawables;
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> gridPoints;
|
|
||||||
|
|
||||||
size_t newStartIndex = originalWellPathSize - wellPathPoints.size();
|
|
||||||
double firstMd = wellPathGeometry()->m_measuredDepths.at(newStartIndex);
|
|
||||||
double lastMd = wellPathGeometry()->m_measuredDepths.back();
|
|
||||||
|
|
||||||
double md = lastMd;
|
|
||||||
while (md >= firstMd)
|
|
||||||
{
|
|
||||||
cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(md);
|
|
||||||
gridPoints.push_back(point);
|
|
||||||
md -= gridIntervalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> pointNormals;
|
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> closestPoints;
|
|
||||||
RigWellPathGeometryTools::calculatePairsOfClosestSamplingPointsAlongWellPath(wellPathGeometry(), gridPoints, &closestPoints);
|
|
||||||
|
|
||||||
pointNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, closestPoints, RigWellPathGeometryTools::LINE_SEGMENTS);
|
|
||||||
if (pointNormals.size() != gridPoints.size())
|
|
||||||
{
|
|
||||||
return std::map< DrawableId, cvf::ref<cvf::DrawableGeo> >();
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculateLineSegmentNormals returns normals for the whole well path. Erase the part which is clipped off
|
// calculateLineSegmentNormals returns normals for the whole well path. Erase the part which is clipped off
|
||||||
std::vector<cvf::Vec3d> wellPathSegmentNormals =
|
std::vector<cvf::Vec3d> wellPathSegmentNormals =
|
||||||
RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, wellPathGeometry()->m_wellPathPoints, RigWellPathGeometryTools::POLYLINE);
|
RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle);
|
||||||
wellPathSegmentNormals.erase(wellPathSegmentNormals.begin(), wellPathSegmentNormals.end() - wellPathPoints.size());
|
wellPathSegmentNormals.erase(wellPathSegmentNormals.begin(), wellPathSegmentNormals.end() - wellPathPoints.size());
|
||||||
|
|
||||||
{
|
{
|
||||||
std::vector<cvf::Vec3f> vertices;
|
std::vector<cvf::Vec3f> vertices;
|
||||||
vertices.reserve(gridPoints.size());
|
vertices.reserve(wellPathPoints.size());
|
||||||
|
|
||||||
std::vector<cvf::uint> indices;
|
std::vector<cvf::uint> indices;
|
||||||
indices.reserve(gridPoints.size());
|
indices.reserve(wellPathPoints.size());
|
||||||
cvf::uint indexCounter = 0;
|
cvf::uint indexCounter = 0;
|
||||||
// Line along and close to well
|
// Line along and close to well
|
||||||
for (size_t i = 0; i < wellPathPoints.size(); i++)
|
for (size_t i = 0; i < wellPathPoints.size(); i++)
|
||||||
@ -162,20 +137,37 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform*
|
|||||||
drawables[GridBorder] = gridBorderDrawable;
|
drawables[GridBorder] = gridBorderDrawable;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
std::vector<cvf::Vec3d> interpolatedGridPoints;
|
||||||
|
std::vector<cvf::Vec3d> interpolatedGridNormals;
|
||||||
|
|
||||||
|
size_t newStartIndex = originalWellPathSize - wellPathPoints.size();
|
||||||
|
double firstMd = wellPathGeometry()->m_measuredDepths.at(newStartIndex);
|
||||||
|
double lastMd = wellPathGeometry()->m_measuredDepths.back();
|
||||||
|
|
||||||
|
double md = lastMd;
|
||||||
|
while (md >= firstMd)
|
||||||
|
{
|
||||||
|
cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(md);
|
||||||
|
cvf::Vec3d normal = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathSegmentNormals, md);
|
||||||
|
interpolatedGridPoints.push_back(point);
|
||||||
|
interpolatedGridNormals.push_back(normal.getNormalized());
|
||||||
|
md -= gridIntervalSize;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<cvf::Vec3f> vertices;
|
std::vector<cvf::Vec3f> vertices;
|
||||||
vertices.reserve(gridPoints.size());
|
vertices.reserve(interpolatedGridPoints.size());
|
||||||
|
|
||||||
std::vector<cvf::uint> indices;
|
std::vector<cvf::uint> indices;
|
||||||
indices.reserve(gridPoints.size());
|
indices.reserve(interpolatedGridPoints.size());
|
||||||
cvf::uint indexCounter = 0;
|
cvf::uint indexCounter = 0;
|
||||||
// Normal lines. Start from one to avoid drawing at surface edge.
|
// Normal lines. Start from one to avoid drawing at surface edge.
|
||||||
for (size_t i = 1; i < pointNormals.size(); i++)
|
for (size_t i = 1; i < interpolatedGridNormals.size(); i++)
|
||||||
{
|
{
|
||||||
vertices.push_back(cvf::Vec3f(
|
vertices.push_back(cvf::Vec3f(
|
||||||
displayCoordTransform->transformToDisplayCoord(gridPoints[i] + pointNormals[i] * planeOffsetFromWellPathCenter)));
|
displayCoordTransform->transformToDisplayCoord(interpolatedGridPoints[i] + interpolatedGridNormals[i] * planeOffsetFromWellPathCenter)));
|
||||||
|
|
||||||
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
||||||
gridPoints[i] + pointNormals[i] * (planeOffsetFromWellPathCenter + planeWidth))));
|
interpolatedGridPoints[i] + interpolatedGridNormals[i] * (planeOffsetFromWellPathCenter + planeWidth))));
|
||||||
|
|
||||||
indices.push_back(indexCounter++);
|
indices.push_back(indexCounter++);
|
||||||
indices.push_back(indexCounter++);
|
indices.push_back(indexCounter++);
|
||||||
|
@ -30,37 +30,27 @@
|
|||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::vector<cvf::Vec3d> RigWellPathGeometryTools::calculateLineSegmentNormals(const RigWellPath* wellPathGeometry,
|
std::vector<cvf::Vec3d> RigWellPathGeometryTools::calculateLineSegmentNormals(const RigWellPath* wellPathGeometry,
|
||||||
double planeAngle,
|
double planeAngle)
|
||||||
const std::vector<cvf::Vec3d>& vertices,
|
|
||||||
VertexOrganization organization)
|
|
||||||
{
|
{
|
||||||
std::vector<cvf::Vec3d> pointNormals;
|
std::vector<cvf::Vec3d> pointNormals;
|
||||||
|
|
||||||
if (!wellPathGeometry) return pointNormals;
|
if (!wellPathGeometry) return pointNormals;
|
||||||
|
|
||||||
|
const std::vector<cvf::Vec3d>& vertices = wellPathGeometry->wellPathPoints();
|
||||||
|
|
||||||
if (vertices.empty()) return pointNormals;
|
if (vertices.empty()) return pointNormals;
|
||||||
|
|
||||||
|
pointNormals.reserve(vertices.size());
|
||||||
|
|
||||||
cvf::Vec3d up(0, 0, 1);
|
cvf::Vec3d up(0, 0, 1);
|
||||||
|
|
||||||
// Project onto normal plane
|
|
||||||
cvf::Vec3d dominantDirection = estimateDominantDirectionInXYPlane(wellPathGeometry);
|
cvf::Vec3d dominantDirection = estimateDominantDirectionInXYPlane(wellPathGeometry);
|
||||||
|
|
||||||
const cvf::Vec3d projectionPlaneNormal = (up ^ dominantDirection).getNormalized();
|
const cvf::Vec3d projectionPlaneNormal = (up ^ dominantDirection).getNormalized();
|
||||||
CVF_ASSERT(projectionPlaneNormal * dominantDirection <= std::numeric_limits<double>::epsilon());
|
CVF_ASSERT(projectionPlaneNormal * dominantDirection <= std::numeric_limits<double>::epsilon());
|
||||||
|
|
||||||
size_t intervalSize;
|
|
||||||
if (organization == LINE_SEGMENTS)
|
|
||||||
{
|
|
||||||
pointNormals.reserve(vertices.size() / 2);
|
|
||||||
intervalSize = 2;
|
|
||||||
}
|
|
||||||
else // organization == POLYLINE
|
|
||||||
{
|
|
||||||
pointNormals.reserve(vertices.size());
|
|
||||||
intervalSize = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cvf::Vec3d lastNormal;
|
cvf::Vec3d lastNormal;
|
||||||
for (size_t i = 0; i < vertices.size() - 1; i += intervalSize)
|
for (size_t i = 0; i < vertices.size() - 1; ++i)
|
||||||
{
|
{
|
||||||
cvf::Vec3d p1 = vertices[i];
|
cvf::Vec3d p1 = vertices[i];
|
||||||
cvf::Vec3d p2 = vertices[i + 1];
|
cvf::Vec3d p2 = vertices[i + 1];
|
||||||
@ -77,35 +67,11 @@ std::vector<cvf::Vec3d> RigWellPathGeometryTools::calculateLineSegmentNormals(co
|
|||||||
lastNormal = normal;
|
lastNormal = normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (organization == POLYLINE)
|
|
||||||
{
|
|
||||||
pointNormals.push_back(lastNormal);
|
pointNormals.push_back(lastNormal);
|
||||||
}
|
|
||||||
|
|
||||||
return interpolateUndefinedNormals(up, pointNormals, vertices);
|
return interpolateUndefinedNormals(up, pointNormals, vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
void RigWellPathGeometryTools::calculatePairsOfClosestSamplingPointsAlongWellPath(const RigWellPath* wellPathGeometry,
|
|
||||||
const std::vector<cvf::Vec3d>& points,
|
|
||||||
std::vector<cvf::Vec3d>* closestWellPathPoints)
|
|
||||||
{
|
|
||||||
CVF_ASSERT(closestWellPathPoints != nullptr);
|
|
||||||
|
|
||||||
for (const cvf::Vec3d point : points)
|
|
||||||
{
|
|
||||||
cvf::Vec3d p1 = cvf::Vec3d::UNDEFINED;
|
|
||||||
cvf::Vec3d p2 = cvf::Vec3d::UNDEFINED;
|
|
||||||
wellPathGeometry->twoClosestPoints(point, &p1, &p2);
|
|
||||||
if (p1.isUndefined() || p2.isUndefined()) continue;
|
|
||||||
|
|
||||||
closestWellPathPoints->push_back(p1);
|
|
||||||
closestWellPathPoints->push_back(p2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> RigWellPathGeometryTools::interpolateUndefinedNormals(const cvf::Vec3d& planeNormal,
|
std::vector<cvf::Vec3d> RigWellPathGeometryTools::interpolateUndefinedNormals(const cvf::Vec3d& planeNormal,
|
||||||
const std::vector<cvf::Vec3d>& normals,
|
const std::vector<cvf::Vec3d>& normals,
|
||||||
const std::vector<cvf::Vec3d>& vertices)
|
const std::vector<cvf::Vec3d>& vertices)
|
||||||
|
@ -39,13 +39,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static std::vector<cvf::Vec3d> calculateLineSegmentNormals(const RigWellPath* wellPathGeometry,
|
static std::vector<cvf::Vec3d> calculateLineSegmentNormals(const RigWellPath* wellPathGeometry,
|
||||||
double angle,
|
double angle);
|
||||||
const std::vector<cvf::Vec3d>& vertices,
|
|
||||||
VertexOrganization organization);
|
|
||||||
|
|
||||||
static void calculatePairsOfClosestSamplingPointsAlongWellPath(const RigWellPath* wellPathGeometry,
|
|
||||||
const std::vector<cvf::Vec3d>& points,
|
|
||||||
std::vector<cvf::Vec3d>* closestWellPathPoints);
|
|
||||||
private:
|
private:
|
||||||
static std::vector<cvf::Vec3d> interpolateUndefinedNormals(const cvf::Vec3d& planeNormal,
|
static std::vector<cvf::Vec3d> interpolateUndefinedNormals(const cvf::Vec3d& planeNormal,
|
||||||
const std::vector<cvf::Vec3d>& normals,
|
const std::vector<cvf::Vec3d>& normals,
|
||||||
|
Loading…
Reference in New Issue
Block a user