///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2011- Statoil ASA // Copyright (C) 2013- Ceetron Solutions AS // Copyright (C) 2011-2012 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RivTextAnnotationPartMgr.h" #include "RiaBoundingBoxTools.h" #include "RiaColorTools.h" #include "RiaFontCache.h" #include "RiaPreferences.h" #include "Rim3dView.h" #include "RimAnnotationInViewCollection.h" #include "RimAnnotationTextAppearance.h" #include "RimTextAnnotation.h" #include "RimTextAnnotationInView.h" #include "RivObjectSourceInfo.h" #include "RivPartPriority.h" #include "RivPolylineGenerator.h" #include "cafDisplayCoordTransform.h" #include "cafEffectGenerator.h" #include "cafFixedAtlasFont.h" #include "cvfDrawableGeo.h" #include "cvfDrawableText.h" #include "cvfModelBasicList.h" #include "cvfPart.h" #include "cvfqtUtils.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivTextAnnotationPartMgr::RivTextAnnotationPartMgr( Rim3dView* view, RimTextAnnotation* annotationLocal ) : m_rimView( view ) , m_rimAnnotationLocal( annotationLocal ) , m_rimAnnotationInView( nullptr ) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivTextAnnotationPartMgr::RivTextAnnotationPartMgr( Rim3dView* view, RimTextAnnotationInView* annotationInView ) : m_rimView( view ) , m_rimAnnotationLocal( nullptr ) , m_rimAnnotationInView( annotationInView ) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivTextAnnotationPartMgr::~RivTextAnnotationPartMgr() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTextAnnotationPartMgr::buildParts( const caf::DisplayCoordTransform* displayXf, bool doFlatten, double xOffset ) { clearAllGeometry(); auto collection = annotationCollection(); if ( !collection ) return; cvf::Vec3d anchorPositionInDomain = getAnchorPointInDomain( collection->snapAnnotations(), collection->annotationPlaneZ() ); cvf::Vec3d labelPositionInDomain = getLabelPointInDomain( collection->snapAnnotations(), collection->annotationPlaneZ() ); cvf::Vec3d anchorPosition = displayXf->transformToDisplayCoord( anchorPositionInDomain ); cvf::Vec3d labelPosition = displayXf->transformToDisplayCoord( labelPositionInDomain ); QString text = rimAnnotation()->text(); auto fontSize = rimAnnotation()->appearance()->fontSize(); auto fontColor = rimAnnotation()->appearance()->fontColor(); auto backgroundColor = rimAnnotation()->appearance()->backgroundColor(); auto anchorLineColor = rimAnnotation()->appearance()->anchorLineColor(); // Line part { std::vector points = { anchorPosition, labelPosition }; cvf::ref drawableGeo = RivPolylineGenerator::createLineAlongPolylineDrawable( points ); cvf::ref part = new cvf::Part; part->setName( "RivTextAnnotationPartMgr" ); part->setDrawable( drawableGeo.p() ); caf::MeshEffectGenerator colorEffgen( anchorLineColor ); cvf::ref eff = colorEffgen.generateUnCachedEffect(); part->setEffect( eff.p() ); part->setPriority( RivPartPriority::PartType::MeshLines ); part->setSourceInfo( new RivObjectSourceInfo( rimAnnotation() ) ); m_linePart = part; } // Text part { auto font = RiaFontCache::getFont( fontSize ); cvf::ref drawableText = new cvf::DrawableText; drawableText->setFont( font.p() ); drawableText->setCheckPosVisible( false ); drawableText->setUseDepthBuffer( true ); drawableText->setDrawBorder( true ); drawableText->setDrawBackground( true ); drawableText->setVerticalAlignment( cvf::TextDrawer::BASELINE ); drawableText->setBackgroundColor( backgroundColor ); drawableText->setBorderColor( RiaColorTools::computeOffsetColor( backgroundColor, 0.3f ) ); drawableText->setTextColor( fontColor ); cvf::String cvfString = cvfqt::Utils::toString( text ); cvf::Vec3f textCoord( labelPosition ); drawableText->addText( cvfString, textCoord ); cvf::ref part = new cvf::Part; part->setName( "RivTextAnnotationPartMgr: " + cvfString ); part->setDrawable( drawableText.p() ); cvf::ref eff = new cvf::Effect(); part->setEffect( eff.p() ); part->setPriority( RivPartPriority::PartType::MeshLines ); m_labelPart = part; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivTextAnnotationPartMgr::Vec3d RivTextAnnotationPartMgr::getAnchorPointInDomain( bool snapToPlaneZ, double planeZ ) { auto pt = rimAnnotation()->anchorPoint(); if ( snapToPlaneZ ) { pt.z() = planeZ; } return pt; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivTextAnnotationPartMgr::Vec3d RivTextAnnotationPartMgr::getLabelPointInDomain( bool snapToPlaneZ, double planeZ ) { auto pt = rimAnnotation()->labelPoint(); if ( snapToPlaneZ ) { pt.z() = planeZ; } return pt; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RivTextAnnotationPartMgr::isTextInBoundingBox( const cvf::BoundingBox& boundingBox ) { auto coll = annotationCollection(); if ( !coll ) return false; auto effectiveBoundingBox = RiaBoundingBoxTools::inflate( boundingBox, 3 ); if ( effectiveBoundingBox.contains( getAnchorPointInDomain( coll->snapAnnotations(), coll->annotationPlaneZ() ) ) || effectiveBoundingBox.contains( getLabelPointInDomain( coll->snapAnnotations(), coll->annotationPlaneZ() ) ) ) return true; return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTextAnnotationPartMgr::clearAllGeometry() { m_linePart = nullptr; m_labelPart = nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTextAnnotationPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayXf, const cvf::BoundingBox& boundingBox ) { if ( !rimAnnotation() || !isAnnotationVisible() ) return; // Check bounding box if ( !isTextInBoundingBox( boundingBox ) ) return; if ( !validateAnnotation( rimAnnotation() ) ) return; buildParts( displayXf, false, 0.0 ); model->addPart( m_linePart.p() ); model->addPart( m_labelPart.p() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RivTextAnnotationPartMgr::validateAnnotation( const RimTextAnnotation* annotation ) const { return rimAnnotation()->anchorPoint() != cvf::Vec3d::ZERO && !rimAnnotation()->text().isEmpty(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimAnnotationInViewCollection* RivTextAnnotationPartMgr::annotationCollection() const { std::vector colls; m_rimView->descendantsIncludingThisOfType( colls ); return !colls.empty() ? colls.front() : nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimTextAnnotation* RivTextAnnotationPartMgr::rimAnnotation() const { if ( m_rimAnnotationLocal ) return m_rimAnnotationLocal; return m_rimAnnotationInView->sourceAnnotation(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RivTextAnnotationPartMgr::isAnnotationVisible() const { if ( m_rimAnnotationLocal ) return m_rimAnnotationLocal->isVisible(); if ( m_rimAnnotationInView ) return m_rimAnnotationInView->isVisible(); return false; }