///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2018- Equinor ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RiuPickItemInfo.h" #include "cvfDrawableGeo.h" #include "cvfEffect.h" #include "cvfHitItem.h" #include "cvfHitItemCollection.h" #include "cvfPart.h" #include "cvfRenderState.h" #include "cvfRenderStatePolygonOffset.h" #include "cvfTransform.h" #include double RiuPickItemInfo::sm_rayDistanceTolerance = 1e-5; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RiuPickItemInfo RiuPickItemInfo::extractPickItemInfo( const cvf::HitItem* hitItem ) { RiuPickItemInfo pickInfo; pickInfo.m_pickedPart = hitItem->part(); pickInfo.m_globalPickedPoint = hitItem->intersectionPoint(); pickInfo.m_distanceAlongRay = hitItem->distanceAlongRay(); if ( pickInfo.m_pickedPart ) pickInfo.m_sourceInfo = pickInfo.m_pickedPart->sourceInfo(); const cvf::HitDetailDrawableGeo* detail = dynamic_cast( hitItem->detail() ); if ( detail ) pickInfo.m_faceIdx = detail->faceIndex(); pickInfo.m_localPickedPoint = pickInfo.m_globalPickedPoint; const cvf::Transform* xf = pickInfo.m_pickedPart->transform(); if ( xf ) { pickInfo.m_localPickedPoint.transformPoint( xf->worldTransform().getInverted() ); } return pickInfo; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RiuPickItemInfo::convertToPickItemInfos( const cvf::HitItemCollection& hitItems, const cvf::Vec3d& globalRayOrigin, double coincidentRayDistanceTolerance ) { sm_rayDistanceTolerance = coincidentRayDistanceTolerance; std::set pickItemInfosSorted; for ( size_t i = 0; i < hitItems.count(); i++ ) { pickItemInfosSorted.insert( RiuPickItemInfo( hitItems.item( i ), globalRayOrigin ) ); } std::vector pickItemInfos; pickItemInfos.insert( pickItemInfos.begin(), pickItemInfosSorted.begin(), pickItemInfosSorted.end() ); return pickItemInfos; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- float RiuPickItemInfo::polygonOffsetUnit() const { float polyOffsetUnit = 0; if ( m_pickedPart ) { cvf::Effect* eff = const_cast( m_pickedPart )->effect(); if ( eff ) { cvf::RenderState* rendState = eff->renderStateOfType( cvf::RenderState::POLYGON_OFFSET ); if ( rendState ) { auto polyOffsetRenderState = static_cast( rendState ); polyOffsetUnit = polyOffsetRenderState->units(); } } } return polyOffsetUnit; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RiuPickItemInfo::operator<( const RiuPickItemInfo& other ) const { if ( fabs( m_distanceAlongRay - other.distanceAlongRay() ) > sm_rayDistanceTolerance ) { return m_distanceAlongRay < other.distanceAlongRay(); } else if ( this->polygonOffsetUnit() != other.polygonOffsetUnit() ) { return this->polygonOffsetUnit() < other.polygonOffsetUnit(); } else if ( m_faceIdx != other.faceIdx() ) { return m_faceIdx < other.faceIdx(); } else if ( m_pickedPart != other.pickedPart() ) { return m_pickedPart < other.pickedPart(); } return false; }