LCOV - code coverage report
Current view: top level - libreoffice/svx/source/engine3d - helperhittest3d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 105 0.0 %
Date: 2012-12-27 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <svx/helperhittest3d.hxx>
      22             : #include <basegfx/point/b2dpoint.hxx>
      23             : #include <svx/svdpage.hxx>
      24             : #include <svx/scene3d.hxx>
      25             : #include <svx/svditer.hxx>
      26             : #include <drawinglayer/processor3d/cutfindprocessor3d.hxx>
      27             : #include <svx/sdr/contact/viewcontactofe3d.hxx>
      28             : #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
      29             : #include <com/sun/star/uno/Sequence.h>
      30             : 
      31             : //////////////////////////////////////////////////////////////////////////////
      32             : 
      33             : using namespace com::sun::star;
      34             : 
      35             : //////////////////////////////////////////////////////////////////////////////
      36             : 
      37             : class ImplPairDephAndObject
      38             : {
      39             : private:
      40             :     const E3dCompoundObject*    mpObject;
      41             :     double                      mfDepth;
      42             : 
      43             : public:
      44           0 :     ImplPairDephAndObject(const E3dCompoundObject* pObject, double fDepth)
      45             :     :   mpObject(pObject),
      46           0 :         mfDepth(fDepth)
      47           0 :     {}
      48             : 
      49             :     // for ::std::sort
      50           0 :     bool operator<(const ImplPairDephAndObject& rComp) const
      51             :     {
      52           0 :         return (mfDepth < rComp.mfDepth);
      53             :     }
      54             : 
      55             :     // data read access
      56           0 :     const E3dCompoundObject* getObject() const { return mpObject; }
      57             :     double getDepth() const { return mfDepth; }
      58             : };
      59             : 
      60             : //////////////////////////////////////////////////////////////////////////////
      61             : 
      62           0 : void getAllHit3DObjectWithRelativePoint(
      63             :     const basegfx::B3DPoint& rFront,
      64             :     const basegfx::B3DPoint& rBack,
      65             :     const E3dCompoundObject& rObject,
      66             :     const drawinglayer::geometry::ViewInformation3D& rObjectViewInformation3D,
      67             :     ::std::vector< basegfx::B3DPoint >& o_rResult,
      68             :     bool bAnyHit)
      69             : {
      70           0 :     o_rResult.clear();
      71             : 
      72           0 :     if(!rFront.equal(rBack))
      73             :     {
      74             :         // rObject is a E3dCompoundObject, so it cannot be a scene (which is a E3dObject)
      75           0 :         const sdr::contact::ViewContactOfE3d& rVCObject = static_cast< sdr::contact::ViewContactOfE3d& >(rObject.GetViewContact());
      76           0 :         const drawinglayer::primitive3d::Primitive3DSequence aPrimitives(rVCObject.getViewIndependentPrimitive3DSequence());
      77             : 
      78           0 :         if(aPrimitives.hasElements())
      79             :         {
      80             :             // make BoundVolume empty and overlapping test for speedup
      81           0 :             const basegfx::B3DRange aObjectRange(drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(aPrimitives, rObjectViewInformation3D));
      82             : 
      83           0 :             if(!aObjectRange.isEmpty())
      84             :             {
      85           0 :                 const basegfx::B3DRange aFrontBackRange(rFront, rBack);
      86             : 
      87           0 :                 if(aObjectRange.overlaps(aFrontBackRange))
      88             :                 {
      89             :                     // bound volumes hit, geometric cut tests needed
      90           0 :                     drawinglayer::processor3d::CutFindProcessor aCutFindProcessor(rObjectViewInformation3D, rFront, rBack, bAnyHit);
      91           0 :                     aCutFindProcessor.process(aPrimitives);
      92           0 :                     o_rResult = aCutFindProcessor.getCutPoints();
      93             :                 }
      94             :             }
      95           0 :         }
      96             :     }
      97           0 : }
      98             : 
      99             : //////////////////////////////////////////////////////////////////////////////
     100             : 
     101           0 : E3dScene* fillViewInformation3DForCompoundObject(drawinglayer::geometry::ViewInformation3D& o_rViewInformation3D, const E3dCompoundObject& rCandidate)
     102             : {
     103             :     // Search for root scene (outmost scene) of the 3d object since e.g. in chart, multiple scenes may
     104             :     // be placed between object and outmost scene. On that search, remember the in-between scene's
     105             :     // transformation for the correct complete ObjectTransformation. For historical reasons, the
     106             :     // root scene's own object transformation is part of the scene's ViewTransformation, o do not
     107             :     // add it. For more details, see ViewContactOfE3dScene::createViewInformation3D.
     108           0 :     E3dScene* pParentScene = dynamic_cast< E3dScene* >(rCandidate.GetParentObj());
     109           0 :     E3dScene* pRootScene = 0;
     110           0 :     basegfx::B3DHomMatrix aInBetweenSceneMatrix;
     111             : 
     112           0 :     while(pParentScene)
     113             :     {
     114           0 :         E3dScene* pParentParentScene = dynamic_cast< E3dScene* >(pParentScene->GetParentObj());
     115             : 
     116           0 :         if(pParentParentScene)
     117             :         {
     118             :             // pParentScene is a in-between scene
     119           0 :             aInBetweenSceneMatrix = pParentScene->GetTransform() * aInBetweenSceneMatrix;
     120             :         }
     121             :         else
     122             :         {
     123             :             // pParentScene is the root scene
     124           0 :             pRootScene = pParentScene;
     125             :         }
     126             : 
     127           0 :         pParentScene = pParentParentScene;
     128             :     }
     129             : 
     130           0 :     if(pRootScene)
     131             :     {
     132           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     133             : 
     134           0 :         if(aInBetweenSceneMatrix.isIdentity())
     135             :         {
     136           0 :             o_rViewInformation3D = rVCScene.getViewInformation3D();
     137             :         }
     138             :         else
     139             :         {
     140             :             // build new ViewInformation containing all transforms for the candidate
     141           0 :             const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
     142             : 
     143             :             o_rViewInformation3D = drawinglayer::geometry::ViewInformation3D(
     144           0 :                 aViewInfo3D.getObjectTransformation() * aInBetweenSceneMatrix,
     145           0 :                 aViewInfo3D.getOrientation(),
     146           0 :                 aViewInfo3D.getProjection(),
     147           0 :                 aViewInfo3D.getDeviceToView(),
     148             :                 aViewInfo3D.getViewTime(),
     149           0 :                 aViewInfo3D.getExtendedInformationSequence());
     150             :         }
     151             :     }
     152             :     else
     153             :     {
     154           0 :         const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     155           0 :         o_rViewInformation3D = drawinglayer::geometry::ViewInformation3D(aEmptyParameters);
     156             :     }
     157             : 
     158           0 :     return pRootScene;
     159             : }
     160             : 
     161             : //////////////////////////////////////////////////////////////////////////////
     162             : 
     163           0 : SVX_DLLPUBLIC void getAllHit3DObjectsSortedFrontToBack(
     164             :     const basegfx::B2DPoint& rPoint,
     165             :     const E3dScene& rScene,
     166             :     ::std::vector< const E3dCompoundObject* >& o_rResult)
     167             : {
     168           0 :     o_rResult.clear();
     169           0 :     SdrObjList* pList = rScene.GetSubList();
     170             : 
     171           0 :     if(pList && pList->GetObjCount())
     172             :     {
     173             :         // prepare relative HitPoint. To do so, get the VC of the 3DScene and from there
     174             :         // the Scene's 2D transformation. Multiplying with the inverse transformation
     175             :         // will create a point relative to the 3D scene as unit-2d-object
     176           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rScene.GetViewContact());
     177           0 :         basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
     178           0 :         aInverseSceneTransform.invert();
     179           0 :         const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * rPoint);
     180             : 
     181             :         // check if test point is inside scene's area at all
     182           0 :         if(aRelativePoint.getX() >= 0.0 && aRelativePoint.getX() <= 1.0 && aRelativePoint.getY() >= 0.0 && aRelativePoint.getY() <= 1.0)
     183             :         {
     184           0 :             SdrObjListIter aIterator(*pList, IM_DEEPNOGROUPS);
     185           0 :             ::std::vector< ImplPairDephAndObject > aDepthAndObjectResults;
     186           0 :             const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     187           0 :             drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     188             : 
     189           0 :             while(aIterator.IsMore())
     190             :             {
     191           0 :                 const E3dCompoundObject* pCandidate = dynamic_cast< const E3dCompoundObject* >(aIterator.Next());
     192             : 
     193           0 :                 if(pCandidate)
     194             :                 {
     195           0 :                     fillViewInformation3DForCompoundObject(aViewInfo3D, *pCandidate);
     196             : 
     197             :                     // create HitPoint Front and Back, transform to object coordinates
     198           0 :                     basegfx::B3DHomMatrix aViewToObject(aViewInfo3D.getObjectToView());
     199           0 :                     aViewToObject.invert();
     200           0 :                     const basegfx::B3DPoint aFront(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 0.0));
     201           0 :                     const basegfx::B3DPoint aBack(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 1.0));
     202             : 
     203           0 :                     if(!aFront.equal(aBack))
     204             :                     {
     205             :                         // get all hit points with object
     206           0 :                         ::std::vector< basegfx::B3DPoint > aHitsWithObject;
     207           0 :                         getAllHit3DObjectWithRelativePoint(aFront, aBack, *pCandidate, aViewInfo3D, aHitsWithObject, false);
     208             : 
     209           0 :                         for(sal_uInt32 a(0); a < aHitsWithObject.size(); a++)
     210             :                         {
     211           0 :                             const basegfx::B3DPoint aPointInViewCoordinates(aViewInfo3D.getObjectToView() * aHitsWithObject[a]);
     212           0 :                             aDepthAndObjectResults.push_back(ImplPairDephAndObject(pCandidate, aPointInViewCoordinates.getZ()));
     213           0 :                         }
     214           0 :                     }
     215             :                 }
     216             :             }
     217             : 
     218             :             // fill nRetval
     219           0 :             const sal_uInt32 nCount(aDepthAndObjectResults.size());
     220             : 
     221           0 :             if(nCount)
     222             :             {
     223             :                 // sort aDepthAndObjectResults by depth
     224           0 :                 ::std::sort(aDepthAndObjectResults.begin(), aDepthAndObjectResults.end());
     225             : 
     226             :                 // copy SdrObject pointers to return result set
     227           0 :                 ::std::vector< ImplPairDephAndObject >::iterator aIterator2(aDepthAndObjectResults.begin());
     228             : 
     229           0 :                 for(;aIterator2 != aDepthAndObjectResults.end(); ++aIterator2)
     230             :                 {
     231           0 :                     o_rResult.push_back(aIterator2->getObject());
     232             :                 }
     233           0 :             }
     234           0 :         }
     235             :     }
     236           0 : }
     237             : 
     238             : //////////////////////////////////////////////////////////////////////////////
     239             : 
     240           0 : bool checkHitSingle3DObject(
     241             :     const basegfx::B2DPoint& rPoint,
     242             :     const E3dCompoundObject& rCandidate)
     243             : {
     244           0 :     const uno::Sequence< beans::PropertyValue > aEmptyParameters;
     245           0 :     drawinglayer::geometry::ViewInformation3D aViewInfo3D(aEmptyParameters);
     246           0 :     E3dScene* pRootScene = fillViewInformation3DForCompoundObject(aViewInfo3D, rCandidate);
     247             : 
     248           0 :     if(pRootScene)
     249             :     {
     250             :         // prepare relative HitPoint. To do so, get the VC of the 3DScene and from there
     251             :         // the Scene's 2D transformation. Multiplying with the inverse transformation
     252             :         // will create a point relative to the 3D scene as unit-2d-object
     253           0 :         const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pRootScene->GetViewContact());
     254           0 :         basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
     255           0 :         aInverseSceneTransform.invert();
     256           0 :         const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * rPoint);
     257             : 
     258             :         // check if test point is inside scene's area at all
     259           0 :         if(aRelativePoint.getX() >= 0.0 && aRelativePoint.getX() <= 1.0 && aRelativePoint.getY() >= 0.0 && aRelativePoint.getY() <= 1.0)
     260             :         {
     261             :             // create HitPoint Front and Back, transform to object coordinates
     262           0 :             basegfx::B3DHomMatrix aViewToObject(aViewInfo3D.getObjectToView());
     263           0 :             aViewToObject.invert();
     264           0 :             const basegfx::B3DPoint aFront(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 0.0));
     265           0 :             const basegfx::B3DPoint aBack(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 1.0));
     266             : 
     267           0 :             if(!aFront.equal(aBack))
     268             :             {
     269             :                 // get all hit points with object
     270           0 :                 ::std::vector< basegfx::B3DPoint > aHitsWithObject;
     271           0 :                 getAllHit3DObjectWithRelativePoint(aFront, aBack, rCandidate, aViewInfo3D, aHitsWithObject, true);
     272             : 
     273           0 :                 if(!aHitsWithObject.empty())
     274             :                 {
     275           0 :                     return true;
     276           0 :                 }
     277           0 :             }
     278           0 :         }
     279             :     }
     280             : 
     281           0 :     return false;
     282             : }
     283             : 
     284             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10