#2436 Add cube face tracking through the clipping methods used for intersection calculations

This commit is contained in:
Jacob Støren
2018-03-23 10:17:06 +01:00
parent 1a6c529488
commit 3b724e07bd
4 changed files with 184 additions and 104 deletions

View File

@@ -204,16 +204,19 @@ bool HexGridIntersectionTools::planeTriangleIntersection(const cvf::Plane& plane
//
// Clips the supplied triangles into new triangles returned in clippedTriangleVxes.
// New vertices have set isVxIdsNative = false and their vxIds is indices into triangleVxes
// The isTriangleEdgeCellContour bits refer to the edge after the corresponding triangle vertex.
// The cellFaceForEachTriangleEdge refer to the edge after the corresponding triangle vertex.
// This method will keep the faces provided, while added edges is marked with no face = 6
//--------------------------------------------------------------------------------------------------
void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::vector<ClipVx>& triangleVxes,
const std::vector<bool>& isTriangleEdgeCellContour,
const std::vector<int>& cellFaceForEachTriangleEdge,
const cvf::Plane& p1Plane,
const cvf::Plane& p2Plane,
std::vector<ClipVx>* clippedTriangleVxes,
std::vector<bool>* isClippedTriEdgeCellContour)
std::vector<int>* cellFaceForEachClippedTriangleEdge)
{
#define HT_NO_FACE 6
size_t triangleCount = triangleVxes.size() / 3;
for (size_t tIdx = 0; tIdx < triangleCount; ++tIdx)
@@ -272,9 +275,9 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(triangleVxes[triVxIdx + 1]);
clippedTriangleVxes->push_back(triangleVxes[triVxIdx + 2]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[triVxIdx + 0]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[triVxIdx + 1]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[triVxIdx + 2]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[triVxIdx + 0]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[triVxIdx + 1]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[triVxIdx + 2]);
continue;
}
@@ -290,13 +293,13 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(triangleVxes[newVx2OnP1.clippedEdgeVx2Id]);
clippedTriangleVxes->push_back(newVx2OnP1);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP1.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP1.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP1.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx2OnP1.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP1.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx2OnP1.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
continue;
}
@@ -312,13 +315,13 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(triangleVxes[newVx1OnP2.clippedEdgeVx2Id]);
clippedTriangleVxes->push_back(triangleVxes[newVx2OnP2.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx2OnP2.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx2OnP2.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP2.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP2.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP2.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP2.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
continue;
}
@@ -330,9 +333,9 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(newVx2OnP1);
clippedTriangleVxes->push_back(triangleVxes[newVx1OnP1.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx2OnP1.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP1.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx2OnP1.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP1.clippedEdgeVx1Id]);
continue;
}
@@ -344,9 +347,9 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(newVx2OnP2);
clippedTriangleVxes->push_back(triangleVxes[newVx1OnP2.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx2OnP2.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP2.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx2OnP2.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP2.clippedEdgeVx1Id]);
continue;
}
@@ -370,17 +373,17 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(newVx1OnP2);
clippedTriangleVxes->push_back(triangleVxes[newVx2OnP1.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP1.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP1.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP2.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx2OnP1.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP2.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx2OnP1.clippedEdgeVx2Id]);
}
else
{
@@ -389,17 +392,17 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(newVx1OnP1);
clippedTriangleVxes->push_back(triangleVxes[newVx2OnP2.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP2.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP2.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP1.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx2OnP2.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP1.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx2OnP2.clippedEdgeVx2Id]);
}
continue;
@@ -416,13 +419,13 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(newVx2OnP2);
clippedTriangleVxes->push_back(newVx2OnP1);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP1.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP1.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx2OnP2.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx2OnP2.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
continue;
}
@@ -438,13 +441,13 @@ void HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes(const std::
clippedTriangleVxes->push_back(newVx1OnP2);
clippedTriangleVxes->push_back(newVx1OnP1);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx2OnP1.clippedEdgeVx2Id]);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx2OnP1.clippedEdgeVx2Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
isClippedTriEdgeCellContour->push_back(false);
isClippedTriEdgeCellContour->push_back(isTriangleEdgeCellContour[newVx1OnP2.clippedEdgeVx1Id]);
isClippedTriEdgeCellContour->push_back(false);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
cellFaceForEachClippedTriangleEdge->push_back(cellFaceForEachTriangleEdge[newVx1OnP2.clippedEdgeVx1Id]);
cellFaceForEachClippedTriangleEdge->push_back(HT_NO_FACE);
continue;
}
@@ -502,17 +505,33 @@ cvf::Vec3d HexGridIntersectionTools::planeLineIntersectionForMC(const cvf::Plane
}
//--------------------------------------------------------------------------------------------------
/// Based on description and implementation from Paul Bourke:
///
/// http://paulbourke.net/geometry/polygonise/
///
/// Note that the element is turned inside-out compared to what we use elsewhere in caf/ResInsight
/// So the winding of all the sides are opposite.
/// 4-----4------5
/// /| /| k POS_I = 0
/// 7 8 5 9 | NEG_I = 1
/// / | / | | POS_J = 2
/// 7------6-----6 | | NEG_J = 3
/// | 0-----0--|---1 *------i POS_K = 4
/// 11 / 10 / / NEG_K = 5
/// | 3 | 1 / NO_FACE = 6
/// |/ |/ j
/// 3------2-----2
///
// The cellFaceForEachTriangleEdge refer to the edge after the corresponding triangle vertex.
//--------------------------------------------------------------------------------------------------
int HexGridIntersectionTools::planeHexIntersectionMC(const cvf::Plane& plane,
const cvf::Vec3d cell[8],
const size_t hexCornersIds[8],
std::vector<ClipVx>* triangleVxes,
std::vector<bool>* isTriEdgeCellContour)
const cvf::Vec3d cell[8],
const size_t hexCornersIds[8],
std::vector<ClipVx>* triangleVxes,
std::vector<int>* cellFaceForEachTriangleEdge)
{
// Based on description and implementation from Paul Bourke:
// http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
static const cvf::uint cubeIdxToCutEdgeBitfield[256] =
{
@@ -864,24 +883,67 @@ int HexGridIntersectionTools::planeHexIntersectionMC(const cvf::Plane& plane,
const int* triangleIndicesToCubeEdges = cubeIdxToTriangleIndices[cubeIndex];
cvf::uint triangleVxIdx = 0;
int cubeEdgeIdx = triangleIndicesToCubeEdges[triangleVxIdx];
while (cubeEdgeIdx != -1)
{
ClipVx cvx;
cvx.vx = edgeIntersections[cubeEdgeIdx];
cvx.vx = edgeIntersections[cubeEdgeIdx];
cvx.normDistFromEdgeVx1 = normDistAlongEdge[cubeEdgeIdx];
cvx.clippedEdgeVx1Id = hexCornersIds[edgeTable[cubeEdgeIdx][0]];
cvx.clippedEdgeVx2Id = hexCornersIds[edgeTable[cubeEdgeIdx][1]];
cvx.clippedEdgeVx1Id = hexCornersIds[edgeTable[cubeEdgeIdx][0]];
cvx.clippedEdgeVx2Id = hexCornersIds[edgeTable[cubeEdgeIdx][1]];
(*triangleVxes).push_back(cvx);
++triangleVxIdx;
cubeEdgeIdx = triangleIndicesToCubeEdges[triangleVxIdx];
}
cvf::uint triangleCount = triangleVxIdx / 3;
static const int edgeEdgeCutsToCellFace[12][12] = {
// 0 1 2 3 4 5 6 7 8 9 10 11
{ 6, 5, 5, 5, 3, 6, 6, 6, 3, 3, 6, 6 }, // 0
{ 5, 6, 5, 5, 6, 0, 6, 6, 6, 0, 0, 6 }, // 1 POS_I = 0
{ 5, 5, 6, 5, 6, 6, 2, 6, 6, 6, 2, 2 }, // 2 NEG_I = 1
{ 5, 5, 5, 6, 6, 6, 6, 1, 1, 6, 6, 1 }, // 3 POS_J = 2
{ 3, 6, 6, 6, 6, 4, 4, 4, 3, 3, 6, 6 }, // 4 NEG_J = 3
{ 6, 0, 6, 6, 4, 6, 4, 4, 6, 0, 0, 6 }, // 5 POS_K = 4
{ 6, 6, 2, 6, 4, 4, 6, 4, 6, 6, 2, 2 }, // 6 NEG_K = 5
{ 6, 6, 6, 1, 4, 4, 4, 6, 1, 6, 6, 1 }, // 7 NO_FACE = 6
{ 3, 6, 6, 1, 3, 6, 6, 1, 6, 3, 6, 1 }, // 8
{ 3, 0, 6, 6, 3, 0, 6, 6, 3, 6, 0, 6 }, // 9
{ 6, 0, 2, 6, 6, 0, 2, 6, 6, 0, 6, 2 }, // 10
{ 6, 6, 2, 1, 6, 6, 2, 1, 1, 6, 2, 6 } // 11
};
(*cellFaceForEachTriangleEdge).clear();
(*cellFaceForEachTriangleEdge).resize(triangleVxIdx, 6);
for (cvf::uint tIdx = 0; tIdx < triangleCount; ++tIdx)
{
cvf::uint triVxIdx = 3 * tIdx;
int cubeEdgeIdx1 = triangleIndicesToCubeEdges[triVxIdx];
int cubeEdgeIdx2 = triangleIndicesToCubeEdges[triVxIdx + 1];
int cubeEdgeIdx3 = triangleIndicesToCubeEdges[triVxIdx + 2];
(*cellFaceForEachTriangleEdge)[triVxIdx + 0] = edgeEdgeCutsToCellFace[cubeEdgeIdx1][cubeEdgeIdx2];
(*cellFaceForEachTriangleEdge)[triVxIdx + 1] = edgeEdgeCutsToCellFace[cubeEdgeIdx2][cubeEdgeIdx3];
(*cellFaceForEachTriangleEdge)[triVxIdx + 2] = edgeEdgeCutsToCellFace[cubeEdgeIdx3][cubeEdgeIdx1];
}
#if 0
// Calculate what triangle edges are representing the cut of a cell face
// Do this by counting the times two specific cube edges are used for a triangle edge.
// Internal edges will have a count of 2, while external edges only 1
(*isTriEdgeCellContour).clear();
(*isTriEdgeCellContour).resize(triangleVxIdx);
int triangleEdgeCount[12][12] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@@ -920,11 +982,14 @@ int HexGridIntersectionTools::planeHexIntersectionMC(const cvf::Plane& plane,
int cubeEdgeIdx2 = triangleIndicesToCubeEdges[triVxIdx + 1];
int cubeEdgeIdx3 = triangleIndicesToCubeEdges[triVxIdx + 2];
// We have a contour if the count is exactly 1.
(*isTriEdgeCellContour)[triVxIdx + 0] = (1 == (cubeEdgeIdx1 < cubeEdgeIdx2 ? triangleEdgeCount[cubeEdgeIdx1][cubeEdgeIdx2] : triangleEdgeCount[cubeEdgeIdx2][cubeEdgeIdx1]));
(*isTriEdgeCellContour)[triVxIdx + 1] = (1 == (cubeEdgeIdx2 < cubeEdgeIdx3 ? triangleEdgeCount[cubeEdgeIdx2][cubeEdgeIdx3] : triangleEdgeCount[cubeEdgeIdx3][cubeEdgeIdx2]));
(*isTriEdgeCellContour)[triVxIdx + 2] = (1 == (cubeEdgeIdx3 < cubeEdgeIdx1 ? triangleEdgeCount[cubeEdgeIdx3][cubeEdgeIdx1] : triangleEdgeCount[cubeEdgeIdx1][cubeEdgeIdx3]));
}
#endif
return triangleCount;
}

View File

@@ -40,28 +40,40 @@ public:
int derivedVxLevel; //< Helper data to make it possible to track what set of ClipVx's the indices is reffering to in case of consecutive clips
};
static bool planeLineIntersect(const cvf::Plane& plane, const cvf::Vec3d& a, const cvf::Vec3d& b, cvf::Vec3d* intersection, double* normalizedDistFromA);
static bool planeLineIntersect(const cvf::Plane& plane,
const cvf::Vec3d& a,
const cvf::Vec3d& b,
cvf::Vec3d* intersection,
double* normalizedDistFromA);
static bool planeTriangleIntersection(const cvf::Plane& plane,
const cvf::Vec3d& p1, size_t p1Id,
const cvf::Vec3d& p2, size_t p2Id,
const cvf::Vec3d& p3, size_t p3Id,
ClipVx* newVx1, ClipVx* newVx2,
bool* isMostVxesOnPositiveSide);
const cvf::Vec3d& p1,
size_t p1Id,
const cvf::Vec3d& p2,
size_t p2Id,
const cvf::Vec3d& p3,
size_t p3Id,
ClipVx* newVx1,
ClipVx* newVx2,
bool* isMostVxesOnPositiveSide);
static void clipTrianglesBetweenTwoParallelPlanes(const std::vector<ClipVx>& triangleVxes,
const std::vector<bool>& isTriangleEdgeCellContour,
const cvf::Plane& p1Plane, const cvf::Plane& p2Plane,
std::vector<ClipVx>* clippedTriangleVxes,
std::vector<bool>* isClippedTriEdgeCellContour);
const std::vector<int>& cellFaceForEachTriangleEdge,
const cvf::Plane& p1Plane,
const cvf::Plane& p2Plane,
std::vector<ClipVx>* clippedTriangleVxes,
std::vector<int>* cellFaceForEachClippedTriangleEdge);
static cvf::Vec3d planeLineIntersectionForMC(const cvf::Plane& plane, const cvf::Vec3d& p1, const cvf::Vec3d& p2, double* normalizedDistFromP1);
static cvf::Vec3d planeLineIntersectionForMC(const cvf::Plane& plane,
const cvf::Vec3d& p1,
const cvf::Vec3d& p2,
double* normalizedDistFromP1);
static int planeHexIntersectionMC(const cvf::Plane& plane,
const cvf::Vec3d cell[8],
const size_t hexCornersIds[8],
std::vector<ClipVx>* triangleVxes,
std::vector<bool>* isTriEdgeCellContour);
const cvf::Vec3d cell[8],
const size_t hexCornersIds[8],
std::vector<ClipVx>* triangleVxes,
std::vector<int>* cellFaceForEachTriangleEdge);
};