//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::setCellResultIndex(size_t reservoirCellIndex, size_t reservoirCellResultIndex) { CVF_TIGHT_ASSERT(reservoirCellResultIndex < m_cellIndexToResultIndex.size()); m_cellIndexToResultIndex[reservoirCellIndex] = reservoirCellResultIndex; if (reservoirCellResultIndex >= m_reservoirCellResultCount) { m_reservoirCellResultCount = reservoirCellResultIndex + 1; } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::setCellResultIndex(size_t globalCellIndex, size_t globalCellResultIndex) { CVF_TIGHT_ASSERT(globalCellResultIndex < m_cellIndexToResultIndex.size()); m_cellIndexToResultIndex[globalCellIndex] = globalCellResultIndex; if (globalCellResultIndex >= m_globalCellResultCount) { m_globalCellResultCount = globalCellResultIndex + 1; } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigActiveCellInfo::isActive(size_t globalCellIndex) const { if (m_cellIndexToResultIndex.size() == 0) { return true; } CVF_TIGHT_ASSERT(globalCellIndex < m_cellIndexToResultIndex.size()); return m_cellIndexToResultIndex[globalCellIndex] != cvf::UNDEFINED_SIZE_T; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void PartRenderHintCollection::add(Part* part) { CVF_TIGHT_ASSERT(part); size_t arrSize = m_parts.size(); CVF_TIGHT_ASSERT(arrSize == m_renderHints.size()); if (arrSize > m_itemCount) { m_parts[m_itemCount] = part; m_renderHints[m_itemCount] = NULL; } else { m_parts.push_back(part); m_renderHints.push_back(NULL); } m_itemCount++; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigActiveCellInfo::cellResultIndex(size_t reservoirCellIndex) const { if (m_cellIndexToResultIndex.size() == 0) { return reservoirCellIndex; } CVF_TIGHT_ASSERT(reservoirCellIndex < m_cellIndexToResultIndex.size()); return m_cellIndexToResultIndex[reservoirCellIndex]; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigActiveCellInfo::cellResultIndex(size_t globalCellIndex) const { if (m_cellIndexToResultIndex.size() == 0) { return globalCellIndex; } CVF_TIGHT_ASSERT(globalCellIndex < m_cellIndexToResultIndex.size()); return m_cellIndexToResultIndex[globalCellIndex]; }
//-------------------------------------------------------------------------------------------------- /// Returns an array with vertex indices into the input origVertexArray for each vertex in the /// output vertexArray(). Used to keep track of the original index of the compacted and split output /// array. //-------------------------------------------------------------------------------------------------- ref<UIntArray> TriangleVertexSplitter::perVertexOriginalIndices() { if (!m_isComputed) { splitVertices(); } size_t numUsedVertices = m_vertexArray.size(); ref<UIntArray> output = new UIntArray; if (numUsedVertices == 0) { return output; } output->resize(numUsedVertices); output->setAll(UNDEFINED_UINT); size_t numOrigVertices = m_origVertexArray.size(); size_t i; for (i = 0; i < numOrigVertices; i++) { uint usedIdx = m_origToUsedNodeMap[i]; if (usedIdx != UNDEFINED_UINT) { output->set(usedIdx, static_cast<uint>(i)); } } for (i = 0; i < numUsedVertices; i++) { if (output->get(i) != UNDEFINED_UINT) { uint origIndex = output->get(i); uint nextSplit = m_nextSplitVertexIdx[i]; m_nextSplitVertexIdx[i] = UNDEFINED_UINT; while (nextSplit != UNDEFINED_UINT) { CVF_TIGHT_ASSERT(output->get(nextSplit) == UNDEFINED_UINT); output->set(nextSplit, origIndex); uint nextSplitThis = nextSplit; nextSplit = m_nextSplitVertexIdx[nextSplit]; m_nextSplitVertexIdx[nextSplitThis] = UNDEFINED_UINT; } } } return output; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RigActiveCellsResultAccessor::cellScalar(size_t gridLocalCellIndex) const { if (m_reservoirResultValues == NULL || m_reservoirResultValues->size() == 0 ) return HUGE_VAL; size_t reservoirCellIndex = m_grid->reservoirCellIndex(gridLocalCellIndex); size_t resultValueIndex = m_activeCellInfo->cellResultIndex(reservoirCellIndex); if (resultValueIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL; CVF_TIGHT_ASSERT(resultValueIndex < m_reservoirResultValues->size()); return m_reservoirResultValues->at(resultValueIndex); }
//-------------------------------------------------------------------------------------------------- /// Create any needed buffer objects and upload data to the GPU /// /// Buffer objects are created only if renderMode is set to VBO. /// /// \warning Requires at least OpenGL 1.5 //-------------------------------------------------------------------------------------------------- void DrawableGeo::createUploadBufferObjectsGPU(OpenGLContext* oglContext) { CVF_TIGHT_ASSERT(oglContext); CVF_TIGHT_ASSERT(BufferObjectManaged::supportedOpenGL(oglContext)); if (m_renderMode != BUFFER_OBJECT) { return; } // Upload all data in the bundle m_vertexBundle->createUploadBufferObjectsGPU(oglContext); // Do the primitive sets separately size_t numPrimitiveSets = m_primitiveSets.size(); for (size_t i = 0; i < numPrimitiveSets; i++) { PrimitiveSet* prim = m_primitiveSets[i].p(); prim->createUploadBufferObjectsGPU(oglContext); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigEclipseWellLogExtractor::curveData(const RigResultAccessor* resultAccessor, std::vector<double>* values) { CVF_TIGHT_ASSERT(values); values->resize(m_intersections.size()); for (size_t cpIdx = 0; cpIdx < m_intersections.size(); ++cpIdx) { size_t cellIdx = m_intersectedCellsGlobIdx[cpIdx]; cvf::StructGridInterface::FaceType cellFace = m_intersectedCellFaces[cpIdx]; (*values)[cpIdx] = resultAccessor->cellFaceScalarGlobIdx(cellIdx, cellFace); } }
//-------------------------------------------------------------------------------------------------- /// Releases all buffer objects (BOs) held by this drawable /// /// \warning The OpenGL context in which the resources were created or a context that is being /// shared must be current in the calling thread. /// \warning In order to assure that the actual OpenGL resources get deleted, you must call /// OpenGLResourceManager::deleteOrphanedManagedBufferObjects() afterwards. //-------------------------------------------------------------------------------------------------- void DrawableGeo::releaseBufferObjectsGPU() { m_vertexBundle->releaseBufferObjectsGPU(); // Release all buffer objects in primitive sets size_t numPrimitiveSets = m_primitiveSets.size(); for (size_t i = 0; i < numPrimitiveSets; i++) { PrimitiveSet* prim = m_primitiveSets[i].p(); CVF_TIGHT_ASSERT(prim); prim->releaseBufferObjectsGPU(); } }
//-------------------------------------------------------------------------------------------------- /// Create buffer object and upload data to the GPU /// /// \warning The current render context must support buffer objects (OGL version >= 1.5) //-------------------------------------------------------------------------------------------------- void PrimitiveSetIndexedUInt::createUploadBufferObjectsGPU(OpenGLContext* oglContext) { CVF_TIGHT_ASSERT(oglContext); CVF_TIGHT_ASSERT(BufferObjectManaged::supportedOpenGL(oglContext)); // Buffer object already in place? if (m_indicesBO.notNull() && m_indicesBO->isUploaded()) { return; } if (m_indices.notNull()) { size_t numIndices = m_indices->size(); if (numIndices > 0) { GLuint uiSizeInBytes = static_cast<GLuint>(numIndices*sizeof(GLuint)); m_indicesBO = oglContext->resourceManager()->getOrCreateManagedBufferObject(oglContext, GL_ELEMENT_ARRAY_BUFFER, uiSizeInBytes, m_indices->ptr()); CVF_CHECK_OGL(oglContext); } } }
//-------------------------------------------------------------------------------------------------- /// Do immediate mode rendering //-------------------------------------------------------------------------------------------------- void DrawableGeo::renderImmediateMode(OpenGLContext* oglContext, const MatrixState&) { #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else CVF_ASSERT(oglContext); const Vec3fArray* vertexArr = m_vertexBundle->vertexArray(); const Vec3fArray* normalArr = m_vertexBundle->normalArray(); const Vec2fArray* texCoordArr = m_vertexBundle->textureCoordArray(); const Color3ubArray* colorArr = m_vertexBundle->colorArray(); size_t numPrimitiveSets = m_primitiveSets.size(); size_t ip; for (ip = 0; ip < numPrimitiveSets; ip++) { const PrimitiveSet* primitiveSet = m_primitiveSets.at(ip); CVF_TIGHT_ASSERT(primitiveSet); glBegin(primitiveSet->primitiveTypeOpenGL()); size_t numIndices = primitiveSet->indexCount(); size_t i; for (i = 0; i < numIndices; i++) { uint index = primitiveSet->index(i); if (normalArr) { glNormal3fv((const float*)&normalArr->get(index)); } if (colorArr) { glColor3ubv((const ubyte*)&colorArr->get(index)); } if (texCoordArr) { glTexCoord2fv((const float*)&texCoordArr->get(index)); } glVertex3fv((float*)&vertexArr->get(index)); } glEnd(); } #endif // CVF_OPENGL_ES }
//-------------------------------------------------------------------------------------------------- /// Render primitives in this primitive set using vertex arrays /// /// \warning Requires at least OpenGL 1.5 //-------------------------------------------------------------------------------------------------- void PrimitiveSetIndexedUInt::render(OpenGLContext* oglContext) const { CVF_CALLSITE_OPENGL(oglContext); CVF_TIGHT_ASSERT(oglContext); CVF_TIGHT_ASSERT(BufferObjectManaged::supportedOpenGL(oglContext)); if (m_indices.isNull()) { return; } GLsizei numIndices = static_cast<GLsizei>(m_indices->size()); if (numIndices <= 0) { return; } const GLvoid* ptrOrOffset = 0; if (m_indicesBO.notNull() && m_indicesBO->isUploaded()) { m_indicesBO->bindBuffer(oglContext); } else { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); ptrOrOffset = m_indices->ptr(); } #ifdef CVF_OPENGL_ES glDrawElements(primitiveTypeOpenGL(), numIndices, GL_UNSIGNED_INT, ptrOrOffset); #else glDrawRangeElements(primitiveTypeOpenGL(), m_minIndex, m_maxIndex, numIndices, GL_UNSIGNED_INT, ptrOrOffset); #endif CVF_CHECK_OGL(oglContext); }
//-------------------------------------------------------------------------------------------------- /// Check if the bounding box contains the specified point /// /// Note that a point on the box's surface is classified as being contained //-------------------------------------------------------------------------------------------------- bool BoundingBox::contains(const Vec3d& point) const { CVF_TIGHT_ASSERT(isValid()); if (point.x() >= m_min.x() && point.x() <= m_max.x() && point.y() >= m_min.y() && point.y() <= m_max.y() && point.z() >= m_min.z() && point.z() <= m_max.z()) { return true; } else { return false; } }
bool operator()(const RenderItem* a, const RenderItem* b) const { CVF_TIGHT_ASSERT(a && b); CVF_TIGHT_ASSERT(a->effect()); CVF_TIGHT_ASSERT(b->effect()); // This sorter is currently experimental!! // Sort order is: // - priority // - shader program // - state set // - effect // - drawable if (a->part()->priority() != b->part()->priority()) { return (a->part()->priority() < b->part()->priority()); } else if (a->effect()->shaderProgram() != b->effect()->shaderProgram()) { return (a->effect()->shaderProgram() < b->effect()->shaderProgram()); } else if (a->effect()->renderStateSet() != b->effect()->renderStateSet()) { return (a->effect()->renderStateSet() < b->effect()->renderStateSet()); } else if (a->effect() != b->effect()) { return (a->effect() < b->effect()); } else { return (a->drawable() < b->drawable()); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigGridCellFaceVisibilityFilter::isFaceVisible(size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility) const { CVF_TIGHT_ASSERT(m_grid); size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k); if (m_grid->cell(cellIndex).subGrid()) { // Do not show any faces in the place where a LGR is present return false; } size_t ni, nj, nk; cvf::StructGridInterface::neighborIJKAtCellFace(i, j, k, face, &ni, &nj, &nk); // If the cell is on the edge of the grid, Interpret as having an invisible neighbour if (ni >= m_grid->cellCountI() || nj >= m_grid->cellCountJ() || nk >= m_grid->cellCountK()) { return true; } size_t neighborCellIndex = m_grid->cellIndexFromIJK(ni, nj, nk); // Do show the faces in the boarder between this grid and a possible LGR. Some of the LGR cells // might not be visible. if (m_grid->cell(neighborCellIndex).subGrid()) { return true; } // Do not show cell geometry if a fault is present to avoid z fighting between surfaces // It will always be a better solution to avoid geometry creation instead of part priority and polygon offset size_t nativeResvCellIndex = m_grid->reservoirCellIndex(cellIndex); const RigFault* fault = m_grid->mainGrid()->findFaultFromCellIndexAndCellFace(nativeResvCellIndex, face); if (fault) { return false; } // If the neighbour cell is invisible, we need to draw the face if ((cellVisibility != NULL) && !(*cellVisibility)[neighborCellIndex]) { return true; } return false; }
//-------------------------------------------------------------------------------------------------- /// Get layout information //-------------------------------------------------------------------------------------------------- void OverlayScalarMapperLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout) { CVF_TIGHT_ASSERT(layout); ref<Glyph> glyph = m_font->getGlyph(L'A'); layout->charHeight = static_cast<float>(glyph->height()); layout->lineSpacing = layout->charHeight*1.5f; layout->margins = Vec2f(4.0f, 4.0f); float legendWidth = 25.0f; float legendHeight = static_cast<float>(layout->size.y()) - 2*layout->margins.y() - static_cast<float>(m_titleStrings.size())*layout->lineSpacing - layout->lineSpacing; layout->legendRect = Rectf(layout->margins.x(), layout->margins.y() + layout->charHeight/2.0f, legendWidth, legendHeight); if (layout->legendRect.width() < 1 || layout->legendRect.height() < 1) { return; } layout->x0 = layout->margins.x(); layout->x1 = layout->margins.x() + layout->legendRect.width(); layout->tickX = layout->x1 + 5; // Build array containing the pixel positions of all the ticks size_t numTicks = m_tickValues.size(); layout->tickPixelPos = new DoubleArray(numTicks); size_t i; for (i = 0; i < numTicks; i++) { double t; if (m_scalarMapper.isNull()) t = 0; else t = m_scalarMapper->normalizedValue(m_tickValues[i]); t = Math::clamp(t, 0.0, 1.1); if (i != numTicks -1) { layout->tickPixelPos->set(i, t*layout->legendRect.height()); } else { layout->tickPixelPos->set(i, layout->legendRect.height()); // Make sure we get a value at the top even if the scalarmapper range is zero } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RenderQueueSorterTargetFramerate::sort(RenderQueue* renderQueue) const { std::vector<RenderItem*>* renderItems = renderQueue->renderItemsForSorting(); CVF_TIGHT_ASSERT(renderItems); std::vector<RenderItem*>::difference_type numItemsToDraw = static_cast<std::vector<RenderItem*>::difference_type>(std::min(m_maxNumPartsToDraw, renderItems->size())); std::vector<RenderItem*>::difference_type numItemsToDistSort = static_cast<std::vector<RenderItem*>::difference_type>(std::min(m_numPartsToDistanceSort, renderItems->size())); bool useTBB = TBBControl::isEnabled(); SortAlgorithms sa(useTBB); sa.partial_sort(renderItems->begin(), renderItems->begin() + numItemsToDistSort, renderItems->end(), ComparatorDistance()); sa.sort(renderItems->begin(), renderItems->begin() + numItemsToDistSort, ComparatorEffectOnly()); sa.sort(renderItems->begin() + numItemsToDistSort, renderItems->end(), ComparatorArea()); sa.sort(renderItems->begin() + numItemsToDistSort, renderItems->begin() + static_cast<int>(numItemsToDraw), ComparatorEffectOnly()); sa.sort(renderItems->begin() + numItemsToDraw, renderItems->end(), ComparatorEffectOnly()); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigGridBase::ijkFromCellIndex(size_t cellIndex, size_t* i, size_t* j, size_t* k) const { CVF_TIGHT_ASSERT(cellIndex < cellCount()); size_t index = cellIndex; if (cellCountI() <= 0 || cellCountJ() <= 0) { return false; } *k = index/(cellCountI()*cellCountJ()); index -= (*k)*(cellCountI()*cellCountJ()); *j = index/cellCountI(); index -= (*j)*cellCountI(); *i = index; return true; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimWellPathFracture::compareByWellPathNameAndMD(const RimWellPathFracture* lhs, const RimWellPathFracture* rhs) { CVF_TIGHT_ASSERT(lhs && rhs); RimWellPath* lhsWellPath = nullptr; lhs->firstAncestorOrThisOfType(lhsWellPath); RimWellPath* rhsWellPath = nullptr; rhs->firstAncestorOrThisOfType(rhsWellPath); if (lhsWellPath && rhsWellPath) { if (lhsWellPath->name() != rhsWellPath->name()) { return lhsWellPath->name() < rhsWellPath->name(); } } return lhs->fractureMD() < rhs->fractureMD(); }
//-------------------------------------------------------------------------------------------------- /// Setup and bind texture //-------------------------------------------------------------------------------------------------- void Glyph::setupAndBindTexture(OpenGLContext* oglContext, bool software) { // Short path first if everything is in place if (m_textureBindings.notNull()) { RenderState::Type renderStateType = m_textureBindings->type(); if (software) { #ifndef CVF_OPENGL_ES if (renderStateType == RenderState::TEXTURE_MAPPING_FF) { RenderStateTextureMapping_FF* texMapping = static_cast<RenderStateTextureMapping_FF*>(m_textureBindings.p()); texMapping->setupTexture(oglContext); texMapping->applyOpenGL(oglContext); return; } #else CVF_FAIL_MSG("Not supported on OpenGL ES"); #endif } else { if (renderStateType == RenderState::TEXTURE_BINDINGS) { RenderStateTextureBindings* texBindings = static_cast<RenderStateTextureBindings*>(m_textureBindings.p()); texBindings->setupTextures(oglContext); texBindings->applyOpenGL(oglContext); return; } } } m_textureBindings = NULL; if (m_textureBindings.isNull()) { // TODO // Revisit the code that sets up the texture image // The code below ends up modifying the stored texture image // Is this intentional - there is an external getter for the image!! CVF_TIGHT_ASSERT(0 < m_textureImage->width()); CVF_TIGHT_ASSERT(0 < m_textureImage->height()); uint pow2Width = Math::roundUpPow2(m_width); uint pow2Height = Math::roundUpPow2(m_height); TextureImage* pow2Image = new TextureImage; pow2Image->allocate(pow2Width, pow2Height); pow2Image->fill(Color4ub(255, 255, 255, 0)); uint i, j; for (j = 0; j < m_height; j++) { for (i = 0; i < m_width; i++) { pow2Image->setPixel(i, j, m_textureImage->pixel(i, j)); } } float textureCoordinateMaxX = static_cast<float>(m_width) / static_cast<float>(pow2Width); float textureCoordinateMaxY = static_cast<float>(m_height) / static_cast<float>(pow2Height); // Lower left m_textureCoordinates->set(0, 0.0f); m_textureCoordinates->set(1, 0.0f); // Lower right m_textureCoordinates->set(2, textureCoordinateMaxX); m_textureCoordinates->set(3, 0.0f); // Upper right m_textureCoordinates->set(4, textureCoordinateMaxX); m_textureCoordinates->set(5, textureCoordinateMaxY); // Upper left m_textureCoordinates->set(6, 0.0f); m_textureCoordinates->set(7, textureCoordinateMaxY); m_textureImage = pow2Image; if (software) { #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else // Use fixed function texture setup ref<Texture2D_FF> texture = new Texture2D_FF(m_textureImage.p()); texture->setWrapMode(Texture2D_FF::CLAMP); if (m_minFilter == NEAREST) { texture->setMinFilter(Texture2D_FF::NEAREST); } else { texture->setMinFilter(Texture2D_FF::LINEAR); } if (m_magFilter == NEAREST) { texture->setMagFilter(Texture2D_FF::NEAREST); } else { texture->setMagFilter(Texture2D_FF::LINEAR); } ref<RenderStateTextureMapping_FF> textureMapping = new RenderStateTextureMapping_FF(texture.p()); textureMapping->setTextureFunction(RenderStateTextureMapping_FF::MODULATE); textureMapping->setupTexture(oglContext); m_textureBindings = textureMapping; #endif } else { ref<Sampler> sampler = new Sampler; sampler->setWrapMode(Sampler::CLAMP_TO_EDGE); if (m_minFilter == NEAREST) { sampler->setMinFilter(Sampler::NEAREST); } else { sampler->setMinFilter(Sampler::LINEAR); } if (m_magFilter == NEAREST) { sampler->setMagFilter(Sampler::NEAREST); } else { sampler->setMagFilter(Sampler::LINEAR); } ref<Texture> texture = new Texture(m_textureImage.p()); RenderStateTextureBindings* textureBindings = new RenderStateTextureBindings(texture.p(), sampler.p(), "dummy"); textureBindings->setupTextures(oglContext); m_textureBindings = textureBindings; } } if (m_textureBindings.notNull()) { m_textureBindings->applyOpenGL(oglContext); } }
//-------------------------------------------------------------------------------------------------- /// Average of neighbor corresponding nodes //-------------------------------------------------------------------------------------------------- void RigCaseToCaseCellMapperTools::estimatedFemCellFromEclCell(const RigMainGrid* eclGrid, size_t reservoirCellIndex, cvf::Vec3d estimatedElmCorners[8]) { CVF_TIGHT_ASSERT(reservoirCellIndex < eclGrid->cellCount()); // Assume reservoirCellIdx == localGridCellIdx for maingrid const std::vector<cvf::Vec3d>& eclNodes = eclGrid->nodes(); size_t I,J,K; eclGrid->ijkFromCellIndex(reservoirCellIndex, &I, &J, &K); RigNeighborCornerFinder nbFinder(eclGrid, I,J,K); // Cell corner Averaging mapping: Local cell index in neighbor matching specific corner of this cell // N - Negative P - positive // 0 <- NI[1] NINJ[2] NJ[3] NK[4] NINK[5] NINJNK[6] NJNK[7] // 1 <- NJ[2] PINJ[3] PI[0] NK[5] NJNK[6] PINJNK[7] PINK[4] // 2 <- PI[3] PIPJ[0] PJ[1] NK[6] PINK[7] PIPJNK[4] PJNK[5] // 3 <- PJ[0] NIPJ[1] NI[2] NK[7] PJNK[4] NIPJNK[5] NINK[6] // 4 <- NI[5] NINJ[6] NJ[7] PK[0] NIPK[1] NINJPK[2] NJPK[3] // 5 <- NJ[6] PINJ[7] PI[4] PK[1] NJPK[2] PINJPK[3] PIPK[0] // 6 <- PI[7] PIPJ[4] PJ[5] PK[2] PIPK[3] PIPJPK[0] PJPK[1] // 7 <- PJ[4] NIPJ[5] NI[6] PK[3] PJPK[0] NIPJPK[1] NIPK[2] const caf::SizeTArray8* IJK = nbFinder.neighborIndices( 0, 0, 0); const caf::SizeTArray8* NI = nbFinder.neighborIndices(-1, 0, 0); const caf::SizeTArray8* NJ = nbFinder.neighborIndices( 0,-1, 0); const caf::SizeTArray8* PI = nbFinder.neighborIndices( 1, 0, 0); const caf::SizeTArray8* PJ = nbFinder.neighborIndices( 0, 1, 0); const caf::SizeTArray8* NK = nbFinder.neighborIndices( 0, 0,-1); const caf::SizeTArray8* PK = nbFinder.neighborIndices( 0, 0, 1); const caf::SizeTArray8* NINJ = nbFinder.neighborIndices(-1,-1, 0); const caf::SizeTArray8* PINJ = nbFinder.neighborIndices( 1,-1, 0); const caf::SizeTArray8* PIPJ = nbFinder.neighborIndices( 1, 1, 0); const caf::SizeTArray8* NIPJ = nbFinder.neighborIndices(-1, 1, 0); const caf::SizeTArray8* NINK = nbFinder.neighborIndices(-1, 0,-1); const caf::SizeTArray8* NJNK = nbFinder.neighborIndices( 0,-1,-1); const caf::SizeTArray8* PINK = nbFinder.neighborIndices( 1, 0,-1); const caf::SizeTArray8* PJNK = nbFinder.neighborIndices( 0, 1,-1); const caf::SizeTArray8* NIPK = nbFinder.neighborIndices(-1, 0, 1); const caf::SizeTArray8* NJPK = nbFinder.neighborIndices( 0,-1, 1); const caf::SizeTArray8* PIPK = nbFinder.neighborIndices( 1, 0, 1); const caf::SizeTArray8* PJPK = nbFinder.neighborIndices( 0, 1, 1); const caf::SizeTArray8* NINJNK = nbFinder.neighborIndices(-1,-1,-1); const caf::SizeTArray8* PINJNK = nbFinder.neighborIndices( 1,-1,-1); const caf::SizeTArray8* PIPJNK = nbFinder.neighborIndices( 1, 1,-1); const caf::SizeTArray8* NIPJNK = nbFinder.neighborIndices(-1, 1,-1); const caf::SizeTArray8* NINJPK = nbFinder.neighborIndices(-1,-1, 1); const caf::SizeTArray8* PINJPK = nbFinder.neighborIndices( 1,-1, 1); const caf::SizeTArray8* PIPJPK = nbFinder.neighborIndices( 1, 1, 1); const caf::SizeTArray8* NIPJPK = nbFinder.neighborIndices(-1, 1, 1); std::vector<size_t> contributingNodeIndicesPrCellCorner[8]; if (IJK ) contributingNodeIndicesPrCellCorner[0].push_back((*IJK )[0]); if (NI ) contributingNodeIndicesPrCellCorner[0].push_back((*NI )[1]); if (NINJ ) contributingNodeIndicesPrCellCorner[0].push_back((*NINJ )[2]); if (NJ ) contributingNodeIndicesPrCellCorner[0].push_back((*NJ )[3]); if (NK ) contributingNodeIndicesPrCellCorner[0].push_back((*NK )[4]); if (NINK ) contributingNodeIndicesPrCellCorner[0].push_back((*NINK )[5]); if (NINJNK) contributingNodeIndicesPrCellCorner[0].push_back((*NINJNK)[6]); if (NJNK ) contributingNodeIndicesPrCellCorner[0].push_back((*NJNK )[7]); if (IJK ) contributingNodeIndicesPrCellCorner[1].push_back((*IJK )[1]); if (NJ ) contributingNodeIndicesPrCellCorner[1].push_back((*NJ )[2]); if (PINJ ) contributingNodeIndicesPrCellCorner[1].push_back((*PINJ )[3]); if (PI ) contributingNodeIndicesPrCellCorner[1].push_back((*PI )[0]); if (NK ) contributingNodeIndicesPrCellCorner[1].push_back((*NK )[5]); if (NJNK ) contributingNodeIndicesPrCellCorner[1].push_back((*NJNK )[6]); if (PINJNK) contributingNodeIndicesPrCellCorner[1].push_back((*PINJNK)[7]); if (PINK ) contributingNodeIndicesPrCellCorner[1].push_back((*PINK )[4]); if (IJK ) contributingNodeIndicesPrCellCorner[2].push_back((*IJK )[2]); if (PI ) contributingNodeIndicesPrCellCorner[2].push_back((*PI )[3]); if (PIPJ ) contributingNodeIndicesPrCellCorner[2].push_back((*PIPJ )[0]); if (PJ ) contributingNodeIndicesPrCellCorner[2].push_back((*PJ )[1]); if (NK ) contributingNodeIndicesPrCellCorner[2].push_back((*NK )[6]); if (PINK ) contributingNodeIndicesPrCellCorner[2].push_back((*PINK )[7]); if (PIPJNK) contributingNodeIndicesPrCellCorner[2].push_back((*PIPJNK)[4]); if (PJNK ) contributingNodeIndicesPrCellCorner[2].push_back((*PJNK )[5]); if (IJK ) contributingNodeIndicesPrCellCorner[3].push_back((*IJK )[3]); if (PJ ) contributingNodeIndicesPrCellCorner[3].push_back((*PJ )[0]); if (NIPJ ) contributingNodeIndicesPrCellCorner[3].push_back((*NIPJ )[1]); if (NI ) contributingNodeIndicesPrCellCorner[3].push_back((*NI )[2]); if (NK ) contributingNodeIndicesPrCellCorner[3].push_back((*NK )[7]); if (PJNK ) contributingNodeIndicesPrCellCorner[3].push_back((*PJNK )[4]); if (NIPJNK) contributingNodeIndicesPrCellCorner[3].push_back((*NIPJNK)[5]); if (NINK ) contributingNodeIndicesPrCellCorner[3].push_back((*NINK )[6]); // 4 <- NI[5] NINJ[6] NJ[7] PK[0] NIPK[1] NINJPK[2] NJPK[3] if (IJK ) contributingNodeIndicesPrCellCorner[4].push_back((*IJK )[4]); if (NI ) contributingNodeIndicesPrCellCorner[4].push_back((*NI )[5]); if (NINJ ) contributingNodeIndicesPrCellCorner[4].push_back((*NINJ )[6]); if (NJ ) contributingNodeIndicesPrCellCorner[4].push_back((*NJ )[7]); if (PK ) contributingNodeIndicesPrCellCorner[4].push_back((*PK )[0]); if (NIPK ) contributingNodeIndicesPrCellCorner[4].push_back((*NIPK )[1]); if (NINJPK) contributingNodeIndicesPrCellCorner[4].push_back((*NINJPK)[2]); if (NJPK ) contributingNodeIndicesPrCellCorner[4].push_back((*NJPK )[3]); if (IJK ) contributingNodeIndicesPrCellCorner[5].push_back((*IJK )[5]); if (NJ ) contributingNodeIndicesPrCellCorner[5].push_back((*NJ )[6]); if (PINJ ) contributingNodeIndicesPrCellCorner[5].push_back((*PINJ )[7]); if (PI ) contributingNodeIndicesPrCellCorner[5].push_back((*PI )[4]); if (PK ) contributingNodeIndicesPrCellCorner[5].push_back((*PK )[1]); if (NJPK ) contributingNodeIndicesPrCellCorner[5].push_back((*NJPK )[2]); if (PINJPK) contributingNodeIndicesPrCellCorner[5].push_back((*PINJPK)[3]); if (PIPK ) contributingNodeIndicesPrCellCorner[5].push_back((*PIPK )[0]); // 6 <- PI[7] PIPJ[4] PJ[5] PK[2] PIPK[3] PIPJPK[0] PJPK[1] if (IJK ) contributingNodeIndicesPrCellCorner[6].push_back((*IJK )[6]); if (PI ) contributingNodeIndicesPrCellCorner[6].push_back((*PI )[7]); if (PIPJ ) contributingNodeIndicesPrCellCorner[6].push_back((*PIPJ )[4]); if (PJ ) contributingNodeIndicesPrCellCorner[6].push_back((*PJ )[5]); if (PK ) contributingNodeIndicesPrCellCorner[6].push_back((*PK )[2]); if (PIPK ) contributingNodeIndicesPrCellCorner[6].push_back((*PIPK )[3]); if (PIPJPK) contributingNodeIndicesPrCellCorner[6].push_back((*PIPJPK)[0]); if (PJPK ) contributingNodeIndicesPrCellCorner[6].push_back((*PJPK )[1]); if (IJK ) contributingNodeIndicesPrCellCorner[7].push_back((*IJK )[7]); if (PJ ) contributingNodeIndicesPrCellCorner[7].push_back((*PJ )[4]); if (NIPJ ) contributingNodeIndicesPrCellCorner[7].push_back((*NIPJ )[5]); if (NI ) contributingNodeIndicesPrCellCorner[7].push_back((*NI )[6]); if (PK ) contributingNodeIndicesPrCellCorner[7].push_back((*PK )[3]); if (PJPK ) contributingNodeIndicesPrCellCorner[7].push_back((*PJPK )[0]); if (NIPJPK) contributingNodeIndicesPrCellCorner[7].push_back((*NIPJPK)[1]); if (NIPK ) contributingNodeIndicesPrCellCorner[7].push_back((*NIPK )[2]); // Average the nodes for (size_t cornIdx = 0; cornIdx < 8; ++cornIdx) { estimatedElmCorners[cornIdx] = cvf::Vec3d::ZERO; size_t contribCount = contributingNodeIndicesPrCellCorner[cornIdx].size(); for (size_t ctnIdx = 0; ctnIdx < contribCount; ++ctnIdx) { estimatedElmCorners[cornIdx] += eclNodes[contributingNodeIndicesPrCellCorner[cornIdx][ctnIdx]]; } estimatedElmCorners[cornIdx] /= contribCount; } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigGeoMechWellLogExtractor::curveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values) { CVF_TIGHT_ASSERT(values); if (!resAddr.isValid()) return ; RigFemResultAddress convResAddr = resAddr; // When showing POR results, always use the element nodal result, // to get correct handling of elements without POR results if (convResAddr.fieldName == "POR-Bar") convResAddr.resultPosType = RIG_ELEMENT_NODAL; const RigFemPart* femPart = m_caseData->femParts()->part(0); const std::vector<cvf::Vec3f>& nodeCoords = femPart->nodes().coordinates; const std::vector<float>& resultValues = m_caseData->femPartResults()->resultValues(convResAddr, 0, frameIndex); if (!resultValues.size()) return; values->resize(m_intersections.size()); for (size_t cpIdx = 0; cpIdx < m_intersections.size(); ++cpIdx) { size_t elmIdx = m_intersectedCells[cpIdx]; RigElementType elmType = femPart->elementType(elmIdx); if (!(elmType == HEX8 || elmType == HEX8P)) continue; cvf::StructGridInterface::FaceType cellFace = m_intersectedCellFaces[cpIdx]; int faceNodeCount = 0; const int* faceLocalIndices = RigFemTypes::localElmNodeIndicesForFace(elmType, cellFace, &faceNodeCount); const int* elmNodeIndices = femPart->connectivities(elmIdx); cvf::Vec3d v0(nodeCoords[elmNodeIndices[faceLocalIndices[0]]]); cvf::Vec3d v1(nodeCoords[elmNodeIndices[faceLocalIndices[1]]]); cvf::Vec3d v2(nodeCoords[elmNodeIndices[faceLocalIndices[2]]]); cvf::Vec3d v3(nodeCoords[elmNodeIndices[faceLocalIndices[3]]]); size_t resIdx0 = cvf::UNDEFINED_SIZE_T; size_t resIdx1 = cvf::UNDEFINED_SIZE_T; size_t resIdx2 = cvf::UNDEFINED_SIZE_T; size_t resIdx3 = cvf::UNDEFINED_SIZE_T; if (convResAddr.resultPosType == RIG_NODAL) { resIdx0 = elmNodeIndices[faceLocalIndices[0]]; resIdx1 = elmNodeIndices[faceLocalIndices[1]]; resIdx2 = elmNodeIndices[faceLocalIndices[2]]; resIdx3 = elmNodeIndices[faceLocalIndices[3]]; } else { resIdx0 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[0]); resIdx1 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[1]); resIdx2 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[2]); resIdx3 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[3]); } double interpolatedValue = cvf::GeometryTools::interpolateQuad( v0, resultValues[resIdx0], v1, resultValues[resIdx1], v2, resultValues[resIdx2], v3, resultValues[resIdx3], m_intersections[cpIdx] ); (*values)[cpIdx] = interpolatedValue; } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const std::vector< std::vector<double> > & RigCaseCellResultsData::cellScalarResults( size_t scalarResultIndex ) const { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); return m_cellScalarResults[scalarResultIndex]; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- uint PrimitiveSetIndexedUInt::index(size_t i) const { CVF_TIGHT_ASSERT(m_indices.notNull()); return m_indices->get(i); }
int GeometryTools::intersectLineSegmentTriangle( const cvf::Vec3d p0, const cvf::Vec3d p1, const cvf::Vec3d t0, const cvf::Vec3d t1, const cvf::Vec3d t2, cvf::Vec3d* intersectionPoint , bool * isLineDirDotNormalNegative) { CVF_TIGHT_ASSERT(intersectionPoint != NULL); CVF_TIGHT_ASSERT(isLineDirDotNormalNegative != NULL); cvf::Vec3d u, v, n; // triangle vectors cvf::Vec3d dir, w0, w; // ray vectors double r, a, b; // params to calc ray-plane intersect // get triangle edge vectors and plane normal u = t1 - t0; v = t2 - t0; n = u ^ v; // cross product if (n == cvf::Vec3d::ZERO) // triangle is degenerate return -1; // do not deal with this case dir = p1 - p0; // ray direction vector w0 = p0 - t0; a = -dot(n, w0); b = dot(n, dir); (*isLineDirDotNormalNegative) = (b < 0.0); if (fabs(b) < SMALL_NUM) { // ray is parallel to triangle plane if (a == 0) // ray lies in triangle plane return 2; else return 0; // ray disjoint from plane } // get intersect point of ray with triangle plane r = a / b; if (r < 0.0) // ray goes away from triangle return 0; // => no intersect if (r > 1.0) // Line segment does not reach triangle return 0; *intersectionPoint = p0 + r * dir; // intersect point of ray and plane // is I inside T? double uu, uv, vv, wu, wv, D; uu = dot(u, u); uv = dot(u, v); vv = dot(v, v); w = *intersectionPoint - t0; wu = dot(w, u); wv = dot(w, v); D = uv * uv - uu * vv; // get and test parametric coords double s, t; s = (uv * wv - vv * wu) / D; if (s < 0.0 || s > 1.0) // I is outside T return 0; t = (uv * wu - uu * wv) / D; if (t < 0.0 || (s + t) > 1.0) // I is outside T return 0; return 1; // I is in T }
//-------------------------------------------------------------------------------------------------- /// Gets connectivity for one face in this primitive set /// /// The indices array will be populated with the connectivities for the specified face. /// The connectivity table will have 1, 2, 3 or 4 entries. If this primitive set consists /// of a triangle fan, triangles will be returned. In a similar fashion, if the primitive set /// consist of a quad strip, quads will be returned. //-------------------------------------------------------------------------------------------------- void PrimitiveSet::getFaceIndices(size_t indexOfFace, UIntArray* indices) const { CVF_TIGHT_ASSERT(indexOfFace < faceCount()); CVF_TIGHT_ASSERT(indices); indices->setSizeZero(); if (m_primitiveType == PT_POINTS) { indices->reserve(1); indices->add(index(indexOfFace)); } else if (m_primitiveType == PT_LINES) { indices->reserve(2); indices->add(index(2*indexOfFace)); indices->add(index(2*indexOfFace + 1)); } else if (m_primitiveType == PT_LINE_LOOP) { indices->reserve(2); if (indexOfFace == faceCount() - 1) { indices->add(index(indexOfFace)); indices->add(index(0)); } else { indices->add(index(indexOfFace)); indices->add(index(indexOfFace + 1)); } } else if (m_primitiveType == PT_LINE_STRIP) { indices->reserve(2); indices->add(index(indexOfFace)); indices->add(index(indexOfFace + 1)); } else if (m_primitiveType == PT_TRIANGLES) { indices->reserve(3); const size_t baseIdx = 3*indexOfFace; indices->add(index(baseIdx)); indices->add(index(baseIdx + 1)); indices->add(index(baseIdx + 2)); } else if (m_primitiveType == PT_TRIANGLE_FAN) { indices->reserve(3); indices->add(index(0)); indices->add(index(indexOfFace + 1)); indices->add(index(indexOfFace + 2)); } else if (m_primitiveType == PT_TRIANGLE_STRIP) { indices->reserve(3); if (indexOfFace % 2 == 0) { indices->add(index(indexOfFace)); indices->add(index(indexOfFace + 1)); indices->add(index(indexOfFace + 2)); } else { indices->add(index(indexOfFace + 1)); indices->add(index(indexOfFace)); indices->add(index(indexOfFace + 2)); } } else { CVF_FAIL_MSG("Not implemented"); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector< std::vector<double> > & RigReservoirCellResults::cellScalarResults( size_t scalarResultIndex ) { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); return m_cellScalarResults[scalarResultIndex]; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigReservoirCellResults::timeStepCount(size_t scalarResultIndex) const { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); return m_cellScalarResults[scalarResultIndex].size(); }