mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merge pull request #5403 from OPM/feature-reservoir-surface-intersection-border
Feature reservoir surface intersection border
This commit is contained in:
commit
529696de89
@ -47,6 +47,9 @@
|
|||||||
#include "../cafHexInterpolator/cafHexInterpolator.h"
|
#include "../cafHexInterpolator/cafHexInterpolator.h"
|
||||||
#include "RivSectionFlattner.h"
|
#include "RivSectionFlattner.h"
|
||||||
|
|
||||||
|
#include "RiaLogging.h"
|
||||||
|
#include "clipper.hpp"
|
||||||
|
|
||||||
cvf::ref<caf::DisplayCoordTransform> displayCoordTransform( const RimIntersection* intersection )
|
cvf::ref<caf::DisplayCoordTransform> displayCoordTransform( const RimIntersection* intersection )
|
||||||
{
|
{
|
||||||
Rim3dView* rimView = nullptr;
|
Rim3dView* rimView = nullptr;
|
||||||
@ -177,8 +180,6 @@ void RivSurfaceIntersectionGeometryGenerator::calculateArrays()
|
|||||||
std::array<cvf::Vec3d, 8> cellCorners;
|
std::array<cvf::Vec3d, 8> cellCorners;
|
||||||
std::array<size_t, 8> cornerIndices;
|
std::array<size_t, 8> cornerIndices;
|
||||||
|
|
||||||
size_t startOfGeneratedTrianglesForNativeTriangles = outputTriangleVertices.size();
|
|
||||||
|
|
||||||
for ( size_t ticIdx = 0; ticIdx < triIntersectedCellCandidates.size(); ++ticIdx )
|
for ( size_t ticIdx = 0; ticIdx < triIntersectedCellCandidates.size(); ++ticIdx )
|
||||||
{
|
{
|
||||||
size_t globalCellIdx = triIntersectedCellCandidates[ticIdx];
|
size_t globalCellIdx = triIntersectedCellCandidates[ticIdx];
|
||||||
@ -250,28 +251,6 @@ void RivSurfaceIntersectionGeometryGenerator::calculateArrays()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add triangles for the part of the native triangle outside any gridcells
|
|
||||||
|
|
||||||
if ( startOfGeneratedTrianglesForNativeTriangles == outputTriangleVertices.size() )
|
|
||||||
{
|
|
||||||
// No triangles created, use the complete native triangle
|
|
||||||
outputTriangleVertices.push_back( cvf::Vec3f( p0 - displayModelOffset ) );
|
|
||||||
outputTriangleVertices.push_back( cvf::Vec3f( p1 - displayModelOffset ) );
|
|
||||||
outputTriangleVertices.push_back( cvf::Vec3f( p2 - displayModelOffset ) );
|
|
||||||
|
|
||||||
m_triangleToCellIdxMap.push_back( cvf::UNDEFINED_SIZE_T );
|
|
||||||
|
|
||||||
m_triVxToCellCornerWeights.push_back( RivIntersectionVertexWeights() );
|
|
||||||
m_triVxToCellCornerWeights.push_back( RivIntersectionVertexWeights() );
|
|
||||||
m_triVxToCellCornerWeights.push_back( RivIntersectionVertexWeights() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Todo:
|
|
||||||
// Subtract the created triangles from the native triangle
|
|
||||||
// Add the remains
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_triangleVxes->assign( outputTriangleVertices );
|
m_triangleVxes->assign( outputTriangleVertices );
|
||||||
|
@ -111,7 +111,7 @@ void RivSurfacePartMgr::updateCellResultColor( size_t timeStepIndex )
|
|||||||
m_intersectionFacesTextureCoords.p() );
|
m_intersectionFacesTextureCoords.p() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_nativeTrianglesPart.notNull() )
|
if ( false && m_nativeTrianglesPart.notNull() )
|
||||||
{
|
{
|
||||||
if ( !m_nativeVertexToCellIndexMap.size() )
|
if ( !m_nativeVertexToCellIndexMap.size() )
|
||||||
{
|
{
|
||||||
@ -230,6 +230,8 @@ void RivSurfacePartMgr::appendIntersectionGeometryPartsToModel( cvf::ModelBasicL
|
|||||||
m_intersectionFaultGridLines->setTransform( scaleTransform );
|
m_intersectionFaultGridLines->setTransform( scaleTransform );
|
||||||
model->addPart( m_intersectionFaultGridLines.p() );
|
model->addPart( m_intersectionFaultGridLines.p() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
appendNativeGeometryPartsToModel( model, scaleTransform );
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -241,9 +243,12 @@ void RivSurfacePartMgr::applySingleColor()
|
|||||||
caf::SurfaceEffectGenerator surfaceGen( cvf::Color4f( m_surfaceInView->surface()->color() ), caf::PO_1 );
|
caf::SurfaceEffectGenerator surfaceGen( cvf::Color4f( m_surfaceInView->surface()->color() ), caf::PO_1 );
|
||||||
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
|
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
|
||||||
|
|
||||||
|
caf::SurfaceEffectGenerator surfaceGenBehind( cvf::Color4f( m_surfaceInView->surface()->color() ), caf::PO_2 );
|
||||||
|
cvf::ref<cvf::Effect> effBehind = surfaceGenBehind.generateCachedEffect();
|
||||||
|
|
||||||
if ( m_nativeTrianglesPart.notNull() )
|
if ( m_nativeTrianglesPart.notNull() )
|
||||||
{
|
{
|
||||||
m_nativeTrianglesPart->setEffect( eff.p() );
|
m_nativeTrianglesPart->setEffect( effBehind.p() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_intersectionFaces.notNull() )
|
if ( m_intersectionFaces.notNull() )
|
||||||
|
@ -53,7 +53,7 @@ public:
|
|||||||
|
|
||||||
static std::vector<std::vector<cvf::Vec3d>>
|
static std::vector<std::vector<cvf::Vec3d>>
|
||||||
subtractPolygons( const std::vector<cvf::Vec3d>& sourcePolygon,
|
subtractPolygons( const std::vector<cvf::Vec3d>& sourcePolygon,
|
||||||
const std::vector<std::vector<cvf::Vec3d>>& polygonToSubtract );
|
const std::vector<std::vector<cvf::Vec3d>>& polygonsToSubtract );
|
||||||
|
|
||||||
enum ZInterpolationType
|
enum ZInterpolationType
|
||||||
{
|
{
|
||||||
|
@ -175,6 +175,31 @@ double GeometryTools::signedAreaPlanarPolygon( const cvf::Vec3d& planeNormal, co
|
|||||||
return signedArea;
|
return signedArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
/// This method below is more correct than the one above, both in naming and behaviour.
|
||||||
|
/// Should be replaced, but is not done now to avoid possible sideeffects
|
||||||
|
/// The difference is the sign of the area. The one below retuns correct sign according to the plane normal
|
||||||
|
/// provided
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
template <typename Vec3Type>
|
||||||
|
double closestAxisSignedAreaPlanarPolygon( const cvf::Vec3d& planeNormal, const std::vector<Vec3Type>& polygon )
|
||||||
|
{
|
||||||
|
int Z = cvf::GeometryTools::findClosestAxis( planeNormal );
|
||||||
|
int X = ( Z + 1 ) % 3;
|
||||||
|
int Y = ( Z + 2 ) % 3;
|
||||||
|
|
||||||
|
// Use Shoelace formula to calculate signed area.
|
||||||
|
// https://en.wikipedia.org/wiki/Shoelace_formula
|
||||||
|
double signedArea = 0.0;
|
||||||
|
for ( size_t i = 0; i < polygon.size(); ++i )
|
||||||
|
{
|
||||||
|
signedArea += ( polygon[( i + 1 ) % polygon.size()][X] + polygon[i][X] ) *
|
||||||
|
( polygon[( i + 1 ) % polygon.size()][Y] - polygon[i][Y] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( planeNormal[Z] > 0 ) ? signedArea : -signedArea;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Determine the intersection point of two line segments
|
Determine the intersection point of two line segments
|
||||||
From Paul Bourke, but modified to really handle coincident lines
|
From Paul Bourke, but modified to really handle coincident lines
|
||||||
@ -880,12 +905,17 @@ bool EarClipTesselator::calculateTriangles( std::vector<size_t>* triangleIndices
|
|||||||
++w; // v + 1;
|
++w; // v + 1;
|
||||||
if ( w == m_polygonIndices.end() ) w = m_polygonIndices.begin(); // if (nv <= w) w = 0;
|
if ( w == m_polygonIndices.end() ) w = m_polygonIndices.begin(); // if (nv <= w) w = 0;
|
||||||
|
|
||||||
if ( isTriangleValid( u, v, w ) )
|
EarClipTesselator::TriangleStatus triStatus = calculateTriangleStatus( u, v, w );
|
||||||
|
|
||||||
|
if ( triStatus != INVALID_TRIANGLE )
|
||||||
{
|
{
|
||||||
// Indices of the vertices
|
// Indices of the vertices
|
||||||
triangleIndices->push_back( *u );
|
if ( triStatus == VALID_TRIANGLE )
|
||||||
triangleIndices->push_back( *v );
|
{
|
||||||
triangleIndices->push_back( *w );
|
triangleIndices->push_back( *u );
|
||||||
|
triangleIndices->push_back( *v );
|
||||||
|
triangleIndices->push_back( *w );
|
||||||
|
}
|
||||||
|
|
||||||
// Remove v from remaining polygon
|
// Remove v from remaining polygon
|
||||||
m_polygonIndices.erase( v );
|
m_polygonIndices.erase( v );
|
||||||
@ -904,9 +934,9 @@ bool EarClipTesselator::calculateTriangles( std::vector<size_t>* triangleIndices
|
|||||||
/// Is this a valid triangle ? ( No points inside, and points not on a line. )
|
/// Is this a valid triangle ? ( No points inside, and points not on a line. )
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool EarClipTesselator::isTriangleValid( std::list<size_t>::const_iterator u,
|
EarClipTesselator::TriangleStatus EarClipTesselator::calculateTriangleStatus( std::list<size_t>::const_iterator u,
|
||||||
std::list<size_t>::const_iterator v,
|
std::list<size_t>::const_iterator v,
|
||||||
std::list<size_t>::const_iterator w ) const
|
std::list<size_t>::const_iterator w ) const
|
||||||
{
|
{
|
||||||
CVF_ASSERT( m_X > -1 && m_Y > -1 );
|
CVF_ASSERT( m_X > -1 && m_Y > -1 );
|
||||||
|
|
||||||
@ -914,9 +944,17 @@ bool EarClipTesselator::isTriangleValid( std::list<size_t>::const_iterator u,
|
|||||||
cvf::Vec3d B = ( *m_nodeCoords )[*v];
|
cvf::Vec3d B = ( *m_nodeCoords )[*v];
|
||||||
cvf::Vec3d C = ( *m_nodeCoords )[*w];
|
cvf::Vec3d C = ( *m_nodeCoords )[*w];
|
||||||
|
|
||||||
if ( m_areaTolerance >
|
double mainAxisProjectedArea = ( ( B[m_X] - A[m_X] ) * ( C[m_Y] - A[m_Y] ) ) -
|
||||||
( ( ( B[m_X] - A[m_X] ) * ( C[m_Y] - A[m_Y] ) ) - ( ( B[m_Y] - A[m_Y] ) * ( C[m_X] - A[m_X] ) ) ) )
|
( ( B[m_Y] - A[m_Y] ) * ( C[m_X] - A[m_X] ) );
|
||||||
return false;
|
if ( -m_areaTolerance > mainAxisProjectedArea )
|
||||||
|
{
|
||||||
|
// Definite negative triangle
|
||||||
|
return INVALID_TRIANGLE;
|
||||||
|
}
|
||||||
|
else if ( fabs( mainAxisProjectedArea ) < m_areaTolerance )
|
||||||
|
{
|
||||||
|
return NEAR_ZERO_AREA_TRIANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
std::list<size_t>::const_iterator c;
|
std::list<size_t>::const_iterator c;
|
||||||
std::list<size_t>::const_iterator outside;
|
std::list<size_t>::const_iterator outside;
|
||||||
@ -948,15 +986,16 @@ bool EarClipTesselator::isTriangleValid( std::list<size_t>::const_iterator u,
|
|||||||
|
|
||||||
cvf::Vec3d P = ( *m_nodeCoords )[*c];
|
cvf::Vec3d P = ( *m_nodeCoords )[*c];
|
||||||
|
|
||||||
if ( isPointInsideTriangle( A, B, C, P ) ) return false;
|
if ( isPointInsideTriangle( A, B, C, P ) ) return INVALID_TRIANGLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return VALID_TRIANGLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
/// Decides if a point P is inside of the triangle defined by A, B, C.
|
/// Decides if a point P is inside of the triangle defined by A, B, C.
|
||||||
/// By calculating the "double area" (cross product) of Corner to corner x Corner to point vectors
|
/// By calculating the "double area" (cross product) of Corner to corner x Corner to point vectors
|
||||||
|
/// If cross product is negative, the point is outside
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool EarClipTesselator::isPointInsideTriangle( const cvf::Vec3d& A,
|
bool EarClipTesselator::isPointInsideTriangle( const cvf::Vec3d& A,
|
||||||
@ -983,7 +1022,8 @@ bool EarClipTesselator::isPointInsideTriangle( const cvf::Vec3d& A,
|
|||||||
double aCROSSbp = ax * bpy - ay * bpx;
|
double aCROSSbp = ax * bpy - ay * bpx;
|
||||||
double cCROSSap = cx * apy - cy * apx;
|
double cCROSSap = cx * apy - cy * apx;
|
||||||
double bCROSScp = bx * cpy - by * cpx;
|
double bCROSScp = bx * cpy - by * cpx;
|
||||||
double tol = 0;
|
double tol = -m_areaTolerance;
|
||||||
|
|
||||||
return ( ( aCROSSbp >= tol ) && ( bCROSScp >= tol ) && ( cCROSSap >= tol ) );
|
return ( ( aCROSSbp >= tol ) && ( bCROSScp >= tol ) && ( cCROSSap >= tol ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -209,9 +209,16 @@ public:
|
|||||||
virtual bool calculateTriangles( std::vector<size_t>* triangles );
|
virtual bool calculateTriangles( std::vector<size_t>* triangles );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool isTriangleValid( std::list<size_t>::const_iterator u,
|
enum TriangleStatus
|
||||||
std::list<size_t>::const_iterator v,
|
{
|
||||||
std::list<size_t>::const_iterator w ) const;
|
INVALID_TRIANGLE,
|
||||||
|
NEAR_ZERO_AREA_TRIANGLE,
|
||||||
|
VALID_TRIANGLE
|
||||||
|
};
|
||||||
|
TriangleStatus calculateTriangleStatus( std::list<size_t>::const_iterator u,
|
||||||
|
std::list<size_t>::const_iterator v,
|
||||||
|
std::list<size_t>::const_iterator w ) const;
|
||||||
|
|
||||||
bool isPointInsideTriangle( const cvf::Vec3d& A, const cvf::Vec3d& B, const cvf::Vec3d& C, const cvf::Vec3d& P ) const;
|
bool isPointInsideTriangle( const cvf::Vec3d& A, const cvf::Vec3d& B, const cvf::Vec3d& C, const cvf::Vec3d& P ) const;
|
||||||
double calculateProjectedPolygonArea() const;
|
double calculateProjectedPolygonArea() const;
|
||||||
|
|
||||||
|
@ -531,3 +531,44 @@ TEST( CellFaceIntersectionTst, PolygonAreaNormal3D )
|
|||||||
EXPECT_DOUBLE_EQ( 0.0, area.z() );
|
EXPECT_DOUBLE_EQ( 0.0, area.z() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST( EarClipTesselator, ErrorTest )
|
||||||
|
{
|
||||||
|
std::vector<cvf::Vec3d> remainingPolygon{
|
||||||
|
cvf::Vec3d( 44.66, 20.17, 0 ),
|
||||||
|
cvf::Vec3d( 78.08, 35.26, 0 ),
|
||||||
|
cvf::Vec3d( 93.97, 35.83, 0 ),
|
||||||
|
cvf::Vec3d( 144.95, 44.42, 0 ),
|
||||||
|
cvf::Vec3d( 172.59, 39.73, 0 ),
|
||||||
|
cvf::Vec3d( 227.27, 24.01, 0 ),
|
||||||
|
cvf::Vec3d( 217.46, 45.72, 0 ),
|
||||||
|
cvf::Vec3d( 178.5, 57.61, 0 ),
|
||||||
|
cvf::Vec3d( 141.33, 63.82, 0 ),
|
||||||
|
cvf::Vec3d( 0, 0, 0 ),
|
||||||
|
cvf::Vec3d( 63.77, 0, 0 ),
|
||||||
|
};
|
||||||
|
|
||||||
|
double nativeTriangleArea = 21266;
|
||||||
|
|
||||||
|
cvf::EarClipTesselator tess;
|
||||||
|
tess.setNormal( cvf::Vec3d::Z_AXIS );
|
||||||
|
tess.setMinTriangleArea( 1e-3 * nativeTriangleArea );
|
||||||
|
cvf::Vec3dArray cvfNodes( remainingPolygon );
|
||||||
|
tess.setGlobalNodeArray( cvfNodes );
|
||||||
|
|
||||||
|
std::vector<size_t> polyIndexes;
|
||||||
|
for ( size_t idx = 0; idx < remainingPolygon.size(); ++idx )
|
||||||
|
{
|
||||||
|
polyIndexes.push_back( idx );
|
||||||
|
}
|
||||||
|
tess.setPolygonIndices( polyIndexes );
|
||||||
|
|
||||||
|
std::vector<size_t> triangleIndices;
|
||||||
|
bool isTesselationOk = tess.calculateTriangles( &triangleIndices );
|
||||||
|
|
||||||
|
// CVF_ASSERT( isTesselationOk );
|
||||||
|
if ( !isTesselationOk )
|
||||||
|
{
|
||||||
|
// continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user