mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Add experimental test of using clipper to keep edge information through the clipping
This commit is contained in:
@@ -525,3 +525,137 @@ TEST( RigWellPathStimplanIntersector, intersection )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Test of whether we can transport edge information trough clipper clipping
|
||||
// Seems as if it might be possible, but clipper will ignore the edge information
|
||||
// processed by the callback if one of the edges is horizontal
|
||||
//
|
||||
|
||||
#include "clipper/clipper.hpp"
|
||||
double clipperConversionFactor2 = 10000; // For transform to clipper int
|
||||
|
||||
ClipperLib::IntPoint toClipperEdgePoint( const cvf::Vec3d& cvfPoint )
|
||||
{
|
||||
int xInt = cvfPoint.x() * clipperConversionFactor2;
|
||||
int yInt = cvfPoint.y() * clipperConversionFactor2;
|
||||
int zInt = cvfPoint.z();
|
||||
return ClipperLib::IntPoint( xInt, yInt, zInt );
|
||||
}
|
||||
|
||||
cvf::Vec3d fromClipperEdgePoint( const ClipperLib::IntPoint& clipPoint )
|
||||
{
|
||||
double zDValue;
|
||||
|
||||
if ( clipPoint.Z == std::numeric_limits<int>::max() )
|
||||
{
|
||||
zDValue = HUGE_VAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
zDValue = clipPoint.Z;
|
||||
}
|
||||
|
||||
return cvf::Vec3d( clipPoint.X / clipperConversionFactor2, clipPoint.Y / clipperConversionFactor2, zDValue );
|
||||
}
|
||||
|
||||
void swapPointsIfNeedeed( ClipperLib::IntPoint*& p1, ClipperLib::IntPoint*& p2 )
|
||||
{
|
||||
if ( p1->Z > p2->Z )
|
||||
{
|
||||
std::swap( p1, p2 );
|
||||
}
|
||||
|
||||
if ( ( p2->Z - p1->Z ) > 1 ) // End edge of polygon
|
||||
{
|
||||
std::swap( p1, p2 ); // Swap back
|
||||
}
|
||||
}
|
||||
|
||||
void clipperEdgeIntersectCallback( ClipperLib::IntPoint& e1bot,
|
||||
ClipperLib::IntPoint& e1top,
|
||||
ClipperLib::IntPoint& e2bot,
|
||||
ClipperLib::IntPoint& e2top,
|
||||
ClipperLib::IntPoint& pt )
|
||||
{
|
||||
ClipperLib::IntPoint* e11 = &e1bot;
|
||||
ClipperLib::IntPoint* e12 = &e1top;
|
||||
ClipperLib::IntPoint* e21 = &e2bot;
|
||||
ClipperLib::IntPoint* e22 = &e2top;
|
||||
|
||||
swapPointsIfNeedeed( e11, e12 );
|
||||
swapPointsIfNeedeed( e21, e22 );
|
||||
|
||||
cvf::Vec3f e1( e12->X - e11->X, e12->Y - e11->Y, 0.0 );
|
||||
cvf::Vec3f e2( e22->X - e21->X, e22->Y - e21->Y, 0.0 );
|
||||
|
||||
cvf::Vec3f up = e1 ^ e2;
|
||||
if ( up.z() > 0 )
|
||||
{
|
||||
pt.Z = e12->Z;
|
||||
std::cout << "E1 :" << e11->Z << " " << e12->Z << std::endl;
|
||||
std::cout << "E2 :" << e21->Z << " " << e22->Z << std::endl << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
pt.Z = e22->Z;
|
||||
std::cout << "E1 :" << e21->Z << " " << e22->Z << std::endl;
|
||||
std::cout << "E2 :" << e11->Z << " " << e12->Z << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
TEST( RigCellGeometryTools, ClipperEdgeTracking )
|
||||
{
|
||||
// If the first edges of the polygons are horizontal, the edge tracking will fail.
|
||||
// Encode polygon and edge into Z coordinate of the vertex
|
||||
|
||||
std::vector<cvf::Vec3d> polygon1 = {{0.0, 0.51, 1002.0}, {1.0, 0.5, 1000.0}, {0.0, 1.0, 1001.0}};
|
||||
std::vector<cvf::Vec3d> polygon2 = {{0.5, 0.01, 2002.0}, {1.0, 0.0, 2000.0}, {0.5, 1.0, 2001.0}};
|
||||
|
||||
std::vector<std::vector<cvf::Vec3d>> clippedPolygons;
|
||||
|
||||
// Convert to int for clipper library and store as clipper "path"
|
||||
ClipperLib::Path polygon1path;
|
||||
for ( const cvf::Vec3d& v : polygon1 )
|
||||
{
|
||||
polygon1path.push_back( toClipperEdgePoint( v ) );
|
||||
}
|
||||
|
||||
ClipperLib::Path polygon2path;
|
||||
for ( const cvf::Vec3d& v : polygon2 )
|
||||
{
|
||||
polygon2path.push_back( toClipperEdgePoint( v ) );
|
||||
}
|
||||
|
||||
ClipperLib::Clipper clpr;
|
||||
clpr.AddPath( polygon1path, ClipperLib::ptSubject, true );
|
||||
clpr.AddPath( polygon2path, ClipperLib::ptClip, true );
|
||||
|
||||
clpr.ZFillFunction( &clipperEdgeIntersectCallback );
|
||||
|
||||
ClipperLib::Paths solution;
|
||||
clpr.Execute( ClipperLib::ctIntersection, solution, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd );
|
||||
|
||||
// Convert back to std::vector<std::vector<cvf::Vec3d> >
|
||||
for ( ClipperLib::Path pathInSol : solution )
|
||||
{
|
||||
std::vector<cvf::Vec3d> clippedPolygon;
|
||||
for ( ClipperLib::IntPoint IntPosition : pathInSol )
|
||||
{
|
||||
clippedPolygon.push_back( fromClipperEdgePoint( IntPosition ) );
|
||||
}
|
||||
clippedPolygons.push_back( clippedPolygon );
|
||||
}
|
||||
|
||||
int pIdx = 1;
|
||||
for ( auto& polygon : clippedPolygons )
|
||||
{
|
||||
std::cout << "Polygon: " << pIdx << std::endl;
|
||||
for ( auto& point : polygon )
|
||||
{
|
||||
std::cout << " [ " << point[0] << ", " << point[1] << ", " << point[2] << " ]" << std::endl;
|
||||
}
|
||||
pIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user