mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
BACKUP Testing to create enclosing polygon from triangles per cell - WIP
This commit is contained in:
parent
091bd8163a
commit
1bdc8e95a1
@ -12,6 +12,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RivFemIntersectionGrid.h
|
${CMAKE_CURRENT_LIST_DIR}/RivFemIntersectionGrid.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivIntersectionGeometryGeneratorInterface.h
|
${CMAKE_CURRENT_LIST_DIR}/RivIntersectionGeometryGeneratorInterface.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivPolylineIntersectionGeometryGenerator.h
|
${CMAKE_CURRENT_LIST_DIR}/RivPolylineIntersectionGeometryGenerator.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RivEnclosingPolygonGenerator.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCE_GROUP_SOURCE_FILES
|
set(SOURCE_GROUP_SOURCE_FILES
|
||||||
@ -26,6 +27,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RivEclipseIntersectionGrid.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivEclipseIntersectionGrid.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivFemIntersectionGrid.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivFemIntersectionGrid.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivPolylineIntersectionGeometryGenerator.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivPolylineIntersectionGeometryGenerator.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RivEnclosingPolygonGenerator.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||||
|
@ -0,0 +1,285 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018- Equinor ASA
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "RivEnclosingPolygonGenerator.h"
|
||||||
|
#include "cvfMath.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
PolygonVertexWelder::PolygonVertexWelder( double weldEpsilon )
|
||||||
|
: m_epsilon( weldEpsilon )
|
||||||
|
, m_first( cvf::UNDEFINED_UINT )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void PolygonVertexWelder::reserveVertices( cvf::uint vertexCount )
|
||||||
|
{
|
||||||
|
m_vertex.reserve( vertexCount );
|
||||||
|
m_next.reserve( vertexCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<cvf::uint> PolygonVertexWelder::weldVerticesAndGetIndices( const std::vector<cvf::Vec3f>& vertices )
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
cvf::uint PolygonVertexWelder::weldVertexAndGetIndex( const cvf::Vec3f& vertex )
|
||||||
|
{
|
||||||
|
// Compute cell coordinates of bounding box of vertex epsilon neighborhood
|
||||||
|
int left = static_cast<int>( ( vertex.x() - m_epsilon ) );
|
||||||
|
int right = static_cast<int>( ( vertex.x() + m_epsilon ) );
|
||||||
|
int front = static_cast<int>( ( vertex.y() - m_epsilon ) );
|
||||||
|
int back = static_cast<int>( ( vertex.y() + m_epsilon ) );
|
||||||
|
int bottom = static_cast<int>( ( vertex.z() - m_epsilon ) );
|
||||||
|
int top = static_cast<int>( ( vertex.z() + m_epsilon ) );
|
||||||
|
|
||||||
|
// Call function to step through linked list of bucket, testing
|
||||||
|
// if vertex is within the epsilon of one of the vertices in the bucket
|
||||||
|
cvf::uint indexOfLocatedVertex = locateVertexInPolygon( vertex );
|
||||||
|
if ( indexOfLocatedVertex != cvf::UNDEFINED_UINT )
|
||||||
|
{
|
||||||
|
// if ( wasWelded ) *wasWelded = true;
|
||||||
|
return indexOfLocatedVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertex not found in epsilon neighborhood, add it to the list
|
||||||
|
cvf::uint indexOfAddedVertex = addVertexToPolygon( vertex );
|
||||||
|
return indexOfAddedVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
const cvf::Vec3f& PolygonVertexWelder::vertex( cvf::uint index ) const
|
||||||
|
{
|
||||||
|
return m_vertex[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
cvf::ref<cvf::Vec3fArray> PolygonVertexWelder::createVertexArray() const
|
||||||
|
{
|
||||||
|
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray( m_vertex );
|
||||||
|
return vertexArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
cvf::uint PolygonVertexWelder::locateVertexInPolygon( const cvf::Vec3f& vertex ) const
|
||||||
|
{
|
||||||
|
const auto epsilonSquared = m_epsilon * m_epsilon;
|
||||||
|
|
||||||
|
cvf::uint currentIndex = m_first;
|
||||||
|
while ( currentIndex != cvf::UNDEFINED_UINT )
|
||||||
|
{
|
||||||
|
// Weld point within tolerance
|
||||||
|
float distanceSquared = ( m_vertex[currentIndex] - vertex ).lengthSquared();
|
||||||
|
if ( distanceSquared < epsilonSquared )
|
||||||
|
{
|
||||||
|
return currentIndex;
|
||||||
|
}
|
||||||
|
currentIndex = m_next[currentIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// No vertex found to weld to
|
||||||
|
return cvf::UNDEFINED_UINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
cvf::uint PolygonVertexWelder::addVertexToPolygon( const cvf::Vec3f& vertex )
|
||||||
|
{
|
||||||
|
// Add vertex and update linked list
|
||||||
|
m_vertex.push_back( vertex );
|
||||||
|
m_next.push_back( m_first );
|
||||||
|
CVF_TIGHT_ASSERT( m_vertex.size() == m_next.size() );
|
||||||
|
|
||||||
|
// Update index of first vertex
|
||||||
|
cvf::uint indexOfAddedVertex = static_cast<cvf::uint>( m_vertex.size() - 1 );
|
||||||
|
m_first = indexOfAddedVertex;
|
||||||
|
|
||||||
|
return indexOfAddedVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
/// ************************************************************************************************
|
||||||
|
/// ************************************************************************************************
|
||||||
|
/// ************************************************************************************************
|
||||||
|
/// ************************************************************************************************
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RivEnclosingPolygonGenerator::RivEnclosingPolygonGenerator()
|
||||||
|
: m_polygonVertexWelder( 1e-6 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivEnclosingPolygonGenerator::constructEnclosingPolygon()
|
||||||
|
{
|
||||||
|
// Construct the enclosing polygon from the edges
|
||||||
|
//
|
||||||
|
// d ________ c
|
||||||
|
// | /|
|
||||||
|
// | / |
|
||||||
|
// | / |
|
||||||
|
// | / |
|
||||||
|
// | / |
|
||||||
|
// |/_____|
|
||||||
|
// a b
|
||||||
|
//
|
||||||
|
// The line segment ca/ac is the only edge that is not part of the enclosing polygon
|
||||||
|
// This line segment will occur twice in the list of edges as it is present in both triangles
|
||||||
|
// (a, b, c) and (a, c, d).
|
||||||
|
// The line segment ca/ac will be removed from the list of for the enclosing polygon
|
||||||
|
//
|
||||||
|
// Enclosing edges are defined as edges only occurring once in the list of edges
|
||||||
|
//
|
||||||
|
|
||||||
|
// Must have at least 3 edges to construct a polygon
|
||||||
|
CVF_ASSERT( m_allEdgeKeys.size() >= 3 );
|
||||||
|
|
||||||
|
// Map of edge key and number of occurrences
|
||||||
|
std::map<cvf::uint64, cvf::uint> edgeKeysAndCount;
|
||||||
|
|
||||||
|
// Extract boundary edge keys from all edge keys
|
||||||
|
for ( const auto& edgeKey : m_allEdgeKeys )
|
||||||
|
{
|
||||||
|
// If edge is already in the set, it occurs more than once and is not a boundary edge
|
||||||
|
if ( edgeKeysAndCount.contains( edgeKey ) )
|
||||||
|
{
|
||||||
|
edgeKeysAndCount[edgeKey]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
edgeKeysAndCount[edgeKey] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// At least a triangle is needed to construct a polygon
|
||||||
|
CVF_ASSERT( edgeKeysAndCount.size() >= 3 ); // This occurs to often?
|
||||||
|
|
||||||
|
// Extract boundary edge keys from all edge keys and count
|
||||||
|
std::set<cvf::EdgeKey> boundaryEdges;
|
||||||
|
for ( const auto& [key, value] : edgeKeysAndCount )
|
||||||
|
{
|
||||||
|
if ( value == 1 )
|
||||||
|
{
|
||||||
|
boundaryEdges.insert( cvf::EdgeKey::fromkeyVal( key ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lambda function to check if index exists in a vector
|
||||||
|
auto indexExists = []( const std::vector<cvf::uint>& indices, cvf::uint index ) -> bool
|
||||||
|
{ return std::find( indices.cbegin(), indices.cend(), index ) != indices.cend(); };
|
||||||
|
|
||||||
|
// Construct the enclosing polygon from the boundary edges
|
||||||
|
cvf::EdgeKey currentEdge = *boundaryEdges.begin();
|
||||||
|
std::vector<cvf::uint> enclosingPolygonVertexIndices = { currentEdge.index1(), currentEdge.index2() };
|
||||||
|
cvf::uint nextVertexIndex = currentEdge.index2();
|
||||||
|
boundaryEdges.erase( currentEdge );
|
||||||
|
while ( !boundaryEdges.empty() )
|
||||||
|
{
|
||||||
|
// Find next edge in the boundary, i.e. edge containing the next vertex index to look for
|
||||||
|
currentEdge = findNextEdge( nextVertexIndex, boundaryEdges );
|
||||||
|
boundaryEdges.erase( currentEdge );
|
||||||
|
const int start = currentEdge.index1();
|
||||||
|
const int end = currentEdge.index2();
|
||||||
|
if ( start == cvf::UNDEFINED_UINT || end == cvf::UNDEFINED_UINT )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The enclosing polygon is a closed loop, so the start and end vertices are always in the correct order
|
||||||
|
if ( !indexExists( enclosingPolygonVertexIndices, end ) )
|
||||||
|
{
|
||||||
|
nextVertexIndex = end;
|
||||||
|
enclosingPolygonVertexIndices.push_back( end );
|
||||||
|
}
|
||||||
|
else if ( !indexExists( enclosingPolygonVertexIndices, start ) )
|
||||||
|
{
|
||||||
|
nextVertexIndex = start;
|
||||||
|
enclosingPolygonVertexIndices.push_back( start );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert vertex indices to vertices
|
||||||
|
m_polygonVertices.clear();
|
||||||
|
for ( cvf::uint vertexIndex : enclosingPolygonVertexIndices )
|
||||||
|
{
|
||||||
|
m_polygonVertices.push_back( m_polygonVertexWelder.vertex( vertexIndex ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
cvf::EdgeKey RivEnclosingPolygonGenerator::findNextEdge( int vertexIndex, const std::set<cvf::EdgeKey>& boundaryEdges )
|
||||||
|
{
|
||||||
|
for ( auto& elm : boundaryEdges )
|
||||||
|
{
|
||||||
|
if ( elm.index1() == vertexIndex || elm.index2() == vertexIndex )
|
||||||
|
{
|
||||||
|
return elm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a dummy edge to indicate no next edge found
|
||||||
|
return cvf::EdgeKey( cvf::UNDEFINED_UINT, cvf::UNDEFINED_UINT );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<cvf::Vec3f> RivEnclosingPolygonGenerator::getPolygonVertices() const
|
||||||
|
{
|
||||||
|
return m_polygonVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivEnclosingPolygonGenerator::addTriangleVertices( const cvf::Vec3f& p0, const cvf::Vec3f& p1, const cvf::Vec3f& p2 )
|
||||||
|
{
|
||||||
|
cvf::uint i0 = m_polygonVertexWelder.weldVertexAndGetIndex( p0 );
|
||||||
|
cvf::uint i1 = m_polygonVertexWelder.weldVertexAndGetIndex( p1 );
|
||||||
|
cvf::uint i2 = m_polygonVertexWelder.weldVertexAndGetIndex( p2 );
|
||||||
|
|
||||||
|
// Add edges keys to list of all edges
|
||||||
|
m_allEdgeKeys.emplace_back( cvf::EdgeKey( i0, i1 ).toKeyVal() );
|
||||||
|
m_allEdgeKeys.emplace_back( cvf::EdgeKey( i1, i2 ).toKeyVal() );
|
||||||
|
m_allEdgeKeys.emplace_back( cvf::EdgeKey( i2, i0 ).toKeyVal() );
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018- Equinor ASA
|
||||||
|
//
|
||||||
|
// 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 "cafLine.h"
|
||||||
|
#include "cvfArray.h"
|
||||||
|
#include "cvfEdgeKey.h"
|
||||||
|
#include "cvfObject.h"
|
||||||
|
#include "cvfVector3.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for handling welding of vertices in a polygon to prevent duplicated vertex 3D points within a tolerance margin
|
||||||
|
*/
|
||||||
|
class PolygonVertexWelder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PolygonVertexWelder( double weldEpsilon );
|
||||||
|
|
||||||
|
void reserveVertices( cvf::uint vertexCount );
|
||||||
|
|
||||||
|
// Add a vertex to the welder. If the vertex is within the tolerance of an existing vertex, the existing vertex index is returned
|
||||||
|
// Size of returned index array is equal size of input array
|
||||||
|
std::vector<cvf::uint> weldVerticesAndGetIndices( const std::vector<cvf::Vec3f>& vertices ); // TODO: Remove?
|
||||||
|
cvf::uint weldVertexAndGetIndex( const cvf::Vec3f& vertex );
|
||||||
|
|
||||||
|
const cvf::Vec3f& vertex( cvf::uint index ) const;
|
||||||
|
cvf::ref<cvf::Vec3fArray> createVertexArray() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
cvf::uint locateVertexInPolygon( const cvf::Vec3f& vertex ) const;
|
||||||
|
cvf::uint addVertexToPolygon( const cvf::Vec3f& vertex );
|
||||||
|
|
||||||
|
private:
|
||||||
|
const double m_epsilon; // Tolerance for vertex welding, radius around vertex defining welding neighborhood
|
||||||
|
|
||||||
|
cvf::uint m_first; // Start of linked list
|
||||||
|
std::vector<cvf::uint> m_next; // Links each vertex to next in linked list. Always numVertices long, will grow as vertices are added
|
||||||
|
std::vector<cvf::Vec3f> m_vertex; // Unique vertices within tolerance
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for generating an enclosing polygon from a set of vertices.
|
||||||
|
*
|
||||||
|
* The class will weld triangle vertices close to each other and provide a vertex index for
|
||||||
|
* the resulting set of vertices. These indices are used for algorithms constructing the enclosing polygon.
|
||||||
|
*
|
||||||
|
* The welding is done using a tolerance value to handle floating point errors.
|
||||||
|
*/
|
||||||
|
class RivEnclosingPolygonGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RivEnclosingPolygonGenerator();
|
||||||
|
|
||||||
|
std::vector<cvf::Vec3f> getPolygonVertices() const;
|
||||||
|
|
||||||
|
bool isValidPolygon() const { return m_allEdgeKeys.size() >= size_t( 3 ); }
|
||||||
|
size_t numEdges() const { return m_allEdgeKeys.size(); }
|
||||||
|
|
||||||
|
void addTriangleVertices( const cvf::Vec3f& p0, const cvf::Vec3f& p1, const cvf::Vec3f& p2 );
|
||||||
|
void constructEnclosingPolygon();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static cvf::EdgeKey findNextEdge( int vertextIndex, const std::set<cvf::EdgeKey>& boundaryEdges );
|
||||||
|
|
||||||
|
private:
|
||||||
|
PolygonVertexWelder m_polygonVertexWelder; // Add and weld vertices for a polygon, provides vertex index
|
||||||
|
std::vector<cvf::int64> m_allEdgeKeys; // Create edge defined by vertex indices when adding triangle. Using cvf::EdgeKey::toKeyVal()
|
||||||
|
std::vector<cvf::Vec3f> m_polygonVertices; // List polygon vertices counter clock-wise
|
||||||
|
};
|
@ -18,12 +18,15 @@
|
|||||||
|
|
||||||
#include "RivPolylineIntersectionGeometryGenerator.h"
|
#include "RivPolylineIntersectionGeometryGenerator.h"
|
||||||
|
|
||||||
|
#include "RivEnclosingPolygonGenerator.h"
|
||||||
#include "RivIntersectionHexGridInterface.h"
|
#include "RivIntersectionHexGridInterface.h"
|
||||||
#include "RivSectionFlattener.h"
|
#include "RivSectionFlattener.h"
|
||||||
|
|
||||||
#include "cafHexGridIntersectionTools/cafHexGridIntersectionTools.h"
|
#include "cafHexGridIntersectionTools/cafHexGridIntersectionTools.h"
|
||||||
|
#include "cafLine.h"
|
||||||
|
|
||||||
#include "cvfPlane.h"
|
#include "cvfPlane.h"
|
||||||
|
#include "cvfVertexWelder.h"
|
||||||
|
|
||||||
#pragma optimize( "", off )
|
#pragma optimize( "", off )
|
||||||
|
|
||||||
@ -35,7 +38,8 @@ RivPolylineIntersectionGeometryGenerator::RivPolylineIntersectionGeometryGenerat
|
|||||||
: m_polyline( polyline )
|
: m_polyline( polyline )
|
||||||
, m_hexGrid( grid )
|
, m_hexGrid( grid )
|
||||||
{
|
{
|
||||||
m_triangleVxes = new cvf::Vec3fArray;
|
m_triangleVxes = new cvf::Vec3fArray;
|
||||||
|
m_polygonVertices = new cvf::Vec3fArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -50,7 +54,8 @@ RivPolylineIntersectionGeometryGenerator::~RivPolylineIntersectionGeometryGenera
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RivPolylineIntersectionGeometryGenerator::isAnyGeometryPresent() const
|
bool RivPolylineIntersectionGeometryGenerator::isAnyGeometryPresent() const
|
||||||
{
|
{
|
||||||
return m_triangleVxes->size() > 0;
|
return m_polygonVertices->size() > 0;
|
||||||
|
// return m_triangleVxes->size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -76,12 +81,39 @@ const cvf::Vec3fArray* RivPolylineIntersectionGeometryGenerator::triangleVxes()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
const std::vector<RivIntersectionVertexWeights>& RivPolylineIntersectionGeometryGenerator::triangleVxToCellCornerInterpolationWeights() const
|
const std::vector<RivIntersectionVertexWeights>& RivPolylineIntersectionGeometryGenerator::triangleVxToCellCornerInterpolationWeights() const
|
||||||
{
|
{
|
||||||
CVF_ASSERT( m_triangleVxes->size() > 0 );
|
CVF_ASSERT( false );
|
||||||
|
|
||||||
// Not implemented error
|
// Not implemented error
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
const cvf::Vec3fArray* RivPolylineIntersectionGeometryGenerator::polygonVxes() const
|
||||||
|
{
|
||||||
|
CVF_ASSERT( m_polygonVertices->size() > 0 );
|
||||||
|
return m_polygonVertices.p();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
const std::vector<size_t>& RivPolylineIntersectionGeometryGenerator::vertiesPerPolygon() const
|
||||||
|
{
|
||||||
|
CVF_ASSERT( m_verticesPerPolygon.size() > 0 );
|
||||||
|
return m_verticesPerPolygon;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
const std::vector<size_t>& RivPolylineIntersectionGeometryGenerator::polygonToCellIndex() const
|
||||||
|
{
|
||||||
|
CVF_ASSERT( m_polygonToCellIdxMap.size() > 0 );
|
||||||
|
return m_polygonToCellIdxMap;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -95,11 +127,10 @@ void RivPolylineIntersectionGeometryGenerator::generateIntersectionGeometry( cvf
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RivPolylineIntersectionGeometryGenerator::calculateArrays( cvf::UByteArray* visibleCells )
|
void RivPolylineIntersectionGeometryGenerator::calculateArrays( cvf::UByteArray* visibleCells )
|
||||||
{
|
{
|
||||||
if ( m_triangleVxes->size() != 0 || m_hexGrid.isNull() ) return;
|
if ( m_triangleVxes->size() != 0 || m_polygonVertices->size() != 0 || m_hexGrid.isNull() ) return;
|
||||||
|
|
||||||
std::vector<cvf::Vec3f> calculatedTriangleVertices;
|
std::vector<cvf::Vec3f> calculatedTriangleVertices;
|
||||||
|
std::vector<cvf::Vec3f> calculatedPolygonVertices;
|
||||||
// MeshLinesAccumulator meshAcc( m_hexGrid.p() );
|
|
||||||
|
|
||||||
cvf::BoundingBox gridBBox = m_hexGrid->boundingBox();
|
cvf::BoundingBox gridBBox = m_hexGrid->boundingBox();
|
||||||
|
|
||||||
@ -142,6 +173,7 @@ void RivPolylineIntersectionGeometryGenerator::calculateArrays( cvf::UByteArray*
|
|||||||
const cvf::Vec3d p1 = m_polyline[pointIdx];
|
const cvf::Vec3d p1 = m_polyline[pointIdx];
|
||||||
const cvf::Vec3d p2 = m_polyline[nextPointIdx];
|
const cvf::Vec3d p2 = m_polyline[nextPointIdx];
|
||||||
|
|
||||||
|
// Get cell candidates for the polyline segment (subset of global cells)
|
||||||
std::vector<size_t> columnCellCandidates =
|
std::vector<size_t> columnCellCandidates =
|
||||||
createPolylineSegmentCellCandidates( *m_hexGrid, p1, p2, maxHeightVec, topDepth, bottomDepth );
|
createPolylineSegmentCellCandidates( *m_hexGrid, p1, p2, maxHeightVec, topDepth, bottomDepth );
|
||||||
|
|
||||||
@ -154,17 +186,22 @@ void RivPolylineIntersectionGeometryGenerator::calculateArrays( cvf::UByteArray*
|
|||||||
cvf::Plane p2Plane;
|
cvf::Plane p2Plane;
|
||||||
p2Plane.setFromPoints( p2, p2 + maxHeightVec, p2 - plane.normal() );
|
p2Plane.setFromPoints( p2, p2 + maxHeightVec, p2 - plane.normal() );
|
||||||
|
|
||||||
|
// Placeholder for triangle vertices per cell
|
||||||
std::vector<caf::HexGridIntersectionTools::ClipVx> hexPlaneCutTriangleVxes;
|
std::vector<caf::HexGridIntersectionTools::ClipVx> hexPlaneCutTriangleVxes;
|
||||||
hexPlaneCutTriangleVxes.reserve( 5 * 3 );
|
hexPlaneCutTriangleVxes.reserve( 5 * 3 );
|
||||||
std::vector<int> cellFaceForEachTriangleEdge;
|
std::vector<int> cellFaceForEachTriangleEdge;
|
||||||
cellFaceForEachTriangleEdge.reserve( 5 * 3 );
|
cellFaceForEachTriangleEdge.reserve( 5 * 3 );
|
||||||
cvf::Vec3d cellCorners[8];
|
cvf::Vec3d cellCorners[8];
|
||||||
size_t cornerIndices[8];
|
size_t cornerIndices[8];
|
||||||
|
|
||||||
|
// Handle triangles per cell
|
||||||
for ( const auto globalCellIdx : columnCellCandidates )
|
for ( const auto globalCellIdx : columnCellCandidates )
|
||||||
{
|
{
|
||||||
if ( ( visibleCells != nullptr ) && ( ( *visibleCells )[globalCellIdx] == 0 ) ) continue;
|
if ( ( visibleCells != nullptr ) && ( ( *visibleCells )[globalCellIdx] == 0 ) ) continue;
|
||||||
if ( !m_hexGrid->useCell( globalCellIdx ) ) continue;
|
if ( !m_hexGrid->useCell( globalCellIdx ) ) continue;
|
||||||
|
|
||||||
|
// if ( globalCellIdx != 93996 ) continue;
|
||||||
|
|
||||||
hexPlaneCutTriangleVxes.clear();
|
hexPlaneCutTriangleVxes.clear();
|
||||||
m_hexGrid->cellCornerVertices( globalCellIdx, cellCorners );
|
m_hexGrid->cellCornerVertices( globalCellIdx, cellCorners );
|
||||||
m_hexGrid->cellCornerIndices( globalCellIdx, cornerIndices );
|
m_hexGrid->cellCornerIndices( globalCellIdx, cornerIndices );
|
||||||
@ -176,7 +213,19 @@ void RivPolylineIntersectionGeometryGenerator::calculateArrays( cvf::UByteArray*
|
|||||||
&hexPlaneCutTriangleVxes,
|
&hexPlaneCutTriangleVxes,
|
||||||
&cellFaceForEachTriangleEdge );
|
&cellFaceForEachTriangleEdge );
|
||||||
|
|
||||||
// Clip triangles outside the polyline segment using p1 and p2 planes
|
// DEBUG CODE
|
||||||
|
bool tmp = false;
|
||||||
|
if ( hexPlaneCutTriangleVxes.size() < 3 )
|
||||||
|
{
|
||||||
|
tmp = true;
|
||||||
|
}
|
||||||
|
if ( globalCellIdx == 93996 )
|
||||||
|
{
|
||||||
|
tmp = true;
|
||||||
|
}
|
||||||
|
// END DEBUG CODE
|
||||||
|
|
||||||
|
// Clip triangles outside the polyline segment using the planes for point p1 and p2
|
||||||
std::vector<caf::HexGridIntersectionTools::ClipVx> clippedTriangleVxes;
|
std::vector<caf::HexGridIntersectionTools::ClipVx> clippedTriangleVxes;
|
||||||
std::vector<int> cellFaceForEachClippedTriangleEdge;
|
std::vector<int> cellFaceForEachClippedTriangleEdge;
|
||||||
|
|
||||||
@ -192,6 +241,9 @@ void RivPolylineIntersectionGeometryGenerator::calculateArrays( cvf::UByteArray*
|
|||||||
if ( !clvx.isVxIdsNative ) clvx.derivedVxLevel = 0;
|
if ( !clvx.isVxIdsNative ) clvx.derivedVxLevel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Object to for adding triangle vertices, well vertices and generate polygon vertices
|
||||||
|
RivEnclosingPolygonGenerator enclosingPolygonGenerator;
|
||||||
|
|
||||||
// Fill triangle vertices vector with clipped triangle vertices
|
// Fill triangle vertices vector with clipped triangle vertices
|
||||||
size_t clippedTriangleCount = clippedTriangleVxes.size() / 3;
|
size_t clippedTriangleCount = clippedTriangleVxes.size() / 3;
|
||||||
for ( size_t triangleIdx = 0; triangleIdx < clippedTriangleCount; ++triangleIdx )
|
for ( size_t triangleIdx = 0; triangleIdx < clippedTriangleCount; ++triangleIdx )
|
||||||
@ -200,26 +252,46 @@ void RivPolylineIntersectionGeometryGenerator::calculateArrays( cvf::UByteArray*
|
|||||||
const size_t vxIdx1 = vxIdx0 + 1;
|
const size_t vxIdx1 = vxIdx0 + 1;
|
||||||
const size_t vxIdx2 = vxIdx0 + 2;
|
const size_t vxIdx2 = vxIdx0 + 2;
|
||||||
|
|
||||||
// Accumulate triangle vertices
|
const cvf::Vec3f point0( clippedTriangleVxes[vxIdx0].vx );
|
||||||
cvf::Vec3f point0( clippedTriangleVxes[vxIdx0].vx );
|
const cvf::Vec3f point1( clippedTriangleVxes[vxIdx1].vx );
|
||||||
cvf::Vec3f point1( clippedTriangleVxes[vxIdx1].vx );
|
const cvf::Vec3f point2( clippedTriangleVxes[vxIdx2].vx );
|
||||||
cvf::Vec3f point2( clippedTriangleVxes[vxIdx2].vx );
|
|
||||||
|
|
||||||
calculatedTriangleVertices.emplace_back( point0 );
|
calculatedTriangleVertices.emplace_back( point0 );
|
||||||
calculatedTriangleVertices.emplace_back( point1 );
|
calculatedTriangleVertices.emplace_back( point1 );
|
||||||
calculatedTriangleVertices.emplace_back( point2 );
|
calculatedTriangleVertices.emplace_back( point2 );
|
||||||
|
|
||||||
// TODO: Accumulate mesh lines?
|
// Add triangle to enclosing polygon line handler
|
||||||
// meshAcc.accumulateMeshLines( cellFaceForEachTriangleEdge, ...
|
enclosingPolygonGenerator.addTriangleVertices( point0, point1, point2 );
|
||||||
|
|
||||||
m_triangleToCellIdxMap.push_back( globalCellIdx );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must be a triangle
|
||||||
|
if ( enclosingPolygonGenerator.numEdges() < size_t( 3 ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct enclosing polygon after adding each triangle
|
||||||
|
enclosingPolygonGenerator.constructEnclosingPolygon();
|
||||||
|
const auto& vertices = enclosingPolygonGenerator.getPolygonVertices();
|
||||||
|
for ( const auto& vertex : enclosingPolygonGenerator.getPolygonVertices() )
|
||||||
|
{
|
||||||
|
calculatedPolygonVertices.push_back( vertex );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_verticesPerPolygon.push_back( vertices.size() );
|
||||||
|
m_polygonToCellIdxMap.push_back( globalCellIdx );
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// - Create polygon
|
||||||
|
// - Get polygon indices
|
||||||
|
// - Convert to "local" coordinates for each polyline segment
|
||||||
}
|
}
|
||||||
pointIdx = nextPointIdx;
|
pointIdx = nextPointIdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_triangleVxes->assign( calculatedTriangleVertices );
|
m_triangleVxes->assign( calculatedTriangleVertices );
|
||||||
|
m_polygonVertices->assign( calculatedPolygonVertices );
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -51,7 +51,10 @@ public:
|
|||||||
RivPolylineIntersectionGeometryGenerator( std::vector<cvf::Vec3d>& polyline, RivIntersectionHexGridInterface* grid );
|
RivPolylineIntersectionGeometryGenerator( std::vector<cvf::Vec3d>& polyline, RivIntersectionHexGridInterface* grid );
|
||||||
~RivPolylineIntersectionGeometryGenerator() override;
|
~RivPolylineIntersectionGeometryGenerator() override;
|
||||||
|
|
||||||
void generateIntersectionGeometry( cvf::UByteArray* visibleCells );
|
void generateIntersectionGeometry( cvf::UByteArray* visibleCells );
|
||||||
|
const cvf::Vec3fArray* polygonVxes() const;
|
||||||
|
const std::vector<size_t>& vertiesPerPolygon() const;
|
||||||
|
const std::vector<size_t>& polygonToCellIndex() const;
|
||||||
|
|
||||||
// GeomGen Interface
|
// GeomGen Interface
|
||||||
bool isAnyGeometryPresent() const override;
|
bool isAnyGeometryPresent() const override;
|
||||||
@ -75,4 +78,8 @@ private:
|
|||||||
// Output arrays
|
// Output arrays
|
||||||
cvf::ref<cvf::Vec3fArray> m_triangleVxes;
|
cvf::ref<cvf::Vec3fArray> m_triangleVxes;
|
||||||
std::vector<size_t> m_triangleToCellIdxMap;
|
std::vector<size_t> m_triangleToCellIdxMap;
|
||||||
|
|
||||||
|
std::vector<size_t> m_polygonToCellIdxMap;
|
||||||
|
cvf::ref<cvf::Vec3fArray> m_polygonVertices;
|
||||||
|
std::vector<size_t> m_verticesPerPolygon;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
import "Grid.proto";
|
|
||||||
import "VectorDefines.proto";
|
import "VectorDefines.proto";
|
||||||
|
|
||||||
// Will this work if we import only part of the protos?
|
// Will this work if we import only part of the protos?
|
||||||
@ -48,7 +47,7 @@ message GetGridSurfaceResponse
|
|||||||
repeated float vertexArray = 1;
|
repeated float vertexArray = 1;
|
||||||
repeated fixed32 quadIndicesArr = 2; // 4*NumQuads long
|
repeated fixed32 quadIndicesArr = 2; // 4*NumQuads long
|
||||||
repeated fixed32 sourceCellIndicesArr = 3; // The originating cell index per quad, longnumQuads long
|
repeated fixed32 sourceCellIndicesArr = 3; // The originating cell index per quad, longnumQuads long
|
||||||
GridDimensions gridDimensions = 5;
|
Vec3i gridDimensions = 5;
|
||||||
Vec3d originUtm = 6;
|
Vec3d originUtm = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,11 +71,12 @@ message FenceMeshSection
|
|||||||
//message CutAlongPolylineResponse
|
//message CutAlongPolylineResponse
|
||||||
//{
|
//{
|
||||||
// repeated FenceMeshSection feceMeshSections = 1;
|
// repeated FenceMeshSection feceMeshSections = 1;
|
||||||
//GridDimensions gridDimensions = 2;
|
//Vec3i gridDimensions = 2;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
message CutAlongPolylineResponse
|
message CutAlongPolylineResponse
|
||||||
{
|
{
|
||||||
repeated float vertexArray = 1;
|
repeated float polygonVertexArray = 1;
|
||||||
GridDimensions gridDimensions = 2;
|
repeated fixed32 verticesPerPolygonArr = 2; // Number of vertices per polygon, numPolygons long
|
||||||
|
repeated fixed32 sourceCellIndicesArr = 3; // The originating cell index per polygon, numPolygons long
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,190 @@
|
|||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
|
||||||
|
from rips.instance import *
|
||||||
|
from rips.generated.GridGeometryExtraction_pb2_grpc import *
|
||||||
|
from rips.generated.GridGeometryExtraction_pb2 import *
|
||||||
|
|
||||||
|
# from ..instance import *
|
||||||
|
# from ..generated.GridGeometryExtraction_pb2_grpc import *
|
||||||
|
# from ..generated.GridGeometryExtraction_pb2 import *
|
||||||
|
|
||||||
|
rips_instance = Instance.find()
|
||||||
|
grid_geometry_extraction_stub = GridGeometryExtractionStub(rips_instance.channel)
|
||||||
|
|
||||||
|
grid_file_name = None
|
||||||
|
grid_file_name = "D:\\Git\\resinsight-tutorials\\model-data\\norne\\NORNE_ATW2013_RFTPLT_V2.EGRID"
|
||||||
|
|
||||||
|
# Test polylines
|
||||||
|
mocked_model_fence_poly_line_utm_xy = [11.2631, 11.9276, 14.1083, 18.2929, 18.3523, 10.9173]
|
||||||
|
norne_case_fence_poly_line_utm_xy = [456221, 7.32113e+06, 457150, 7.32106e+06, 456885, 7.32176e+06, 457648, 7.3226e+06, 458805, 7.32278e+06]
|
||||||
|
norne_case_single_segment_poly_line_utm_xy = [457150, 7.32106e+06, 456885, 7.32176e+06]
|
||||||
|
norne_case_single_segment_poly_line_gap_utm_xy = [460877, 7.3236e+06, 459279, 7.32477e+06]
|
||||||
|
|
||||||
|
|
||||||
|
fence_poly_line_utm_xy = norne_case_single_segment_poly_line_utm_xy
|
||||||
|
|
||||||
|
cut_along_polyline_request = GridGeometryExtraction__pb2.CutAlongPolylineRequest(
|
||||||
|
gridFilename=grid_file_name,
|
||||||
|
fencePolylineUtmXY=fence_poly_line_utm_xy,
|
||||||
|
)
|
||||||
|
cut_along_polyline_response: GridGeometryExtraction__pb2.CutAlongPolylineResponse = (
|
||||||
|
grid_geometry_extraction_stub.CutAlongPolyline(cut_along_polyline_request)
|
||||||
|
)
|
||||||
|
|
||||||
|
polygon_vertex_array_org = cut_along_polyline_response.polygonVertexArray
|
||||||
|
vertices_per_polygon = cut_along_polyline_response.verticesPerPolygonArr
|
||||||
|
source_cell_indices = cut_along_polyline_response.sourceCellIndicesArr
|
||||||
|
|
||||||
|
x_start = polygon_vertex_array_org[0]
|
||||||
|
y_start = polygon_vertex_array_org[1]
|
||||||
|
z_start = polygon_vertex_array_org[2]
|
||||||
|
|
||||||
|
# Subtract x_start, y_start, z_start from all x, y, z coordinates
|
||||||
|
polygon_vertex_array = []
|
||||||
|
for i in range(0, len(polygon_vertex_array_org), 3):
|
||||||
|
polygon_vertex_array.extend([polygon_vertex_array_org[i] - x_start, polygon_vertex_array_org[i + 1] - y_start, polygon_vertex_array_org[i + 2] - z_start])
|
||||||
|
|
||||||
|
num_vertex_coords = 3 # [x, y, z]
|
||||||
|
|
||||||
|
# Create x-, y-, and z-arrays
|
||||||
|
x_array = []
|
||||||
|
y_array = []
|
||||||
|
z_array = []
|
||||||
|
for i in range(0, len(polygon_vertex_array), num_vertex_coords):
|
||||||
|
# vertex array is provided as a single array of x, y, z coordinates
|
||||||
|
# i.e. [x1, y1, z1, x2, y2, z2, x3, y3, z3, ... , xn, yn, zn]
|
||||||
|
x_array.append(polygon_vertex_array[i + 0] )
|
||||||
|
y_array.append(polygon_vertex_array[i + 1] )
|
||||||
|
z_array.append(polygon_vertex_array[i + 2] )
|
||||||
|
|
||||||
|
# Create triangular mesh
|
||||||
|
vertices = np.array(polygon_vertex_array).reshape(-1, 3)
|
||||||
|
|
||||||
|
# Create mesh data
|
||||||
|
x, y, z = vertices.T
|
||||||
|
i = []
|
||||||
|
j = []
|
||||||
|
k = []
|
||||||
|
|
||||||
|
# Create edges between points in triangles
|
||||||
|
triangle_edges_x = []
|
||||||
|
triangle_edges_y = []
|
||||||
|
triangle_edges_z = []
|
||||||
|
|
||||||
|
# Populate i, j, k based on vertices_per_polygon
|
||||||
|
# Create triangles from each polygon
|
||||||
|
# A quad with vertex [0,1,2,3] will be split into two triangles [0,1,2] and [0,2,3]
|
||||||
|
# A hexagon with vertex [0,1,2,3,4,5] will be split into four triangles [0,1,2], [0,2,3], [0,3,4], [0,4,5]
|
||||||
|
|
||||||
|
polygon_v0_idx = 0 # Index of vertex 0 in the polygon
|
||||||
|
for vertex_count in vertices_per_polygon:
|
||||||
|
# Must have at least one triangle
|
||||||
|
if vertex_count < 3:
|
||||||
|
polygon_v0_idx += vertex_count
|
||||||
|
continue
|
||||||
|
|
||||||
|
indices = list(range(polygon_v0_idx, polygon_v0_idx + vertex_count))
|
||||||
|
|
||||||
|
# Build triangles from polygon
|
||||||
|
num_triangles = vertex_count - 2
|
||||||
|
for triangle_index in range(0, num_triangles):
|
||||||
|
triangle_v0_idx = polygon_v0_idx
|
||||||
|
triangle_v1_idx = indices[triangle_index + 1]
|
||||||
|
triangle_v2_idx = indices[triangle_index + 2]
|
||||||
|
|
||||||
|
# Vertex indices for the triangle
|
||||||
|
i.append(triangle_v0_idx)
|
||||||
|
j.append(triangle_v1_idx)
|
||||||
|
k.append(triangle_v2_idx)
|
||||||
|
|
||||||
|
# Create edge between vertices in triangle with x,y,z coordinates, coordinates per vertex is 3
|
||||||
|
coordinate_step = 3 # step per vertex
|
||||||
|
triangle_v0_global_idx = triangle_v0_idx * coordinate_step
|
||||||
|
triangle_v1_global_idx = triangle_v1_idx * coordinate_step
|
||||||
|
triangle_v2_global_idx = triangle_v2_idx * coordinate_step
|
||||||
|
|
||||||
|
# Add x,y,z coordinates for the triangle vertices (closing triangle with 'None')
|
||||||
|
triangle_edges_x.extend([polygon_vertex_array[triangle_v0_global_idx + 0], polygon_vertex_array[triangle_v1_global_idx + 0], polygon_vertex_array[triangle_v2_global_idx + 0], polygon_vertex_array[triangle_v0_global_idx + 0], None])
|
||||||
|
triangle_edges_y.extend([polygon_vertex_array[triangle_v0_global_idx + 1], polygon_vertex_array[triangle_v1_global_idx + 1], polygon_vertex_array[triangle_v2_global_idx + 1], polygon_vertex_array[triangle_v0_global_idx + 1], None])
|
||||||
|
triangle_edges_z.extend([polygon_vertex_array[triangle_v0_global_idx + 2], polygon_vertex_array[triangle_v1_global_idx + 2], polygon_vertex_array[triangle_v2_global_idx + 2], polygon_vertex_array[triangle_v0_global_idx + 2], None])
|
||||||
|
|
||||||
|
# Move to next polygon
|
||||||
|
polygon_v0_idx += vertex_count
|
||||||
|
|
||||||
|
# Create edges between points in polygons
|
||||||
|
polygon_edges_x = []
|
||||||
|
polygon_edges_y = []
|
||||||
|
polygon_edges_z = []
|
||||||
|
polygon_global_start_index = 0
|
||||||
|
coordinate_step = 3 # step per vertex
|
||||||
|
for vertex_count in vertices_per_polygon:
|
||||||
|
# Must have at least a triangle
|
||||||
|
if vertex_count < 3:
|
||||||
|
polygon_global_start_index += vertex_count * coordinate_step
|
||||||
|
continue
|
||||||
|
|
||||||
|
for vertex_idx in range(0, vertex_count):
|
||||||
|
vertex_global_idx = polygon_global_start_index + vertex_idx * coordinate_step
|
||||||
|
polygon_edges_x.append(polygon_vertex_array[vertex_global_idx + 0])
|
||||||
|
polygon_edges_y.append(polygon_vertex_array[vertex_global_idx + 1])
|
||||||
|
polygon_edges_z.append(polygon_vertex_array[vertex_global_idx + 2])
|
||||||
|
|
||||||
|
# Close the polygon
|
||||||
|
polygon_edges_x.append(polygon_vertex_array[polygon_global_start_index + 0])
|
||||||
|
polygon_edges_y.append(polygon_vertex_array[polygon_global_start_index + 1])
|
||||||
|
polygon_edges_z.append(polygon_vertex_array[polygon_global_start_index + 2])
|
||||||
|
|
||||||
|
polygon_edges_x.append(None)
|
||||||
|
polygon_edges_y.append(None)
|
||||||
|
polygon_edges_z.append(None)
|
||||||
|
|
||||||
|
polygon_global_start_index += vertex_count * coordinate_step
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Create mesh
|
||||||
|
mesh_3D = go.Mesh3d(x=x, y=y, z=z, i=i, j=j, k=k, opacity=0.8, color='rgba(244,22,100,0.6)')
|
||||||
|
|
||||||
|
# Create edge lines for triangles
|
||||||
|
triangle_edges_3d = go.Scatter3d(
|
||||||
|
x=triangle_edges_x,
|
||||||
|
y=triangle_edges_y,
|
||||||
|
z=triangle_edges_z,
|
||||||
|
mode='lines',
|
||||||
|
name='',
|
||||||
|
line=dict(color= 'rgb(0,0,0)', width=1)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create outer edge lines for polygon
|
||||||
|
polygon_edges_3d = go.Scatter3d(
|
||||||
|
x=polygon_edges_x,
|
||||||
|
y=polygon_edges_y,
|
||||||
|
z=polygon_edges_z,
|
||||||
|
mode='lines',
|
||||||
|
name='',
|
||||||
|
line=dict(color= 'rgb(0,0,0)', width=1)
|
||||||
|
)
|
||||||
|
|
||||||
|
fig = go.Figure(
|
||||||
|
data=[
|
||||||
|
mesh_3D,
|
||||||
|
# triangle_edges_3d,
|
||||||
|
polygon_edges_3d
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# print(f"j array: {j_array}")
|
||||||
|
# print(f"Number of vertices: {len(vertex_array) / 3}")
|
||||||
|
# print(f"Number of traingles: {num_triangles}")
|
||||||
|
# print(f"Source cell indices array length: {len(source_cell_indices_arr)}")
|
||||||
|
# print(
|
||||||
|
# f"Origin UTM coordinates [x, y, z]: [{origin_utm.x}, {origin_utm.y}, {origin_utm.z}]"
|
||||||
|
# )
|
||||||
|
# print(
|
||||||
|
# f"Grid dimensions [I, J, K]: [{grid_dimensions.dimensions.i}, {grid_dimensions.dimensions.j}, {grid_dimensions.dimensions.k}]"
|
||||||
|
# )
|
||||||
|
print(fig.data)
|
||||||
|
|
||||||
|
fig.show()
|
@ -24,8 +24,7 @@ cut_along_polyline_response: GridGeometryExtraction__pb2.CutAlongPolylineRespons
|
|||||||
grid_geometry_extraction_stub.CutAlongPolyline(cut_along_polyline_request)
|
grid_geometry_extraction_stub.CutAlongPolyline(cut_along_polyline_request)
|
||||||
)
|
)
|
||||||
|
|
||||||
cut_along_polyline_response.gridDimensions
|
vertex_array = cut_along_polyline_response.triangleVertexArray
|
||||||
vertex_array = cut_along_polyline_response.vertexArray
|
|
||||||
|
|
||||||
num_vertex_coords = 3 # [x, y, z]
|
num_vertex_coords = 3 # [x, y, z]
|
||||||
num_vertices_per_triangle = 3 # [v1, v2, v3]
|
num_vertices_per_triangle = 3 # [v1, v2, v3]
|
||||||
@ -50,10 +49,7 @@ for i in range(0, len(x_array), num_vertices_per_triangle):
|
|||||||
j_array.extend([i + 1])
|
j_array.extend([i + 1])
|
||||||
k_array.extend([i + 2])
|
k_array.extend([i + 2])
|
||||||
|
|
||||||
|
mesh_3d = go.Mesh3d(
|
||||||
fig = go.Figure(
|
|
||||||
data=[
|
|
||||||
go.Mesh3d(
|
|
||||||
x=x_array,
|
x=x_array,
|
||||||
y=y_array,
|
y=y_array,
|
||||||
z=z_array,
|
z=z_array,
|
||||||
@ -64,6 +60,30 @@ fig = go.Figure(
|
|||||||
showscale=True,
|
showscale=True,
|
||||||
colorscale=[[0, "gold"], [0.5, "mediumturquoise"], [1.0, "magenta"]],
|
colorscale=[[0, "gold"], [0.5, "mediumturquoise"], [1.0, "magenta"]],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Create edges between points in triangles
|
||||||
|
Xe = []
|
||||||
|
Ye = []
|
||||||
|
Ze = []
|
||||||
|
step_per_triangle = num_vertex_coords * num_vertices_per_triangle
|
||||||
|
for i in range(0, len(vertex_array), step_per_triangle):
|
||||||
|
Xe.extend([vertex_array[i + 0], vertex_array[i + 3], vertex_array[i + 6], None]) # x-coordinates of start and end points of the edge
|
||||||
|
Ye.extend([vertex_array[i + 1], vertex_array[i + 4], vertex_array[i + 7], None]) # y-coordinates of start and end points of the edge
|
||||||
|
Ze.extend([vertex_array[i + 2], vertex_array[i + 5], vertex_array[i + 8], None]) # z-coordinates of start and end points of the edge
|
||||||
|
|
||||||
|
edges_3d = go.Scatter3d(
|
||||||
|
x=Xe,
|
||||||
|
y=Ye,
|
||||||
|
z=Ze,
|
||||||
|
mode='lines',
|
||||||
|
name='',
|
||||||
|
line=dict(color= 'rgb(70,70,70)', width=1)
|
||||||
|
)
|
||||||
|
|
||||||
|
fig = go.Figure(
|
||||||
|
data=[
|
||||||
|
mesh_3d,
|
||||||
|
edges_3d
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
@ -25,7 +25,6 @@ get_grid_surface_response: GridGeometryExtraction__pb2.GetGridSurfaceResponse =
|
|||||||
grid_geometry_extraction_stub.GetGridSurface(get_grid_surface_request)
|
grid_geometry_extraction_stub.GetGridSurface(get_grid_surface_request)
|
||||||
)
|
)
|
||||||
|
|
||||||
get_grid_surface_response.gridDimensions
|
|
||||||
vertex_array = get_grid_surface_response.vertexArray
|
vertex_array = get_grid_surface_response.vertexArray
|
||||||
quad_indices_array = get_grid_surface_response.quadIndicesArr
|
quad_indices_array = get_grid_surface_response.quadIndicesArr
|
||||||
origin_utm = get_grid_surface_response.originUtm
|
origin_utm = get_grid_surface_response.originUtm
|
||||||
@ -78,7 +77,7 @@ print(
|
|||||||
f"Origin UTM coordinates [x, y, z]: [{origin_utm.x}, {origin_utm.y}, {origin_utm.z}]"
|
f"Origin UTM coordinates [x, y, z]: [{origin_utm.x}, {origin_utm.y}, {origin_utm.z}]"
|
||||||
)
|
)
|
||||||
print(
|
print(
|
||||||
f"Grid dimensions [I, J, K]: [{grid_dimensions.dimensions.i}, {grid_dimensions.dimensions.j}, {grid_dimensions.dimensions.k}]"
|
f"Grid dimensions [I, J, K]: [{grid_dimensions.i}, {grid_dimensions.j}, {grid_dimensions.k}]"
|
||||||
)
|
)
|
||||||
print(fig.data)
|
print(fig.data)
|
||||||
|
|
@ -137,16 +137,14 @@ grpc::Status RiaGrpcGridGeometryExtractionService::GetGridSurface( grpc::ServerC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set grid dimensions
|
// Set grid dimensions
|
||||||
const auto countI = m_eclipseView->mainGrid()->cellCountI();
|
const auto countI = m_eclipseView->mainGrid()->cellCountI();
|
||||||
const auto countJ = m_eclipseView->mainGrid()->cellCountJ();
|
const auto countJ = m_eclipseView->mainGrid()->cellCountJ();
|
||||||
const auto countK = m_eclipseView->mainGrid()->cellCountK();
|
const auto countK = m_eclipseView->mainGrid()->cellCountK();
|
||||||
rips::Vec3i* dimensions = new rips::Vec3i;
|
rips::Vec3i* dimensions = new rips::Vec3i;
|
||||||
rips::GridDimensions* gridDimensions = new rips::GridDimensions;
|
|
||||||
dimensions->set_i( countI );
|
dimensions->set_i( countI );
|
||||||
dimensions->set_j( countJ );
|
dimensions->set_j( countJ );
|
||||||
dimensions->set_k( countK );
|
dimensions->set_k( countK );
|
||||||
gridDimensions->set_allocated_dimensions( dimensions );
|
response->set_allocated_griddimensions( dimensions );
|
||||||
response->set_allocated_griddimensions( gridDimensions );
|
|
||||||
|
|
||||||
// Close project and return
|
// Close project and return
|
||||||
if ( m_application != nullptr )
|
if ( m_application != nullptr )
|
||||||
@ -217,25 +215,55 @@ grpc::Status RiaGrpcGridGeometryExtractionService::CutAlongPolyline( grpc::Serve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate intersection
|
||||||
polylineIntersectionGenerator->generateIntersectionGeometry( visibleCells );
|
polylineIntersectionGenerator->generateIntersectionGeometry( visibleCells );
|
||||||
if ( !polylineIntersectionGenerator->isAnyGeometryPresent() )
|
if ( !polylineIntersectionGenerator->isAnyGeometryPresent() )
|
||||||
{
|
{
|
||||||
return grpc::Status( grpc::StatusCode::INVALID_ARGUMENT, "No intersection geometry present" );
|
return grpc::Status( grpc::StatusCode::INVALID_ARGUMENT, "No intersection geometry present" );
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& triangleVertices = polylineIntersectionGenerator->triangleVxes();
|
// Get results
|
||||||
if ( triangleVertices->size() == 0 )
|
// const auto& triangleVertices = polylineIntersectionGenerator->triangleVxes();
|
||||||
|
// if ( triangleVertices->size() == 0 )
|
||||||
|
//{
|
||||||
|
// return grpc::Status( grpc::StatusCode::NOT_FOUND, "No triangle vertices found for polyline" );
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// Set vertex_array and quadindicesarr response
|
||||||
|
// for ( int i = 0; i < triangleVertices->size(); ++i )
|
||||||
|
//{
|
||||||
|
// const auto& vertex = triangleVertices->get( i );
|
||||||
|
// response->add_trianglevertexarray( vertex.x() );
|
||||||
|
// response->add_trianglevertexarray( vertex.y() );
|
||||||
|
// response->add_trianglevertexarray( vertex.z() );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Polygon vertices
|
||||||
|
const auto& polygonVertices = polylineIntersectionGenerator->polygonVxes();
|
||||||
|
if ( polygonVertices->size() == 0 )
|
||||||
{
|
{
|
||||||
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No triangle vertices found for polyline" );
|
return grpc::Status( grpc::StatusCode::NOT_FOUND, "No polygon vertices found for polyline" );
|
||||||
|
}
|
||||||
|
for ( int i = 0; i < polygonVertices->size(); ++i )
|
||||||
|
{
|
||||||
|
const auto& vertex = polygonVertices->get( i );
|
||||||
|
response->add_polygonvertexarray( vertex.x() );
|
||||||
|
response->add_polygonvertexarray( vertex.y() );
|
||||||
|
response->add_polygonvertexarray( vertex.z() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set vertex_array and quadindicesarr response
|
// Vertices per polygon
|
||||||
for ( int i = 0; i < triangleVertices->size(); ++i )
|
const auto& verticesPerPolygon = polylineIntersectionGenerator->vertiesPerPolygon();
|
||||||
|
for ( const auto& elm : verticesPerPolygon )
|
||||||
{
|
{
|
||||||
const auto& vertex = triangleVertices->get( i );
|
response->add_verticesperpolygonarr( static_cast<google::protobuf::uint32>( elm ) );
|
||||||
response->add_vertexarray( vertex.x() );
|
}
|
||||||
response->add_vertexarray( vertex.y() );
|
|
||||||
response->add_vertexarray( vertex.z() );
|
// Polygon to cell indices
|
||||||
|
const auto& polygonCellIndices = polylineIntersectionGenerator->polygonToCellIndex();
|
||||||
|
for ( const auto& elm : polygonCellIndices )
|
||||||
|
{
|
||||||
|
response->add_sourcecellindicesarr( static_cast<google::protobuf::uint32>( elm ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return grpc::Status::OK;
|
return grpc::Status::OK;
|
||||||
|
Loading…
Reference in New Issue
Block a user