//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigGeoMechWellLogExtractor::calculateIntersection() { CVF_ASSERT(m_caseData->femParts()->partCount() == 1); std::map<RigMDCellIdxEnterLeaveKey, HexIntersectionInfo > uniqueIntersections; const RigFemPart* femPart = m_caseData->femParts()->part(0); const std::vector<cvf::Vec3f>& nodeCoords = femPart->nodes().coordinates; for (size_t wpp = 0; wpp < m_wellPath->m_wellPathPoints.size() - 1; ++wpp) { std::vector<HexIntersectionInfo> intersections; cvf::Vec3d p1 = m_wellPath->m_wellPathPoints[wpp]; cvf::Vec3d p2 = m_wellPath->m_wellPathPoints[wpp+1]; cvf::BoundingBox bb; bb.add(p1); bb.add(p2); std::vector<size_t> closeCells = findCloseCells(bb); cvf::Vec3d hexCorners[8]; for (size_t ccIdx = 0; ccIdx < closeCells.size(); ++ccIdx) { RigElementType elmType = femPart->elementType(closeCells[ccIdx]); if (!(elmType == HEX8 || elmType == HEX8P)) continue; const int* cornerIndices = femPart->connectivities(closeCells[ccIdx]); hexCorners[0] = cvf::Vec3d(nodeCoords[cornerIndices[0]]); hexCorners[1] = cvf::Vec3d(nodeCoords[cornerIndices[1]]); hexCorners[2] = cvf::Vec3d(nodeCoords[cornerIndices[2]]); hexCorners[3] = cvf::Vec3d(nodeCoords[cornerIndices[3]]); hexCorners[4] = cvf::Vec3d(nodeCoords[cornerIndices[4]]); hexCorners[5] = cvf::Vec3d(nodeCoords[cornerIndices[5]]); hexCorners[6] = cvf::Vec3d(nodeCoords[cornerIndices[6]]); hexCorners[7] = cvf::Vec3d(nodeCoords[cornerIndices[7]]); //int intersectionCount = RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[ccIdx], &intersections); RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[ccIdx], &intersections); } // Now, with all the intersections of this piece of line, we need to // sort them in order, and set the measured depth and corresponding cell index // Inserting the intersections in this map will remove identical intersections // and sort them according to MD, CellIdx, Leave/enter double md1 = m_wellPath->m_measuredDepths[wpp]; double md2 = m_wellPath->m_measuredDepths[wpp+1]; insertIntersectionsInMap(intersections, p1, md1, p2, md2, &uniqueIntersections); } this->populateReturnArrays(uniqueIntersections); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigEclipseWellLogExtractor::calculateIntersection() { std::map<RigMDCellIdxEnterLeaveKey, HexIntersectionInfo > uniqueIntersections; bool isCellFaceNormalsOut = m_caseData->mainGrid()->isFaceNormalsOutwards(); if (m_wellPath->m_wellPathPoints.empty()) return; for (size_t wpp = 0; wpp < m_wellPath->m_wellPathPoints.size() - 1; ++wpp) { std::vector<HexIntersectionInfo> intersections; cvf::Vec3d p1 = m_wellPath->m_wellPathPoints[wpp]; cvf::Vec3d p2 = m_wellPath->m_wellPathPoints[wpp+1]; cvf::BoundingBox bb; bb.add(p1); bb.add(p2); std::vector<size_t> closeCellIndices = findCloseCellIndices(bb); cvf::Vec3d hexCorners[8]; for (const auto& globalCellIndex : closeCellIndices) { const RigCell& cell = m_caseData->mainGrid()->globalCellArray()[globalCellIndex]; if (cell.isInvalid() || cell.subGrid() != nullptr) continue; m_caseData->mainGrid()->cellCornerVertices(globalCellIndex, hexCorners); RigHexIntersectionTools::lineHexCellIntersection(p1, p2, hexCorners, globalCellIndex, &intersections); } if (!isCellFaceNormalsOut) { for (auto& intersection : intersections) { intersection.m_isIntersectionEntering = !intersection.m_isIntersectionEntering; } } // Now, with all the intersections of this piece of line, we need to // sort them in order, and set the measured depth and corresponding cell index // Inserting the intersections in this map will remove identical intersections // and sort them according to MD, CellIdx, Leave/enter double md1 = m_wellPath->m_measuredDepths[wpp]; double md2 = m_wellPath->m_measuredDepths[wpp+1]; insertIntersectionsInMap(intersections, p1, md1, p2, md2, &uniqueIntersections); } if (uniqueIntersections.empty() && m_wellPath->m_wellPathPoints.size() > 1) { // When entering this function, all well path points are either completely outside the grid // or all well path points are inside one cell cvf::Vec3d firstPoint = m_wellPath->m_wellPathPoints.front(); cvf::Vec3d lastPoint = m_wellPath->m_wellPathPoints.back(); { cvf::BoundingBox bb; bb.add(firstPoint); std::vector<size_t> closeCellIndices = findCloseCellIndices(bb); cvf::Vec3d hexCorners[8]; for (const auto& globalCellIndex : closeCellIndices) { const RigCell& cell = m_caseData->mainGrid()->globalCellArray()[globalCellIndex]; if (cell.isInvalid()) continue; m_caseData->mainGrid()->cellCornerVertices(globalCellIndex, hexCorners); if (RigHexIntersectionTools::isPointInCell(firstPoint, hexCorners)) { if (RigHexIntersectionTools::isPointInCell(lastPoint, hexCorners)) { { // Mark the first well path point as entering the cell bool isEntering = true; HexIntersectionInfo info(firstPoint, isEntering, cvf::StructGridInterface::NO_FACE, globalCellIndex); RigMDCellIdxEnterLeaveKey enterLeaveKey(m_wellPath->m_measuredDepths.front(), globalCellIndex, isEntering); uniqueIntersections.insert(std::make_pair(enterLeaveKey, info)); } { // Mark the last well path point as leaving cell bool isEntering = false; HexIntersectionInfo info(lastPoint, isEntering, cvf::StructGridInterface::NO_FACE, globalCellIndex); RigMDCellIdxEnterLeaveKey enterLeaveKey(m_wellPath->m_measuredDepths.back(), globalCellIndex, isEntering); uniqueIntersections.insert(std::make_pair(enterLeaveKey, info)); } } else { QString txt = "Detected two points assumed to be in the same cell, but they are in two different cells"; RiaLogging::debug(txt); } } } } } this->populateReturnArrays(uniqueIntersections); }