mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Rename ApplicationCode to ApplicationLibCode
This commit is contained in:
252
ApplicationLibCode/ReservoirDataModel/cvfGeometryTools.h
Normal file
252
ApplicationLibCode/ReservoirDataModel/cvfGeometryTools.h
Normal file
@@ -0,0 +1,252 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) Statoil ASA
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfArray.h"
|
||||
#include "cvfArrayWrapperConst.h"
|
||||
#include "cvfMatrix3.h"
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
class EdgeSplitStorage;
|
||||
template <typename IndexType>
|
||||
class EdgeIntersectStorage;
|
||||
|
||||
class GeometryTools
|
||||
{
|
||||
public:
|
||||
static cvf::Vec3d
|
||||
computeFaceCenter( const cvf::Vec3d& v0, const cvf::Vec3d& v1, const cvf::Vec3d& v2, const cvf::Vec3d& v3 );
|
||||
static cvf::Vec3d computeTriangleCenter( const cvf::Vec3d& v0, const cvf::Vec3d& v1, const cvf::Vec3d& v2 );
|
||||
template <typename Vec3Type>
|
||||
static Vec3Type computePolygonCenter( const std::vector<Vec3Type>& polygon );
|
||||
static cvf::Mat3f computePlaneHorizontalRotationMx( const cvf::Vec3f& inPlaneVec0, const cvf::Vec3f& inPlaneVec1 );
|
||||
|
||||
static cvf::Vec3d projectPointOnLine( const cvf::Vec3d& p1,
|
||||
const cvf::Vec3d& p2,
|
||||
const cvf::Vec3d& p3,
|
||||
double* normalizedIntersection );
|
||||
|
||||
static double linePointSquareDist( const cvf::Vec3d& p1, const cvf::Vec3d& p2, const cvf::Vec3d& p3 );
|
||||
static int intersectLineSegmentTriangle( const cvf::Vec3d p0,
|
||||
const cvf::Vec3d p1,
|
||||
const cvf::Vec3d t0,
|
||||
const cvf::Vec3d t1,
|
||||
const cvf::Vec3d t2,
|
||||
cvf::Vec3d* intersectionPoint,
|
||||
bool* isLineDirDotNormalNegative );
|
||||
static cvf::Vec3d
|
||||
barycentricCoords( const cvf::Vec3d& t0, const cvf::Vec3d& t1, const cvf::Vec3d& t2, const cvf::Vec3d& p );
|
||||
static cvf::Vec4d barycentricCoords( const cvf::Vec3d& v0,
|
||||
const cvf::Vec3d& v1,
|
||||
const cvf::Vec3d& v2,
|
||||
const cvf::Vec3d& v3,
|
||||
const cvf::Vec3d& p );
|
||||
template <typename DataType>
|
||||
static DataType interpolateQuad( const cvf::Vec3d& v1,
|
||||
DataType s1,
|
||||
const cvf::Vec3d& v2,
|
||||
DataType s2,
|
||||
const cvf::Vec3d& v3,
|
||||
DataType s3,
|
||||
const cvf::Vec3d& v4,
|
||||
DataType s4,
|
||||
const cvf::Vec3d& point );
|
||||
|
||||
static int findClosestAxis( const cvf::Vec3d& vec );
|
||||
static double getAngle( const cvf::Vec3d& positiveNormalAxis, const cvf::Vec3d& v1, const cvf::Vec3d& v2 );
|
||||
static double getAngle( const cvf::Vec3d& v1, const cvf::Vec3d& v2 );
|
||||
|
||||
static double signedAreaPlanarPolygon( const cvf::Vec3d& planeNormal, const std::vector<cvf::Vec3d>& polygon );
|
||||
|
||||
static cvf::Vec3d polygonAreaNormal3D( const std::vector<cvf::Vec3d>& polygon );
|
||||
static cvf::Vec3f polygonAreaNormal3D( const std::vector<cvf::Vec3f>& polygon );
|
||||
|
||||
enum IntersectionStatus
|
||||
{
|
||||
NO_INTERSECTION,
|
||||
LINES_INTERSECT_OUTSIDE,
|
||||
LINES_TOUCH,
|
||||
LINES_CROSSES,
|
||||
LINES_OVERLAP
|
||||
};
|
||||
|
||||
static void addMidEdgeNodes( std::list<std::pair<cvf::uint, bool>>* polygon,
|
||||
const cvf::Vec3dArray& nodes,
|
||||
EdgeSplitStorage& edgeSplitStorage,
|
||||
std::vector<cvf::Vec3d>* createdVertexes );
|
||||
|
||||
template <typename VerticeArrayType, typename IndexType>
|
||||
static bool insertVertexInPolygon( std::vector<IndexType>* polygon,
|
||||
ArrayWrapperConst<VerticeArrayType, cvf::Vec3d> nodeCoords,
|
||||
IndexType vertexIndex,
|
||||
double tolerance );
|
||||
|
||||
static IntersectionStatus inPlaneLineIntersect3D( const cvf::Vec3d& planeNormal,
|
||||
const cvf::Vec3d& p1,
|
||||
const cvf::Vec3d& p2,
|
||||
const cvf::Vec3d& p3,
|
||||
const cvf::Vec3d& p4,
|
||||
cvf::Vec3d* intersectionPoint,
|
||||
double* fractionAlongLine1,
|
||||
double* fractionAlongLine2,
|
||||
double tolerance = 1e-6 );
|
||||
|
||||
template <typename VerticeArrayType, typename PolygonArrayType, typename IndexType>
|
||||
static bool isPointTouchingIndexedPolygon( const cvf::Vec3d& polygonNormal,
|
||||
ArrayWrapperConst<VerticeArrayType, cvf::Vec3d> vertices,
|
||||
ArrayWrapperConst<PolygonArrayType, IndexType> indices,
|
||||
const cvf::Vec3d& point,
|
||||
int* touchedEdgeIndex,
|
||||
double tolerance = 1e-6 );
|
||||
|
||||
template <typename VerticeArrayType, typename IndexType>
|
||||
static bool calculateOverlapPolygonOfTwoQuads( std::vector<IndexType>* polygon,
|
||||
std::vector<cvf::Vec3d>* createdVertexes,
|
||||
EdgeIntersectStorage<IndexType>* edgeIntersectionStorage,
|
||||
ArrayWrapperConst<VerticeArrayType, cvf::Vec3d> nodes,
|
||||
const IndexType cv1CubeFaceIndices[4],
|
||||
const IndexType cv2CubeFaceIndices[4],
|
||||
double tolerance );
|
||||
|
||||
template <typename VerticeArrayType, typename PolygonArrayType, typename IndexType>
|
||||
static void
|
||||
calculatePartiallyFreeCubeFacePolygon( ArrayWrapperConst<VerticeArrayType, cvf::Vec3d> nodeCoords,
|
||||
ArrayWrapperConst<PolygonArrayType, IndexType> completeFacePolygon,
|
||||
const cvf::Vec3d& faceNormal,
|
||||
const std::vector<std::vector<IndexType>*>& faceOverlapPolygons,
|
||||
const std::vector<bool>& faceOverlapPolygonWindingSameAsCubeFaceFlags,
|
||||
std::vector<IndexType>* partialFacePolygon,
|
||||
bool* m_partiallyFreeCubeFaceHasHoles );
|
||||
};
|
||||
|
||||
template <typename IndexType>
|
||||
class EdgeIntersectStorage
|
||||
{
|
||||
public:
|
||||
void setVertexCount( size_t size );
|
||||
bool findIntersection( IndexType e1P1,
|
||||
IndexType e1P2,
|
||||
IndexType e2P1,
|
||||
IndexType e2P2,
|
||||
IndexType* vxIndexIntersectionPoint,
|
||||
GeometryTools::IntersectionStatus* intersectionStatus,
|
||||
double* fractionAlongEdge1,
|
||||
double* fractionAlongEdge2 );
|
||||
void addIntersection( IndexType e1P1,
|
||||
IndexType e1P2,
|
||||
IndexType e2P1,
|
||||
IndexType e2P2,
|
||||
IndexType vxIndexIntersectionPoint,
|
||||
GeometryTools::IntersectionStatus intersectionStatus,
|
||||
double fractionAlongEdge1,
|
||||
double fractionAlongEdge2 );
|
||||
|
||||
private:
|
||||
struct IntersectData
|
||||
{
|
||||
IndexType intersectionPointIndex;
|
||||
GeometryTools::IntersectionStatus intersectionStatus;
|
||||
double fractionAlongEdge1;
|
||||
double fractionAlongEdge2;
|
||||
};
|
||||
|
||||
void canonizeAddress( IndexType& e1P1,
|
||||
IndexType& e1P2,
|
||||
IndexType& e2P1,
|
||||
IndexType& e2P2,
|
||||
bool& flipE1,
|
||||
bool& flipE2,
|
||||
bool& flipE1E2 );
|
||||
|
||||
// A map containing the intersection data. The addressing is :
|
||||
// ( when leastVxIdxEdge1 < leastVxIdxEdge2 )
|
||||
// leastVxIdxEdge1, largestVxIdxEdge1, leastVxIdxEdge2, largestVxIdxEdge2, { vxIdxIntersection, fractionAlongEdg1,
|
||||
// fractionAlonEdge2 }
|
||||
|
||||
std::vector<std::map<IndexType, std::map<IndexType, std::map<IndexType, IntersectData>>>> m_edgeIntsectMap;
|
||||
};
|
||||
|
||||
class EdgeSplitStorage
|
||||
{
|
||||
public:
|
||||
void setVertexCount( size_t size );
|
||||
bool findSplitPoint( size_t edgeP1Index, size_t edgeP2Index, size_t* splitPointIndex );
|
||||
void addSplitPoint( size_t edgeP1Index, size_t edgeP2Index, size_t splitPointIndex );
|
||||
|
||||
private:
|
||||
void canonizeAddress( size_t& e1P1, size_t& e1P2 );
|
||||
|
||||
// Least VxIdx, LargestVxIdx, VertexIdx of splitpoint
|
||||
std::vector<std::map<size_t, size_t>> m_edgeSplitMap;
|
||||
};
|
||||
|
||||
class EarClipTesselator
|
||||
{
|
||||
public:
|
||||
EarClipTesselator();
|
||||
void setNormal( const cvf::Vec3d& polygonNormal );
|
||||
void setMinTriangleArea( double areaTolerance );
|
||||
void setGlobalNodeArray( const cvf::Vec3dArray& nodeCoords );
|
||||
|
||||
void setPolygonIndices( const std::list<size_t>& polygon );
|
||||
void setPolygonIndices( const std::vector<size_t>& polygon );
|
||||
|
||||
virtual bool calculateTriangles( std::vector<size_t>* triangles );
|
||||
|
||||
protected:
|
||||
enum TriangleStatus
|
||||
{
|
||||
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;
|
||||
double calculateProjectedPolygonArea() const;
|
||||
|
||||
protected:
|
||||
std::list<size_t> m_polygonIndices;
|
||||
const cvf::Vec3dArray* m_nodeCoords;
|
||||
int m_X, m_Y; // Index shift in vector to do simple 2D projection
|
||||
cvf::Vec3d m_polygonNormal;
|
||||
double m_areaTolerance;
|
||||
};
|
||||
|
||||
class FanEarClipTesselator : public EarClipTesselator
|
||||
{
|
||||
public:
|
||||
FanEarClipTesselator();
|
||||
|
||||
bool calculateTriangles( std::vector<size_t>* triangles ) override;
|
||||
|
||||
private:
|
||||
bool isTriangleValid( size_t u, size_t v, size_t w );
|
||||
size_t m_centerNodeIndex;
|
||||
};
|
||||
|
||||
} // namespace cvf
|
||||
|
||||
#include "cvfGeometryTools.inl"
|
||||
Reference in New Issue
Block a user