mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#2552 Generalized the flatting transforms to be able to reuse for simwells and wellpaths
This commit is contained in:
parent
c63aee779d
commit
ec5a9e1682
@ -36,7 +36,8 @@
|
||||
#include "cvfPrimitiveSetIndexedUInt.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
#include "cvfRay.h"
|
||||
//#include "cvfTrace.h"
|
||||
|
||||
#include "RivSectionFlattner.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -69,127 +70,42 @@ RivIntersectionGeometryGenerator::~RivIntersectionGeometryGenerator()
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Origo in the intersection of the ray P1-ExtrDir with the XY plane
|
||||
/// Ez in upwards extrusionDir
|
||||
/// Ey normal tio the section pplane
|
||||
/// Ex in plane along p1-p2
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Mat4d calculateSectionLocalFlatteningCS(const cvf::Vec3d& p1, const cvf::Vec3d& p2, const cvf::Vec3d& extrusionDir)
|
||||
{
|
||||
using namespace cvf;
|
||||
|
||||
Vec3d Ez = extrusionDir.z() > 0.0 ? extrusionDir: -extrusionDir;
|
||||
|
||||
Vec3d sectionLineDir = p2 - p1;
|
||||
sectionLineDir.normalize();
|
||||
|
||||
Vec3d Ey = Ez ^ sectionLineDir;
|
||||
Ey.normalize();
|
||||
Vec3d Ex = Ey ^ Ez;
|
||||
Ex.normalize();
|
||||
|
||||
Ray extrusionRay;
|
||||
extrusionRay.setOrigin(p1);
|
||||
|
||||
if (p1.z() > 0) extrusionRay.setDirection(-Ez);
|
||||
else extrusionRay.setDirection(Ez);
|
||||
|
||||
|
||||
Vec3d tr(Vec3d::ZERO);
|
||||
extrusionRay.planeIntersect(Plane(0.0, 0.0 , 1.0, 0.0), &tr);
|
||||
|
||||
return Mat4d(Ex[0], Ey[0], Ez[0], tr[0],
|
||||
Ex[1], Ey[1], Ez[1], tr[1],
|
||||
Ex[2], Ey[2], Ez[2], tr[2],
|
||||
0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivIntersectionGeometryGenerator::calculateSegementTransformPrLinePoint()
|
||||
{
|
||||
cvf::Vec3d displayOffset = m_hexGrid->displayOffset();
|
||||
cvf::Mat4d invSectionCS = cvf::Mat4d::fromTranslation(-displayOffset);
|
||||
|
||||
m_segementTransformPrLinePoint.clear();
|
||||
|
||||
double previousSectionFlattenedEndPosX = m_horizontalLengthAlongWellToPolylineStart;
|
||||
cvf::Vec3d previousSectionOrigo(cvf::Vec3d::ZERO);
|
||||
|
||||
|
||||
for ( size_t pLineIdx = 0; pLineIdx < m_polyLines.size(); ++pLineIdx )
|
||||
if ( m_isFlattened )
|
||||
{
|
||||
m_segementTransformPrLinePoint.emplace_back();
|
||||
const std::vector<cvf::Vec3d>& polyLine = m_polyLines[pLineIdx];
|
||||
if ( !(m_polyLines.size() && m_polyLines.back().size()) ) return;
|
||||
|
||||
size_t pointCount = polyLine.size();
|
||||
cvf::Vec3d startOffset ={ m_horizontalLengthAlongWellToPolylineStart, 0.0, m_polyLines[0][0].z() };
|
||||
|
||||
size_t lIdx = 0;
|
||||
while ( lIdx < pointCount )
|
||||
for ( size_t pLineIdx = 0; pLineIdx < m_polyLines.size(); ++pLineIdx )
|
||||
{
|
||||
size_t idxToNextP = indexToNextValidPoint(polyLine, m_extrusionDirection, lIdx);
|
||||
if (idxToNextP == size_t(-1))
|
||||
{
|
||||
size_t inc = 0;
|
||||
while ((lIdx + inc) < pointCount)
|
||||
{
|
||||
m_segementTransformPrLinePoint.back().push_back(invSectionCS);
|
||||
++inc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_isFlattened)
|
||||
{
|
||||
cvf::Vec3d p1 = polyLine[lIdx];
|
||||
cvf::Vec3d p2 = polyLine[idxToNextP];
|
||||
|
||||
cvf::Mat4d sectionLocalCS = calculateSectionLocalFlatteningCS(p1, p2, m_extrusionDirection);
|
||||
|
||||
if ( pLineIdx == 0 && lIdx == 0 ) previousSectionOrigo = sectionLocalCS.translation();
|
||||
|
||||
previousSectionFlattenedEndPosX += (sectionLocalCS.translation() - previousSectionOrigo).length();
|
||||
previousSectionOrigo = sectionLocalCS.translation();
|
||||
|
||||
invSectionCS = sectionLocalCS.getInverted();
|
||||
cvf::Vec3d flattenedTranslation(previousSectionFlattenedEndPosX, 0.0, 0.0);
|
||||
|
||||
invSectionCS.setTranslation(invSectionCS.translation() + flattenedTranslation );
|
||||
}
|
||||
|
||||
size_t inc = 0;
|
||||
while ((lIdx + inc) < idxToNextP)
|
||||
{
|
||||
m_segementTransformPrLinePoint.back().push_back(invSectionCS);
|
||||
inc++;
|
||||
}
|
||||
|
||||
lIdx = idxToNextP;
|
||||
const std::vector<cvf::Vec3d>& polyLine = m_polyLines[pLineIdx];
|
||||
m_segementTransformPrLinePoint.emplace_back(RivSectionFlattner::calculateFlatteningCSsForPolyline(polyLine,
|
||||
m_extrusionDirection,
|
||||
startOffset,
|
||||
&startOffset));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_segementTransformPrLinePoint.clear();
|
||||
|
||||
// for (auto mx: m_segementTransformPrLinePoint[0])
|
||||
// {
|
||||
// cvf::String text;
|
||||
//
|
||||
// for (int r = 0; r < 4; ++r)
|
||||
// {
|
||||
// for (int c = 0; c < 4; ++c)
|
||||
// {
|
||||
// text += cvf::String::number(mx(r, c));
|
||||
//
|
||||
// if (r * c < 9)
|
||||
// {
|
||||
// text += " ";
|
||||
// }
|
||||
// }
|
||||
// text += "\n";
|
||||
// }
|
||||
//
|
||||
// cvf::Trace::show( text );
|
||||
// }
|
||||
cvf::Mat4d invSectionCS = cvf::Mat4d::fromTranslation(-m_hexGrid->displayOffset());
|
||||
|
||||
for ( const auto & polyLine : m_polyLines )
|
||||
{
|
||||
m_segementTransformPrLinePoint.emplace_back();
|
||||
std::vector<cvf::Mat4d>& segmentTransforms = m_segementTransformPrLinePoint.back();
|
||||
for ( size_t lIdx = 0; lIdx < polyLine.size(); ++lIdx )
|
||||
{
|
||||
segmentTransforms.push_back(invSectionCS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -239,7 +155,7 @@ void RivIntersectionGeometryGenerator::calculateArrays()
|
||||
size_t lIdx = 0;
|
||||
while ( lIdx < lineCount - 1)
|
||||
{
|
||||
size_t idxToNextP = indexToNextValidPoint(polyLine, m_extrusionDirection, lIdx);
|
||||
size_t idxToNextP = RivSectionFlattner::indexToNextValidPoint(polyLine, m_extrusionDirection, lIdx);
|
||||
|
||||
if (idxToNextP == size_t(-1)) break;
|
||||
|
||||
@ -569,34 +485,6 @@ cvf::ref<cvf::DrawableGeo> RivIntersectionGeometryGenerator::createPointsFromPol
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find the next point in the polyline that avoids making the line nearly parallel to the extrusion direction
|
||||
/// Returns size_t(-1) if no point is found
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RivIntersectionGeometryGenerator::indexToNextValidPoint(const std::vector<cvf::Vec3d>& polyLine,
|
||||
const cvf::Vec3d extrDir,
|
||||
size_t idxToStartOfLineSegment)
|
||||
{
|
||||
size_t lineCount = polyLine.size();
|
||||
if ( !(idxToStartOfLineSegment + 1 < lineCount) ) return -1;
|
||||
|
||||
|
||||
cvf::Vec3d p1 = polyLine[idxToStartOfLineSegment];
|
||||
|
||||
for ( size_t lIdx = idxToStartOfLineSegment+1; lIdx < lineCount; ++lIdx )
|
||||
{
|
||||
cvf::Vec3d p2 = polyLine[lIdx];
|
||||
cvf::Vec3d p1p2 = p2 - p1;
|
||||
|
||||
if ( (p1p2 - (p1p2 * extrDir)*extrDir).length() > 0.1 )
|
||||
{
|
||||
return lIdx;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -635,23 +523,23 @@ RimIntersection* RivIntersectionGeometryGenerator::crossSection() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Mat4d RivIntersectionGeometryGenerator::unflattenTransformMatrix(const cvf::Vec3d& intersectionPointUtm)
|
||||
cvf::Mat4d RivIntersectionGeometryGenerator::unflattenTransformMatrix(const cvf::Vec3d& intersectionPointFlat)
|
||||
{
|
||||
cvf::Vec3d startPt = cvf::Vec3d::ZERO;
|
||||
|
||||
int polyLineIdx = -1;
|
||||
int segIdx = -1;
|
||||
for (size_t i = 0; i < m_flattenedOrOffsettedPolyLines.size(); i++)
|
||||
for (size_t pLineIdx = 0; pLineIdx < m_flattenedOrOffsettedPolyLines.size(); pLineIdx++)
|
||||
{
|
||||
std::vector<cvf::Vec3d> pts = m_flattenedOrOffsettedPolyLines[i];
|
||||
for(size_t j = 0; j < pts.size(); j++)
|
||||
std::vector<cvf::Vec3d> polyLine = m_flattenedOrOffsettedPolyLines[pLineIdx];
|
||||
for(size_t pIdx = 0; pIdx < polyLine.size(); pIdx++)
|
||||
{
|
||||
// Assumes ascending sorted list
|
||||
if (j > 0 && intersectionPointUtm.x() < pts[j].x())
|
||||
if (pIdx > 0 && intersectionPointFlat.x() < polyLine[pIdx].x())
|
||||
{
|
||||
polyLineIdx = static_cast<int>(i);
|
||||
segIdx = static_cast<int>(j) - 1;
|
||||
startPt = pts[segIdx];
|
||||
polyLineIdx = static_cast<int>(pLineIdx);
|
||||
segIdx = static_cast<int>(pIdx) - 1;
|
||||
startPt = polyLine[segIdx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
|
||||
RimIntersection* crossSection() const;
|
||||
|
||||
cvf::Mat4d unflattenTransformMatrix(const cvf::Vec3d& intersectionPointUtm);
|
||||
cvf::Mat4d unflattenTransformMatrix(const cvf::Vec3d& intersectionPointFlat);
|
||||
|
||||
private:
|
||||
void calculateArrays();
|
||||
|
@ -974,9 +974,9 @@ const RimIntersection* RivIntersectionPartMgr::intersection() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Mat4d RivIntersectionPartMgr::unflattenTransformMatrix(const cvf::Vec3d& intersectionPointUtm)
|
||||
cvf::Mat4d RivIntersectionPartMgr::unflattenTransformMatrix(const cvf::Vec3d& intersectionPointFlat)
|
||||
{
|
||||
return m_crossSectionGenerator->unflattenTransformMatrix(intersectionPointUtm);
|
||||
return m_crossSectionGenerator->unflattenTransformMatrix(intersectionPointFlat);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
|
||||
const RimIntersection* intersection() const;
|
||||
|
||||
cvf::Mat4d unflattenTransformMatrix(const cvf::Vec3d& intersectionPointUtm);
|
||||
cvf::Mat4d unflattenTransformMatrix(const cvf::Vec3d& intersectionPointFlat);
|
||||
|
||||
public:
|
||||
static void calculateEclipseTextureCoordinates(cvf::Vec2fArray* textureCoords,
|
||||
|
@ -0,0 +1,148 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
class RivSectionFlattner
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the next index higher than idxToStartOfLineSegment that makes the line
|
||||
// polyline[idxToStartOfLineSegment] .. polyline[nextIdx] not parallel to extrDir
|
||||
///
|
||||
/// Returns size_t(-1) if no point is found
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static size_t indexToNextValidPoint(const std::vector<cvf::Vec3d>& polyLine,
|
||||
const cvf::Vec3d extrDir,
|
||||
size_t idxToStartOfLineSegment)
|
||||
{
|
||||
size_t lineCount = polyLine.size();
|
||||
if ( !(idxToStartOfLineSegment + 1 < lineCount) ) return -1;
|
||||
|
||||
|
||||
cvf::Vec3d p1 = polyLine[idxToStartOfLineSegment];
|
||||
|
||||
for ( size_t lIdx = idxToStartOfLineSegment+1; lIdx < lineCount; ++lIdx )
|
||||
{
|
||||
cvf::Vec3d p2 = polyLine[lIdx];
|
||||
cvf::Vec3d p1p2 = p2 - p1;
|
||||
|
||||
if ( (p1p2 - (p1p2 * extrDir)*extrDir).length() > 0.1 )
|
||||
{
|
||||
return lIdx;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns one CS pr point, valid for the next segment
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static std::vector<cvf::Mat4d> calculateFlatteningCSsForPolyline(const std::vector<cvf::Vec3d> & polyLine,
|
||||
const cvf::Vec3d& extrusionDir,
|
||||
const cvf::Vec3d& startOffset,
|
||||
cvf::Vec3d* endOffset)
|
||||
{
|
||||
CVF_ASSERT(endOffset);
|
||||
size_t pointCount = polyLine.size();
|
||||
CVF_ASSERT(pointCount > 1);
|
||||
|
||||
std::vector<cvf::Mat4d> segmentTransforms;
|
||||
segmentTransforms.reserve(pointCount);
|
||||
|
||||
// Find initial transform, used if all is vertical
|
||||
|
||||
cvf::Mat4d invSectionCS;
|
||||
{
|
||||
cvf::Vec3d p1 = polyLine[0];
|
||||
cvf::Vec3d p2 = polyLine[1];
|
||||
|
||||
cvf::Mat4d sectionLocalCS = calculateSectionLocalFlatteningCS(p1, p2, extrusionDir);
|
||||
cvf::Mat4d invSectionCS = sectionLocalCS.getInverted();
|
||||
invSectionCS.setTranslation(invSectionCS.translation() + startOffset);
|
||||
}
|
||||
|
||||
cvf::Vec3d previousFlattenedSectionEndPoint = startOffset;
|
||||
|
||||
size_t lIdx = 0;
|
||||
while ( lIdx < pointCount )
|
||||
{
|
||||
size_t idxToNextP = indexToNextValidPoint(polyLine, extrusionDir, lIdx);
|
||||
|
||||
// If the rest is nearly parallel to extrusionDir, use the current inverse matrix for the rest of the points
|
||||
|
||||
if ( idxToNextP == size_t(-1) )
|
||||
{
|
||||
size_t inc = 0;
|
||||
while ( (lIdx + inc) < pointCount )
|
||||
{
|
||||
segmentTransforms.push_back(invSectionCS);
|
||||
++inc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cvf::Vec3d p1 = polyLine[lIdx];
|
||||
cvf::Vec3d p2 = polyLine[idxToNextP];
|
||||
|
||||
cvf::Mat4d sectionLocalCS = calculateSectionLocalFlatteningCS(p1, p2, extrusionDir);
|
||||
invSectionCS = sectionLocalCS.getInverted();
|
||||
cvf::Vec3d flattenedSectionEndPoint = p2.getTransformedPoint(invSectionCS);
|
||||
|
||||
invSectionCS.setTranslation(invSectionCS.translation() + previousFlattenedSectionEndPoint );
|
||||
|
||||
previousFlattenedSectionEndPoint += flattenedSectionEndPoint;
|
||||
|
||||
// Assign the matrix to the points in between
|
||||
|
||||
size_t inc = 0;
|
||||
while ( (lIdx + inc) < idxToNextP )
|
||||
{
|
||||
segmentTransforms.push_back(invSectionCS);
|
||||
inc++;
|
||||
}
|
||||
|
||||
lIdx = idxToNextP;
|
||||
}
|
||||
|
||||
*endOffset = previousFlattenedSectionEndPoint;
|
||||
return segmentTransforms;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Origo in P1
|
||||
/// Ez in upwards extrusionDir
|
||||
/// Ey normal to the section plane
|
||||
/// Ex in plane along p1-p2
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static cvf::Mat4d calculateSectionLocalFlatteningCS(const cvf::Vec3d& p1,
|
||||
const cvf::Vec3d& p2,
|
||||
const cvf::Vec3d& extrusionDir)
|
||||
{
|
||||
using namespace cvf;
|
||||
|
||||
Vec3d Ez = extrusionDir.z() > 0.0 ? extrusionDir: -extrusionDir;
|
||||
|
||||
Vec3d sectionLineDir = p2 - p1;
|
||||
|
||||
if ( cvf::GeometryTools::getAngle(sectionLineDir, extrusionDir) < 0.01 )
|
||||
{
|
||||
sectionLineDir = Ez.perpendicularVector();
|
||||
}
|
||||
|
||||
Vec3d Ey = Ez ^ sectionLineDir;
|
||||
Ey.normalize();
|
||||
Vec3d Ex = Ey ^ Ez;
|
||||
Ex.normalize();
|
||||
|
||||
return Mat4d(Ex[0], Ey[0], Ez[0], p1[0],
|
||||
Ex[1], Ey[1], Ez[1], p1[1],
|
||||
Ex[2], Ey[2], Ez[2], p1[2],
|
||||
0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user