mirror of
https://github.com/OPM/ResInsight.git
synced 2024-12-29 10:21:54 -06:00
Added MSVC ignores to .gitignore Start point of geometry fixes
This commit is contained in:
parent
741debebd2
commit
05200fe01f
32
.gitignore
vendored
32
.gitignore
vendored
@ -33,3 +33,35 @@ CTest*.cmake
|
|||||||
# Target program
|
# Target program
|
||||||
/ApplicationCode/ResInsight
|
/ApplicationCode/ResInsight
|
||||||
/.project
|
/.project
|
||||||
|
|
||||||
|
#Visual Studio files
|
||||||
|
*.[Oo]bj
|
||||||
|
*.user
|
||||||
|
*.aps
|
||||||
|
*.pch
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ncb
|
||||||
|
*.suo
|
||||||
|
*.tlb
|
||||||
|
*.tlh
|
||||||
|
*.bak
|
||||||
|
*.[Cc]ache
|
||||||
|
*.ilk
|
||||||
|
*.log
|
||||||
|
*.lib
|
||||||
|
*.sbr
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.unsuccessfulbuild
|
||||||
|
ipch/
|
||||||
|
[Oo]bj/
|
||||||
|
[Bb]in
|
||||||
|
[Dd]ebug*/
|
||||||
|
[Rr]elease*/
|
||||||
|
Ankh.NoLoad
|
||||||
|
|
||||||
|
#Temp files
|
||||||
|
*.temp
|
||||||
|
@ -19,6 +19,8 @@ include_directories(
|
|||||||
|
|
||||||
set( MODEL_VISUALIZATION_CPP_SOURCES
|
set( MODEL_VISUALIZATION_CPP_SOURCES
|
||||||
../RivPipeGeometryGenerator.cpp
|
../RivPipeGeometryGenerator.cpp
|
||||||
|
../cvfGeometryTools.cpp
|
||||||
|
../cvfBoundingBoxTree.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -29,6 +31,8 @@ set( CPP_SOURCES
|
|||||||
set( UNIT_TEST_CPP_SOURCES
|
set( UNIT_TEST_CPP_SOURCES
|
||||||
main.cpp
|
main.cpp
|
||||||
RivPipeGeometryGenerator-Test.cpp
|
RivPipeGeometryGenerator-Test.cpp
|
||||||
|
RivCellFaceIntersection-Test.cpp
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,505 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011-2012 Statoil ASA, Ceetron 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.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "cvfLibCore.h"
|
||||||
|
#include "cvfLibViewing.h"
|
||||||
|
#include "cvfLibRender.h"
|
||||||
|
#include "cvfLibGeometry.h"
|
||||||
|
#include "cafFixedArray.h"
|
||||||
|
|
||||||
|
#include "cvfArrayWrapperToEdit.h"
|
||||||
|
#include "cvfArrayWrapperConst.h"
|
||||||
|
|
||||||
|
#include "cvfGeometryTools.h"
|
||||||
|
#include "cvfBoundingBoxTree.h"
|
||||||
|
|
||||||
|
using namespace cvf;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void ControlVolume::calculateCubeFaceStatus(const cvf::Vec3dArray& nodeCoords, double areaTolerance)
|
||||||
|
{
|
||||||
|
int cubeFace;
|
||||||
|
cvf::uint cubeFaceIndices[4];
|
||||||
|
for (cubeFace = 0; cubeFace < 6; ++cubeFace)
|
||||||
|
{
|
||||||
|
surfaceNodeIndices(static_cast<Defines::CubeFace>(cubeFace), cubeFaceIndices);
|
||||||
|
|
||||||
|
std::vector<const brv::Connection*> conns;
|
||||||
|
connections(static_cast<Defines::CubeFace>(cubeFace), &conns);
|
||||||
|
|
||||||
|
if (!conns.size())
|
||||||
|
{
|
||||||
|
m_cubeFaceStatus[cubeFace] = FREE_FACE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double area = 0.5 * (nodeCoords[cubeFaceIndices[1]]-nodeCoords[cubeFaceIndices[0]] ^ nodeCoords[cubeFaceIndices[3]]-nodeCoords[cubeFaceIndices[0]]).length();
|
||||||
|
area += 0.5 * (nodeCoords[cubeFaceIndices[3]]-nodeCoords[cubeFaceIndices[2]] ^ nodeCoords[cubeFaceIndices[1]]-nodeCoords[cubeFaceIndices[2]]).length();
|
||||||
|
double totConnectionArea = 0;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < conns.size(); ++i)
|
||||||
|
{
|
||||||
|
totConnectionArea += conns[i]->brfArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( totConnectionArea < area - areaTolerance )
|
||||||
|
{
|
||||||
|
m_cubeFaceStatus[cubeFace] = PARTIALLY_COVERED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cubeFaceStatus[cubeFace] = COMPLETELY_COVERED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a polygon to store the complete polygon of the faces
|
||||||
|
// not completely covered by connections
|
||||||
|
// This polygon will be filled with nodes later
|
||||||
|
|
||||||
|
if (m_cubeFaceStatus[cubeFace] != COMPLETELY_COVERED )
|
||||||
|
{
|
||||||
|
m_freeFacePolygons[cubeFace] = new std::list<std::pair<cvf::uint, bool> >;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template <typename NodeArrayType, typename NodeType, typename IndexType>
|
||||||
|
NodeType quadNormal (const ArrayWrapperConst<NodeArrayType, NodeType>& nodeCoords,
|
||||||
|
const IndexType cubeFaceIndices[4] )
|
||||||
|
{
|
||||||
|
return ( nodeCoords[cubeFaceIndices[2]] - nodeCoords[cubeFaceIndices[0]]) ^
|
||||||
|
( nodeCoords[cubeFaceIndices[3]] - nodeCoords[cubeFaceIndices[1]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class QuadFaceIntersectorImplHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~QuadFaceIntersectorImplHandle() {}
|
||||||
|
virtual bool intersect() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename NodeArrayType, typename NodeType, typename IndicesArrayType, typename IndicesType>
|
||||||
|
class QuadFaceIntersectorImpl : public QuadFaceIntersectorImplHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QuadFaceIntersectorImpl( ArrayWrapperToEdit<NodeArrayType, NodeType> nodeArray, ArrayWrapperToEdit<IndicesArrayType, IndicesType> indices)
|
||||||
|
: m_nodeArray(nodeArray),
|
||||||
|
m_indices(indices){}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool intersect()
|
||||||
|
{
|
||||||
|
size_t nodeCount = m_nodeArray.size();
|
||||||
|
NodeType a = m_nodeArray[0];
|
||||||
|
IndicesType idx = m_indices[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ArrayWrapperToEdit<NodeArrayType, NodeType> m_nodeArray;
|
||||||
|
ArrayWrapperToEdit<IndicesArrayType, IndicesType> m_indices;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class QuadFaceIntersector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename NodeArrayType, typename NodeType, typename IndicesArrayType, typename IndicesType>
|
||||||
|
void setup( ArrayWrapperToEdit<NodeArrayType, NodeType> nodeArray, ArrayWrapperToEdit<IndicesArrayType, IndicesType> indices)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_implementation = new QuadFaceIntersectorImpl< NodeArrayType, NodeType, IndicesArrayType, IndicesType>( nodeArray, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool intersect() { return m_implementation->intersect(); }
|
||||||
|
private:
|
||||||
|
QuadFaceIntersectorImplHandle * m_implementation;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename ArrayType, typename ElmType>
|
||||||
|
void arrayWrapperConstTestFunction(const ArrayWrapperConst< ArrayType, ElmType> cinRefArray)
|
||||||
|
{
|
||||||
|
ElmType e;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
size = cinRefArray.size();
|
||||||
|
e = cinRefArray[size-1];
|
||||||
|
// cinRefArray[size-1] = e;
|
||||||
|
{
|
||||||
|
const ElmType& cre = cinRefArray[size-1];
|
||||||
|
//ElmType& re = cinRefArray[size-1];
|
||||||
|
//re = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ArrayType, typename ElmType>
|
||||||
|
void arrayWrapperConstRefTestFunction(const ArrayWrapperConst< ArrayType, ElmType>& cinRefArray)
|
||||||
|
{
|
||||||
|
ElmType e;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
size = cinRefArray.size();
|
||||||
|
e = cinRefArray[size-1];
|
||||||
|
// cinRefArray[size-1] = e;
|
||||||
|
{
|
||||||
|
const ElmType& cre = cinRefArray[size-1];
|
||||||
|
//ElmType& re = cinRefArray[size-1];
|
||||||
|
//re = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename ArrayType, typename ElmType>
|
||||||
|
void arrayWrapperTestFunction(ArrayWrapperToEdit< ArrayType, ElmType> cinRefArray)
|
||||||
|
{
|
||||||
|
ElmType e, e2;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
size = cinRefArray.size();
|
||||||
|
e = cinRefArray[size-1];
|
||||||
|
e2 = cinRefArray[0];
|
||||||
|
cinRefArray[0] = e;
|
||||||
|
{
|
||||||
|
const ElmType& cre = cinRefArray[size-1];
|
||||||
|
ElmType& re = cinRefArray[size-1];
|
||||||
|
re = e2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ArrayType, typename ElmType>
|
||||||
|
void arrayWrapperRefTestFunction(ArrayWrapperToEdit< ArrayType, ElmType>& cinRefArray)
|
||||||
|
{
|
||||||
|
ElmType e, e2;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
size = cinRefArray.size();
|
||||||
|
e = cinRefArray[size-1];
|
||||||
|
e2 = cinRefArray[0];
|
||||||
|
cinRefArray[0] = e;
|
||||||
|
{
|
||||||
|
const ElmType& cre = cinRefArray[size-1];
|
||||||
|
ElmType& re = cinRefArray[size-1];
|
||||||
|
re = e2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<< (std::ostream& stream, cvf::Vec3d v)
|
||||||
|
{
|
||||||
|
stream << v[0] << " " << v[1] << " " << v[2] ;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(ArrayWrapperTest, AllSpecializations)
|
||||||
|
{
|
||||||
|
std::vector<cvf::Vec3d> vec3dStdVector;
|
||||||
|
vec3dStdVector.push_back(Vec3d::ZERO);
|
||||||
|
vec3dStdVector.push_back(Vec3d(1,1,1));
|
||||||
|
|
||||||
|
const std::vector<cvf::Vec3d> &cvec3dStdVector = vec3dStdVector;
|
||||||
|
|
||||||
|
cvf::Vec3dArray vec3dCvfArray(vec3dStdVector);
|
||||||
|
const cvf::Vec3dArray& cvec3dCvfArray = vec3dCvfArray;
|
||||||
|
|
||||||
|
cvf::Array<size_t> siztCvfArray(2);
|
||||||
|
siztCvfArray[0] = 0;
|
||||||
|
siztCvfArray[1] = 1;
|
||||||
|
const cvf::Array<size_t>& csiztCvfArray = siztCvfArray;
|
||||||
|
|
||||||
|
cvf::Array<uint> uintCvfArray(2);
|
||||||
|
uintCvfArray[0] = 0;
|
||||||
|
uintCvfArray[1] = 1;
|
||||||
|
const cvf::Array<uint>& cuintCvfArray = uintCvfArray;
|
||||||
|
|
||||||
|
size_t siztBarePtrArray[2] = {0, 1};
|
||||||
|
|
||||||
|
size_t* siztBarePtr = new size_t[2];
|
||||||
|
siztBarePtr[0] = 0;
|
||||||
|
siztBarePtr[1] = 1;
|
||||||
|
|
||||||
|
const size_t* csiztBarePtr = siztBarePtr;
|
||||||
|
|
||||||
|
cvf::uint* uintBarePtr = new cvf::uint[2];
|
||||||
|
uintBarePtr[0] = 0;
|
||||||
|
uintBarePtr[1] = 1;
|
||||||
|
const cvf::uint* cuintBarePtr = uintBarePtr;
|
||||||
|
|
||||||
|
double* doubleBarePtr = new double[2];
|
||||||
|
doubleBarePtr[0] = 0;
|
||||||
|
doubleBarePtr[1] = 1;
|
||||||
|
const double* cdoubleBarePtr = doubleBarePtr;
|
||||||
|
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(&vec3dStdVector));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(&cvec3dStdVector));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(&vec3dCvfArray));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(&cvec3dCvfArray));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(&uintCvfArray));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(&cuintCvfArray));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(siztBarePtrArray, 2));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(siztBarePtr, 2));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(csiztBarePtr, 2));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(doubleBarePtr,2));
|
||||||
|
arrayWrapperConstTestFunction(wrapArrayConst(cdoubleBarePtr, 2));
|
||||||
|
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(&vec3dStdVector));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(&cvec3dStdVector));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(&vec3dCvfArray));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(&cvec3dCvfArray));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(&uintCvfArray));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(&cuintCvfArray));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(siztBarePtrArray, 2));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(siztBarePtr, 2));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(csiztBarePtr, 2));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(doubleBarePtr,2));
|
||||||
|
arrayWrapperConstRefTestFunction(wrapArrayConst(cdoubleBarePtr, 2));
|
||||||
|
|
||||||
|
arrayWrapperTestFunction(wrapArrayToEdit(&vec3dStdVector));
|
||||||
|
//arrayWrapperTestFunction3(wrapArray(&cvec3dStdVector));
|
||||||
|
EXPECT_EQ(Vec3d::ZERO, vec3dStdVector[1]);
|
||||||
|
EXPECT_EQ(Vec3d(1,1,1), vec3dStdVector[0]);
|
||||||
|
|
||||||
|
arrayWrapperTestFunction(wrapArrayToEdit(&vec3dCvfArray));
|
||||||
|
EXPECT_EQ(Vec3d::ZERO, vec3dCvfArray[1]);
|
||||||
|
EXPECT_EQ(Vec3d(1,1,1), vec3dStdVector[0]);
|
||||||
|
//arrayWrapperTestFunction3(wrapArray(&cvec3dCvfArray));
|
||||||
|
arrayWrapperTestFunction(wrapArrayToEdit(&uintCvfArray));
|
||||||
|
//arrayWrapperTestFunction3(wrapArray(&cuintCvfArray));
|
||||||
|
arrayWrapperTestFunction(wrapArrayToEdit(siztBarePtrArray, 2));
|
||||||
|
//arrayWrapperTestFunction3(wrapArray(csiztBarePtr, 2));
|
||||||
|
arrayWrapperTestFunction(wrapArrayToEdit(doubleBarePtr,2));
|
||||||
|
//arrayWrapperTestFunction3(wrapArray(cdoubleBarePtr, 2));
|
||||||
|
EXPECT_EQ(0.0, doubleBarePtr[1]);
|
||||||
|
EXPECT_EQ(1.0, doubleBarePtr[0]);
|
||||||
|
|
||||||
|
arrayWrapperRefTestFunction(wrapArrayToEdit(&vec3dStdVector));
|
||||||
|
EXPECT_EQ(Vec3d::ZERO, vec3dStdVector[0]);
|
||||||
|
EXPECT_EQ(Vec3d(1,1,1), vec3dStdVector[1]);
|
||||||
|
//arrayWrapperRefTestFunction3(wrapArray(&cvec3dStdVector));
|
||||||
|
arrayWrapperRefTestFunction(wrapArrayToEdit(&vec3dCvfArray));
|
||||||
|
EXPECT_EQ(Vec3d::ZERO, vec3dCvfArray[0]);
|
||||||
|
EXPECT_EQ(Vec3d(1,1,1), vec3dStdVector[1]);
|
||||||
|
//arrayWrapperRefTestFunction3(wrapArray(&cvec3dCvfArray));
|
||||||
|
arrayWrapperRefTestFunction(wrapArrayToEdit(&uintCvfArray));
|
||||||
|
//arrayWrapperRefTestFunction3(wrapArray(&cuintCvfArray));
|
||||||
|
arrayWrapperRefTestFunction(wrapArrayToEdit(siztBarePtrArray, 2));
|
||||||
|
//arrayWrapperRefTestFunction3(wrapArray(csiztBarePtr, 2));
|
||||||
|
arrayWrapperRefTestFunction(wrapArrayToEdit(doubleBarePtr,2));
|
||||||
|
//arrayWrapperRefTestFunction3(wrapArray(cdoubleBarePtr, 2));
|
||||||
|
|
||||||
|
EXPECT_EQ(0.0, doubleBarePtr[0]);
|
||||||
|
EXPECT_EQ(1.0, doubleBarePtr[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& stream, const std::vector<size_t>& array)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < array.size(); ++i)
|
||||||
|
{
|
||||||
|
stream << array[i] << " ";
|
||||||
|
}
|
||||||
|
stream << std::endl;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(BoundingBoxTree, Intersection)
|
||||||
|
{
|
||||||
|
cvf::BoundingBoxTree bbtree;
|
||||||
|
|
||||||
|
std::vector<cvf::BoundingBox> bbs;
|
||||||
|
bbs.push_back(cvf::BoundingBox(Vec3d(0,0,0), Vec3d(1,1,1)));
|
||||||
|
bbs.push_back(cvf::BoundingBox(Vec3d(1,0,0), Vec3d(2,1,1)));
|
||||||
|
bbs.push_back(cvf::BoundingBox(Vec3d(2,0,0), Vec3d(3,1,1)));
|
||||||
|
bbs.push_back(cvf::BoundingBox(Vec3d(3,0,0), Vec3d(4,1,1)));
|
||||||
|
bbs.push_back(cvf::BoundingBox(Vec3d(4,0,0), Vec3d(5,1,1)));
|
||||||
|
bbs.push_back(cvf::BoundingBox(Vec3d(0.5,0.5,0), Vec3d(5.5,1.5,1)));
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<size_t> ids;
|
||||||
|
ids.push_back(10);
|
||||||
|
ids.push_back(11);
|
||||||
|
ids.push_back(12);
|
||||||
|
ids.push_back(13);
|
||||||
|
ids.push_back(14);
|
||||||
|
ids.push_back(15);
|
||||||
|
|
||||||
|
bbtree.buildTreeFromBoundingBoxes(bbs, &ids);
|
||||||
|
{
|
||||||
|
std::vector<size_t> intIds;
|
||||||
|
bbtree.findIntersections(cvf::BoundingBox(Vec3d(0.25,0.25,0.25), Vec3d(4.5,0.4,0.4)), &intIds);
|
||||||
|
size_t numBB = intIds.size();
|
||||||
|
EXPECT_EQ(5, numBB);
|
||||||
|
EXPECT_EQ(intIds[4], 13);
|
||||||
|
//std::cout << intIds;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::vector<size_t> intIds;
|
||||||
|
bbtree.findIntersections(cvf::BoundingBox(Vec3d(0.25,0.75,0.25), Vec3d(4.5,0.8,0.4)), &intIds);
|
||||||
|
size_t numBB = intIds.size();
|
||||||
|
EXPECT_EQ(6, numBB);
|
||||||
|
EXPECT_EQ(intIds[5], 15);
|
||||||
|
//std::cout << intIds;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::vector<size_t> intIds;
|
||||||
|
bbtree.findIntersections(cvf::BoundingBox(Vec3d(2,0,0), Vec3d(3,1,1)), &intIds);
|
||||||
|
size_t numBB = intIds.size();
|
||||||
|
EXPECT_EQ(4, numBB);
|
||||||
|
EXPECT_EQ(intIds[0], 11);
|
||||||
|
//std::cout << intIds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(CellFaceIntersectionTst, Intersection)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<cvf::Vec3d> additionalVertices;
|
||||||
|
cvf::Vec3dArray nodes;
|
||||||
|
std::vector<size_t> polygon;
|
||||||
|
|
||||||
|
|
||||||
|
cvf::Array<size_t> ids;
|
||||||
|
size_t cv1CubeFaceIndices[4] = {0, 1, 2, 3};
|
||||||
|
size_t cv2CubeFaceIndices[4] = {4, 5, 6, 7};
|
||||||
|
|
||||||
|
nodes.resize(8);
|
||||||
|
nodes.setAll(cvf::Vec3d(0, 0, 0));
|
||||||
|
EdgeIntersectStorage edgeIntersectionStorage;
|
||||||
|
edgeIntersectionStorage.setVertexCount(nodes.size());
|
||||||
|
|
||||||
|
// Face 1
|
||||||
|
nodes[0] = cvf::Vec3d(0, 0, 0);
|
||||||
|
nodes[1] = cvf::Vec3d(1, 0, 0);
|
||||||
|
nodes[2] = cvf::Vec3d(1, 1, 0);
|
||||||
|
nodes[3] = cvf::Vec3d(0, 1, 0);
|
||||||
|
// Face 2
|
||||||
|
nodes[4] = cvf::Vec3d(0, 0, 0);
|
||||||
|
nodes[5] = cvf::Vec3d(1, 0, 0);
|
||||||
|
nodes[6] = cvf::Vec3d(1, 1, 0);
|
||||||
|
nodes[7] = cvf::Vec3d(0, 1, 0);
|
||||||
|
|
||||||
|
|
||||||
|
bool isOk = GeometryTools::calculateOverlapPolygonOfTwoQuads(&polygon, &additionalVertices, edgeIntersectionStorage, nodes, cv1CubeFaceIndices, cv2CubeFaceIndices, 1e-6);
|
||||||
|
EXPECT_EQ( 4, polygon.size());
|
||||||
|
EXPECT_EQ( (size_t)0, additionalVertices.size());
|
||||||
|
EXPECT_TRUE(isOk);
|
||||||
|
|
||||||
|
// Face 1
|
||||||
|
nodes[0] = cvf::Vec3d(0, 0, 0);
|
||||||
|
nodes[1] = cvf::Vec3d(1, 0, 0);
|
||||||
|
nodes[2] = cvf::Vec3d(1, 1, 0);
|
||||||
|
nodes[3] = cvf::Vec3d(0, 1, 0);
|
||||||
|
// Face 2
|
||||||
|
nodes[4] = cvf::Vec3d(0.5, -0.25, 0);
|
||||||
|
nodes[5] = cvf::Vec3d(1.25, 0.5, 0);
|
||||||
|
nodes[6] = cvf::Vec3d(0.5, 1.25, 0);
|
||||||
|
nodes[7] = cvf::Vec3d(-0.25, 0.5, 0);
|
||||||
|
polygon.clear();
|
||||||
|
|
||||||
|
isOk = GeometryTools::calculateOverlapPolygonOfTwoQuads(&polygon, &additionalVertices, edgeIntersectionStorage, nodes, cv1CubeFaceIndices, cv2CubeFaceIndices, 1e-6);
|
||||||
|
EXPECT_EQ( 8, polygon.size());
|
||||||
|
EXPECT_EQ( (size_t)8, additionalVertices.size());
|
||||||
|
EXPECT_TRUE(isOk);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(CellFaceIntersectionTst, FreeFacePolygon)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<cvf::Vec3d> additionalVertices;
|
||||||
|
cvf::Vec3dArray nodes;
|
||||||
|
std::vector<size_t> polygon;
|
||||||
|
|
||||||
|
|
||||||
|
cvf::Array<size_t> ids;
|
||||||
|
size_t cv1CubeFaceIndices[4] = {0, 1, 2, 3};
|
||||||
|
size_t cv2CubeFaceIndices[4] = {4, 5, 6, 7};
|
||||||
|
|
||||||
|
nodes.resize(8);
|
||||||
|
nodes.setAll(cvf::Vec3d(0, 0, 0));
|
||||||
|
EdgeIntersectStorage edgeIntersectionStorage;
|
||||||
|
edgeIntersectionStorage.setVertexCount(nodes.size());
|
||||||
|
|
||||||
|
// Face 1
|
||||||
|
nodes[0] = cvf::Vec3d(0, 0, 0);
|
||||||
|
nodes[1] = cvf::Vec3d(1, 0, 0);
|
||||||
|
nodes[2] = cvf::Vec3d(1, 1, 0);
|
||||||
|
nodes[3] = cvf::Vec3d(0, 1, 0);
|
||||||
|
// Face 2
|
||||||
|
nodes[4] = cvf::Vec3d(0, 0, 0);
|
||||||
|
nodes[5] = cvf::Vec3d(1, 0, 0);
|
||||||
|
nodes[6] = cvf::Vec3d(1, 1, 0);
|
||||||
|
nodes[7] = cvf::Vec3d(0, 1, 0);
|
||||||
|
|
||||||
|
|
||||||
|
bool isOk = GeometryTools::calculateOverlapPolygonOfTwoQuads(&polygon, &additionalVertices, edgeIntersectionStorage, nodes, cv1CubeFaceIndices, cv2CubeFaceIndices, 1e-6);
|
||||||
|
EXPECT_EQ( 4, polygon.size());
|
||||||
|
EXPECT_EQ( (size_t)0, additionalVertices.size());
|
||||||
|
EXPECT_TRUE(isOk);
|
||||||
|
|
||||||
|
|
||||||
|
//GeometryTools::calculatePartiallyFreeCubeFacePolygon(nodes, );
|
||||||
|
|
||||||
|
// Face 1
|
||||||
|
nodes[0] = cvf::Vec3d(0, 0, 0);
|
||||||
|
nodes[1] = cvf::Vec3d(1, 0, 0);
|
||||||
|
nodes[2] = cvf::Vec3d(1, 1, 0);
|
||||||
|
nodes[3] = cvf::Vec3d(0, 1, 0);
|
||||||
|
// Face 2
|
||||||
|
nodes[4] = cvf::Vec3d(0.5, -0.25, 0);
|
||||||
|
nodes[5] = cvf::Vec3d(1.25, 0.5, 0);
|
||||||
|
nodes[6] = cvf::Vec3d(0.5, 1.25, 0);
|
||||||
|
nodes[7] = cvf::Vec3d(-0.25, 0.5, 0);
|
||||||
|
polygon.clear();
|
||||||
|
|
||||||
|
isOk = GeometryTools::calculateOverlapPolygonOfTwoQuads(&polygon, &additionalVertices, edgeIntersectionStorage, nodes, cv1CubeFaceIndices, cv2CubeFaceIndices, 1e-6);
|
||||||
|
EXPECT_EQ( 8, polygon.size());
|
||||||
|
EXPECT_EQ( (size_t)8, additionalVertices.size());
|
||||||
|
EXPECT_TRUE(isOk);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
1814
ApplicationCode/ModelVisualization/cvfGeometryTools.cpp
Normal file
1814
ApplicationCode/ModelVisualization/cvfGeometryTools.cpp
Normal file
File diff suppressed because it is too large
Load Diff
152
ApplicationCode/ModelVisualization/cvfGeometryTools.h
Normal file
152
ApplicationCode/ModelVisualization/cvfGeometryTools.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "cvfBase.h"
|
||||||
|
#include "cvfArray.h"
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <hash_map>
|
||||||
|
|
||||||
|
namespace cvf
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class EdgeSplitStorage;
|
||||||
|
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 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 );
|
||||||
|
static cvf::Vec3d barycentricCoords(const cvf::Vec3d& t0, const cvf::Vec3d& t1, const cvf::Vec3d& t2, const cvf::Vec3d& p);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
enum IntersectionStatus
|
||||||
|
{
|
||||||
|
NO_INTERSECTION,
|
||||||
|
LINES_INTERSECT_OUTSIDE,
|
||||||
|
LINES_TOUCH,
|
||||||
|
LINES_CROSSES,
|
||||||
|
LINES_OVERLAP
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
static bool isPointTouchingIndexedPolygon(const cvf::Vec3d& polygonNormal, const cvf::Vec3d* vertices, const size_t* indices, size_t numIndices,
|
||||||
|
const cvf::Vec3d& point, int* touchedEdgeIndex, double tolerance = 1e-6);
|
||||||
|
|
||||||
|
|
||||||
|
static bool insertVertexInPolygon(std::list<std::pair<cvf::uint, bool> >* polygon, const cvf::Vec3dArray& nodeCoords, cvf::uint vertexIndex, double tolerance);
|
||||||
|
static void addMidEdgeNodes(std::list<std::pair<cvf::uint, bool> >* polygon, const cvf::Vec3dArray& nodes, EdgeSplitStorage& edgeSplitStorage, std::vector<cvf::Vec3d>* createdVertexes);
|
||||||
|
|
||||||
|
static bool calculateOverlapPolygonOfTwoQuads( std::vector<size_t> * polygon, std::vector<cvf::Vec3d>* createdVertexes,
|
||||||
|
EdgeIntersectStorage& edgeIntersectionStorage,
|
||||||
|
const cvf::Vec3dArray& nodes,
|
||||||
|
const size_t cv1CubeFaceIndices[4],
|
||||||
|
const size_t cv2CubeFaceIndices[4],
|
||||||
|
double tolerance);
|
||||||
|
|
||||||
|
static void calculatePartiallyFreeCubeFacePolygon(const cvf::Vec3dArray& nodeCoords,
|
||||||
|
const std::vector<size_t>* completeFacePolygon,
|
||||||
|
const cvf::Vec3d& faceNormal,
|
||||||
|
const std::vector< std::vector<size_t>* >& faceOverlapPolygons,
|
||||||
|
const std::vector<bool> faceOverlapPolygonWindingSameAsCubeFaceFlags,
|
||||||
|
std::vector<size_t>* partialFacePolygon,
|
||||||
|
bool* m_partiallyFreeCubeFaceHasHoles);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class EdgeIntersectStorage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setVertexCount(size_t size);
|
||||||
|
bool findIntersection( size_t e1P1, size_t e1P2, size_t e2P1, size_t e2P2,
|
||||||
|
size_t* vxIndexIntersectionPoint, GeometryTools::IntersectionStatus* intersectionStatus,
|
||||||
|
double* fractionAlongEdge1, double* fractionAlongEdge2);
|
||||||
|
void addIntersection( size_t e1P1, size_t e1P2, size_t e2P1, size_t e2P2,
|
||||||
|
size_t vxIndexIntersectionPoint, GeometryTools::IntersectionStatus intersectionStatus,
|
||||||
|
double fractionAlongEdge1, double fractionAlongEdge2);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct IntersectData
|
||||||
|
{
|
||||||
|
size_t intersectionPointIndex;
|
||||||
|
GeometryTools::IntersectionStatus intersectionStatus;
|
||||||
|
double fractionAlongEdge1;
|
||||||
|
double fractionAlongEdge2;
|
||||||
|
};
|
||||||
|
|
||||||
|
void canonizeAddress(size_t& e1P1, size_t& e1P2, size_t& e2P1, size_t& 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<size_t, std::map<size_t, std::map<size_t, 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<cvf::uint>* triangles);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isTriangleValid( 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 calculatePolygonArea() 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();
|
||||||
|
void setCenterNode(size_t centerNodeIndex );
|
||||||
|
|
||||||
|
virtual bool calculateTriangles(std::vector<cvf::uint>* triangles);
|
||||||
|
private:
|
||||||
|
bool isTriangleValid( size_t u, size_t v, size_t w);
|
||||||
|
size_t m_centerNodeIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user