LCOV - code coverage report
Current view: top level - chart2/source/tools - ThreeDHelper.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 446 771 57.8 %
Date: 2014-04-11 Functions: 42 50 84.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             : #include "ThreeDHelper.hxx"
      21             : #include "macros.hxx"
      22             : #include "DiagramHelper.hxx"
      23             : #include "ChartTypeHelper.hxx"
      24             : #include "BaseGFXHelper.hxx"
      25             : #include "DataSeriesHelper.hxx"
      26             : #include "defines.hxx"
      27             : 
      28             : #include <editeng/unoprnms.hxx>
      29             : #include <com/sun/star/beans/XPropertyState.hpp>
      30             : #include <com/sun/star/chart2/XDiagram.hpp>
      31             : #include <com/sun/star/drawing/LineStyle.hpp>
      32             : 
      33             : namespace chart
      34             : {
      35             : using namespace ::com::sun::star;
      36             : using namespace ::com::sun::star::chart2;
      37             : 
      38             : using ::com::sun::star::uno::Reference;
      39             : using ::com::sun::star::uno::Sequence;
      40             : using ::rtl::math::cos;
      41             : using ::rtl::math::sin;
      42             : using ::rtl::math::tan;
      43             : 
      44             : namespace
      45             : {
      46             : 
      47         214 : bool lcl_isRightAngledAxesSetAndSupported( const Reference< beans::XPropertySet >& xSceneProperties )
      48             : {
      49         214 :     sal_Bool bRightAngledAxes = sal_False;
      50         214 :     if( xSceneProperties.is() )
      51             :     {
      52         214 :         xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
      53         214 :         if(bRightAngledAxes)
      54             :         {
      55         174 :             uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
      56         348 :             if( ChartTypeHelper::isSupportingRightAngledAxes(
      57         348 :                     DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
      58             :             {
      59         174 :                 return true;
      60           0 :             }
      61             :         }
      62             :     }
      63          40 :     return false;
      64             : }
      65             : 
      66          96 : void lcl_RotateLightSource( const Reference< beans::XPropertySet >& xSceneProperties
      67             :                            , const OUString& rLightSourceDirection
      68             :                            , const OUString& rLightSourceOn
      69             :                            , const ::basegfx::B3DHomMatrix& rRotationMatrix )
      70             : {
      71          96 :     if( xSceneProperties.is() )
      72             :     {
      73          96 :         sal_Bool bLightOn = sal_False;
      74          96 :         if( xSceneProperties->getPropertyValue( rLightSourceOn ) >>= bLightOn )
      75             :         {
      76          96 :             if( bLightOn )
      77             :             {
      78          12 :                 drawing::Direction3D aLight;
      79          12 :                 if( xSceneProperties->getPropertyValue( rLightSourceDirection ) >>= aLight )
      80             :                 {
      81          12 :                     ::basegfx::B3DVector aLightVector( BaseGFXHelper::Direction3DToB3DVector( aLight ) );
      82          12 :                     aLightVector = rRotationMatrix*aLightVector;
      83             : 
      84          12 :                     xSceneProperties->setPropertyValue( rLightSourceDirection
      85          12 :                         , uno::makeAny( BaseGFXHelper::B3DVectorToDirection3D( aLightVector ) ) );
      86             :                 }
      87             :             }
      88             :         }
      89             :     }
      90          96 : }
      91             : 
      92          12 : void lcl_rotateLights( const ::basegfx::B3DHomMatrix& rLightRottion, const Reference< beans::XPropertySet >& xSceneProperties )
      93             : {
      94          12 :     if(!xSceneProperties.is())
      95          12 :         return;
      96             : 
      97          12 :     ::basegfx::B3DHomMatrix aLightRottion( rLightRottion );
      98          12 :     BaseGFXHelper::ReduceToRotationMatrix( aLightRottion );
      99             : 
     100          12 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection1", "D3DSceneLightOn1", aLightRottion );
     101          12 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection2", "D3DSceneLightOn2", aLightRottion );
     102          12 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection3", "D3DSceneLightOn3", aLightRottion );
     103          12 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection4", "D3DSceneLightOn4", aLightRottion );
     104          12 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection5", "D3DSceneLightOn5", aLightRottion );
     105          12 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection6", "D3DSceneLightOn6", aLightRottion );
     106          12 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection7", "D3DSceneLightOn7", aLightRottion );
     107          12 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection8", "D3DSceneLightOn8", aLightRottion );
     108             : }
     109             : 
     110          60 : ::basegfx::B3DHomMatrix lcl_getInverseRotationMatrix( const Reference< beans::XPropertySet >& xSceneProperties )
     111             : {
     112          60 :     ::basegfx::B3DHomMatrix aInverseRotation;
     113          60 :     double fXAngleRad=0.0;
     114          60 :     double fYAngleRad=0.0;
     115          60 :     double fZAngleRad=0.0;
     116             :     ThreeDHelper::getRotationAngleFromDiagram(
     117          60 :         xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
     118          60 :     aInverseRotation.rotate( 0.0, 0.0, -fZAngleRad );
     119          60 :     aInverseRotation.rotate( 0.0, -fYAngleRad, 0.0 );
     120          60 :     aInverseRotation.rotate( -fXAngleRad, 0.0, 0.0 );
     121          60 :     return aInverseRotation;
     122             : }
     123             : 
     124           0 : ::basegfx::B3DHomMatrix lcl_getCompleteRotationMatrix( const Reference< beans::XPropertySet >& xSceneProperties )
     125             : {
     126           0 :     ::basegfx::B3DHomMatrix aCompleteRotation;
     127           0 :     double fXAngleRad=0.0;
     128           0 :     double fYAngleRad=0.0;
     129           0 :     double fZAngleRad=0.0;
     130             :     ThreeDHelper::getRotationAngleFromDiagram(
     131           0 :         xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
     132           0 :     aCompleteRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
     133           0 :     return aCompleteRotation;
     134             : }
     135             : 
     136          11 : bool lcl_isEqual( const drawing::Direction3D& rA, const drawing::Direction3D& rB )
     137             : {
     138          11 :     return ::rtl::math::approxEqual(rA.DirectionX, rB.DirectionX)
     139          11 :         && ::rtl::math::approxEqual(rA.DirectionY, rB.DirectionY)
     140          22 :         && ::rtl::math::approxEqual(rA.DirectionZ, rB.DirectionZ);
     141             : }
     142             : 
     143          11 : bool lcl_isLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, bool bRealistic )
     144             : {
     145          11 :     if(!xDiagramProps.is())
     146           0 :         return false;
     147             : 
     148          11 :     sal_Bool bIsOn = sal_False;
     149          11 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2 ) >>= bIsOn;
     150          11 :     if(!bIsOn)
     151           0 :         return false;
     152             : 
     153          11 :     uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
     154          22 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     155             : 
     156          11 :     sal_Int32 nColor = 0;
     157          11 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2 ) >>= nColor;
     158          11 :     if( nColor != ::chart::ChartTypeHelper::getDefaultDirectLightColor( !bRealistic, xChartType ) )
     159           0 :         return false;
     160             : 
     161          11 :     sal_Int32 nAmbientColor = 0;
     162          11 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR ) >>= nAmbientColor;
     163          11 :     if( nAmbientColor != ::chart::ChartTypeHelper::getDefaultAmbientLightColor( !bRealistic, xChartType ) )
     164           0 :         return false;
     165             : 
     166          11 :     drawing::Direction3D aDirection(0,0,0);
     167          11 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2 ) >>= aDirection;
     168             : 
     169             :     drawing::Direction3D aDefaultDirection( bRealistic
     170             :         ? ChartTypeHelper::getDefaultRealisticLightDirection(xChartType)
     171          11 :         : ChartTypeHelper::getDefaultSimpleLightDirection(xChartType) );
     172             : 
     173             :     //rotate default light direction when right angled axes are off but supported
     174             :     {
     175          11 :         sal_Bool bRightAngledAxes = sal_False;
     176          11 :         xDiagramProps->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
     177          11 :         if(!bRightAngledAxes)
     178             :         {
     179           0 :             if( ChartTypeHelper::isSupportingRightAngledAxes(
     180           0 :                     DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
     181             :             {
     182           0 :                 ::basegfx::B3DHomMatrix aRotation( lcl_getCompleteRotationMatrix( xDiagramProps ) );
     183           0 :                 BaseGFXHelper::ReduceToRotationMatrix( aRotation );
     184           0 :                 ::basegfx::B3DVector aLightVector( BaseGFXHelper::Direction3DToB3DVector( aDefaultDirection ) );
     185           0 :                 aLightVector = aRotation*aLightVector;
     186           0 :                 aDefaultDirection = BaseGFXHelper::B3DVectorToDirection3D( aLightVector );
     187             :             }
     188             :         }
     189             :     }
     190             : 
     191          22 :     return lcl_isEqual( aDirection, aDefaultDirection );
     192             : }
     193             : 
     194          11 : bool lcl_isRealisticLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps )
     195             : {
     196          11 :     return lcl_isLightScheme( xDiagramProps, true /*bRealistic*/ );
     197             : }
     198           0 : bool lcl_isSimpleLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps )
     199             : {
     200           0 :     return lcl_isLightScheme( xDiagramProps, false /*bRealistic*/ );
     201             : }
     202         145 : void lcl_setLightsForScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, const ThreeDLookScheme& rScheme )
     203             : {
     204         145 :     if(!xDiagramProps.is())
     205           0 :         return;
     206         145 :     if( rScheme == ThreeDLookScheme_Unknown)
     207           0 :         return;
     208             : 
     209         145 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2, uno::makeAny( sal_True ) );
     210             : 
     211         145 :     uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
     212         290 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     213         145 :     uno::Any aADirection( uno::makeAny( rScheme == ThreeDLookScheme_Simple
     214             :         ? ChartTypeHelper::getDefaultSimpleLightDirection(xChartType)
     215         290 :         : ChartTypeHelper::getDefaultRealisticLightDirection(xChartType) ) );
     216             : 
     217         145 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2, aADirection );
     218             :     //rotate light direction when right angled axes are off but supported
     219             :     {
     220         145 :         sal_Bool bRightAngledAxes = sal_False;
     221         145 :         xDiagramProps->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
     222         145 :         if(!bRightAngledAxes)
     223             :         {
     224           0 :             if( ChartTypeHelper::isSupportingRightAngledAxes( xChartType ) )
     225             :             {
     226           0 :                 ::basegfx::B3DHomMatrix aRotation( lcl_getCompleteRotationMatrix( xDiagramProps ) );
     227           0 :                 BaseGFXHelper::ReduceToRotationMatrix( aRotation );
     228           0 :                 lcl_RotateLightSource( xDiagramProps, "D3DSceneLightDirection2", "D3DSceneLightOn2", aRotation );
     229             :             }
     230             :         }
     231             :     }
     232             : 
     233         145 :     sal_Int32 nColor = ::chart::ChartTypeHelper::getDefaultDirectLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
     234         145 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2, uno::makeAny( nColor ) );
     235             : 
     236         145 :     sal_Int32 nAmbientColor = ::chart::ChartTypeHelper::getDefaultAmbientLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
     237         290 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR, uno::makeAny( nAmbientColor ) );
     238             : }
     239             : 
     240          13 : bool lcl_isRealisticScheme( drawing::ShadeMode aShadeMode
     241             :                     , sal_Int32 nRoundedEdges
     242             :                     , sal_Int32 nObjectLines )
     243             : {
     244          13 :     if(aShadeMode!=drawing::ShadeMode_SMOOTH)
     245           0 :         return false;
     246          13 :     if(nRoundedEdges!=5)
     247           2 :         return false;
     248          11 :     if(nObjectLines!=0)
     249           0 :         return false;
     250          11 :     return true;
     251             : }
     252             : 
     253          13 : bool lcl_isSimpleScheme( drawing::ShadeMode aShadeMode
     254             :                     , sal_Int32 nRoundedEdges
     255             :                     , sal_Int32 nObjectLines
     256             :                     , const uno::Reference< XDiagram >& xDiagram )
     257             : {
     258          13 :     if(aShadeMode!=drawing::ShadeMode_FLAT)
     259          13 :         return false;
     260           0 :     if(nRoundedEdges!=0)
     261           0 :         return false;
     262           0 :     if(nObjectLines==0)
     263             :     {
     264           0 :         uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     265           0 :         return ChartTypeHelper::noBordersForSimpleScheme( xChartType );
     266             :     }
     267           0 :     if(nObjectLines!=1)
     268           0 :         return false;
     269           0 :     return true;
     270             : }
     271             : 
     272         145 : void lcl_setRealisticScheme( drawing::ShadeMode& rShadeMode
     273             :                     , sal_Int32& rnRoundedEdges
     274             :                     , sal_Int32& rnObjectLines )
     275             : {
     276         145 :     rShadeMode = drawing::ShadeMode_SMOOTH;
     277         145 :     rnRoundedEdges = 5;
     278         145 :     rnObjectLines = 0;
     279         145 : }
     280             : 
     281           0 : void lcl_setSimpleScheme( drawing::ShadeMode& rShadeMode
     282             :                     , sal_Int32& rnRoundedEdges
     283             :                     , sal_Int32& rnObjectLines
     284             :                     , const uno::Reference< XDiagram >& xDiagram )
     285             : {
     286           0 :     rShadeMode = drawing::ShadeMode_FLAT;
     287           0 :     rnRoundedEdges = 0;
     288             : 
     289           0 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     290           0 :     rnObjectLines = ChartTypeHelper::noBordersForSimpleScheme( xChartType ) ? 0 : 1;
     291           0 : }
     292             : 
     293             : } //end anonymous namespace
     294             : 
     295         676 : drawing::CameraGeometry ThreeDHelper::getDefaultCameraGeometry( bool bPie )
     296             : {
     297             :     // ViewReferencePoint (Point on the View plane)
     298         676 :     drawing::Position3D vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
     299             :     // ViewPlaneNormal (Normal to the View Plane)
     300         676 :     drawing::Direction3D vpn(0.416199821709347, 0.173649045905254, 0.892537795986984);
     301             :     // ViewUpVector (determines the v-axis direction on the view plane as
     302             :     // projection of VUP parallel to VPN onto th view pane)
     303         676 :     drawing::Direction3D vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
     304             : 
     305         676 :     if( bPie )
     306             :     {
     307          11 :         vrp = drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspecitve
     308          11 :         vpn = drawing::Direction3D( 0.0, 0.0, 1.0 );
     309          11 :         vup = drawing::Direction3D( 0.0, 1.0, 0.0 );
     310             :     }
     311             : 
     312         676 :     return drawing::CameraGeometry( vrp, vpn, vup );
     313             : }
     314             : 
     315             : namespace
     316             : {
     317         286 : ::basegfx::B3DHomMatrix lcl_getCameraMatrix( const uno::Reference< beans::XPropertySet >& xSceneProperties )
     318             : {
     319         286 :     drawing::HomogenMatrix aCameraMatrix;
     320             : 
     321         286 :     drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
     322         286 :     if( xSceneProperties.is() )
     323         286 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
     324             : 
     325         286 :     ::basegfx::B3DVector aVPN( BaseGFXHelper::Direction3DToB3DVector( aCG.vpn ) );
     326         572 :     ::basegfx::B3DVector aVUP( BaseGFXHelper::Direction3DToB3DVector( aCG.vup ) );
     327             : 
     328             :     //normalize vectors:
     329         286 :     aVPN.normalize();
     330         286 :     aVUP.normalize();
     331             : 
     332         572 :     ::basegfx::B3DVector aCross = ::basegfx::cross( aVUP, aVPN );
     333             : 
     334             :     //first line is VUP x VPN
     335         286 :     aCameraMatrix.Line1.Column1 = aCross[0];
     336         286 :     aCameraMatrix.Line1.Column2 = aCross[1];
     337         286 :     aCameraMatrix.Line1.Column3 = aCross[2];
     338         286 :     aCameraMatrix.Line1.Column4 = 0.0;
     339             : 
     340             :     //second line is VUP
     341         286 :     aCameraMatrix.Line2.Column1 = aVUP[0];
     342         286 :     aCameraMatrix.Line2.Column2 = aVUP[1];
     343         286 :     aCameraMatrix.Line2.Column3 = aVUP[2];
     344         286 :     aCameraMatrix.Line2.Column4 = 0.0;
     345             : 
     346             :     //third line is VPN
     347         286 :     aCameraMatrix.Line3.Column1 = aVPN[0];
     348         286 :     aCameraMatrix.Line3.Column2 = aVPN[1];
     349         286 :     aCameraMatrix.Line3.Column3 = aVPN[2];
     350         286 :     aCameraMatrix.Line3.Column4 = 0.0;
     351             : 
     352             :     //fourth line is 0 0 0 1
     353         286 :     aCameraMatrix.Line4.Column1 = 0.0;
     354         286 :     aCameraMatrix.Line4.Column2 = 0.0;
     355         286 :     aCameraMatrix.Line4.Column3 = 0.0;
     356         286 :     aCameraMatrix.Line4.Column4 = 1.0;
     357             : 
     358         572 :     return BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aCameraMatrix );
     359             : }
     360             : 
     361         678 : double lcl_shiftAngleToIntervalMinusPiToPi( double fAngleRad )
     362             : {
     363             :     //valid range:  ]-Pi,Pi]
     364        1356 :     while( fAngleRad<=-F_PI )
     365           0 :         fAngleRad+=(2*F_PI);
     366        1356 :     while( fAngleRad>F_PI )
     367           0 :         fAngleRad-=(2*F_PI);
     368         678 :     return fAngleRad;
     369             : }
     370             : 
     371         164 : void lcl_shiftAngleToIntervalMinus180To180( sal_Int32& rnAngleDegree )
     372             : {
     373             :     //valid range:  ]-180,180]
     374         328 :     while( rnAngleDegree<=-180 )
     375           0 :         rnAngleDegree+=360;
     376         328 :     while( rnAngleDegree>180 )
     377           0 :         rnAngleDegree-=360;
     378         164 : }
     379             : 
     380          24 : void lcl_shiftAngleToIntervalZeroTo360( sal_Int32& rnAngleDegree )
     381             : {
     382             :     //valid range:  [0,360[
     383          54 :     while( rnAngleDegree<0 )
     384           6 :         rnAngleDegree+=360;
     385          48 :     while( rnAngleDegree>=360 )
     386           0 :         rnAngleDegree-=360;
     387          24 : }
     388             : 
     389           0 : void lcl_ensureIntervalMinus1To1( double& rSinOrCos )
     390             : {
     391           0 :     if (rSinOrCos < -1.0)
     392           0 :        rSinOrCos = -1.0;
     393           0 :     else if (rSinOrCos > 1.0)
     394           0 :         rSinOrCos = 1.0;
     395           0 : }
     396             : 
     397          48 : bool lcl_isSinZero( double fAngleRad )
     398             : {
     399          48 :     return ::basegfx::fTools::equalZero( sin(fAngleRad), 0.0000001 );
     400             : }
     401          28 : bool lcl_isCosZero( double fAngleRad )
     402             : {
     403          28 :     return ::basegfx::fTools::equalZero( cos(fAngleRad), 0.0000001 );
     404             : }
     405             : 
     406             : }
     407             : 
     408          12 : void ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
     409             :     sal_Int32 nElevationDeg, sal_Int32 nRotationDeg,
     410             :     double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad)
     411             : {
     412             :     // for a description of the algorithm see issue 72994
     413             :     //http://www.openoffice.org/issues/show_bug.cgi?id=72994
     414             :     //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
     415             : 
     416          12 :     lcl_shiftAngleToIntervalZeroTo360( nElevationDeg );
     417          12 :     lcl_shiftAngleToIntervalZeroTo360( nRotationDeg );
     418             : 
     419          12 :     double& x = rfXAngleRad;
     420          12 :     double& y = rfYAngleRad;
     421          12 :     double& z = rfZAngleRad;
     422             : 
     423          12 :     double E = F_PI*nElevationDeg/180; //elevation in Rad
     424          12 :     double R = F_PI*nRotationDeg/180; //rotation in Rad
     425             : 
     426          12 :     if( (nRotationDeg == 0 || nRotationDeg == 180 )
     427          12 :         && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
     428             :     {
     429             :         //sR==0 && cE==0
     430           0 :         z = 0.0;
     431             :         //element 23
     432           0 :         double f23 = cos(R)*sin(E);
     433           0 :         if(f23>0)
     434           0 :             x = F_PI/2;
     435             :         else
     436           0 :             x = -F_PI/2;
     437           0 :         y = R;
     438             :     }
     439          12 :     else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
     440           0 :         && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
     441             :     {
     442             :         //cR==0 && cE==0
     443           0 :         z = F_PI/2;
     444           0 :         if( sin(R)>0 )
     445           0 :             x = F_PI/2.0;
     446             :         else
     447           0 :             x = -F_PI/2.0;
     448             : 
     449           0 :         if( (sin(R)*sin(E))>0 )
     450           0 :             y = 0.0;
     451             :         else
     452           0 :             y = F_PI;
     453             :     }
     454          12 :     else if( (nRotationDeg == 0 || nRotationDeg == 180 )
     455          12 :         && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
     456             :     {
     457             :         //sR==0 && sE==0
     458           0 :         z = 0.0;
     459           0 :         y = R;
     460           0 :         x = E;
     461             :     }
     462          12 :     else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
     463           0 :         && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
     464             :     {
     465             :         //cR==0 && sE==0
     466           0 :         z = 0.0;
     467             : 
     468           0 :         if( (sin(R)/cos(E))>0 )
     469           0 :             y = F_PI/2;
     470             :         else
     471           0 :             y = -F_PI/2;
     472             : 
     473           0 :         if( (cos(E))>0 )
     474           0 :             x = 0;
     475             :         else
     476           0 :             x = F_PI;
     477             :     }
     478          12 :     else if ( nElevationDeg == 0 || nElevationDeg == 180 )
     479             :     {
     480             :         //sR!=0 cR!=0 sE==0
     481           0 :         z = 0.0;
     482           0 :         x = E;
     483           0 :         y = R;
     484             :         //use element 13 for sign
     485           0 :         if((cos(x)*sin(y)*sin(R))<0.0)
     486           0 :             y *= -1.0;
     487             :     }
     488          12 :     else if ( nElevationDeg == 90 || nElevationDeg == 270 )
     489             :     {
     490             :         //sR!=0 cR!=0 cE==0
     491             :         //element 12 + 22 --> y=0 or F_PI and x=+-F_PI/2
     492             :         //-->element 13/23:
     493           0 :         z = atan(sin(R)/(cos(R)*sin(E)));
     494             :         //use element 13 for sign for x
     495           0 :         if( (sin(R)*sin(z))>0.0 )
     496           0 :             x = F_PI/2;
     497             :         else
     498           0 :             x = -F_PI/2;
     499             :         //use element 21 for y
     500           0 :         if( (sin(R)*sin(E)*sin(z))>0.0)
     501           0 :             y = 0.0;
     502             :         else
     503           0 :             y = F_PI;
     504             :     }
     505          12 :     else if ( nRotationDeg == 0 || nRotationDeg == 180 )
     506             :     {
     507             :         //sE!=0 cE!=0 sR==0
     508          12 :         z = 0.0;
     509          12 :         x = E;
     510          12 :         y = R;
     511          12 :         double f23 = cos(R)*sin(E);
     512          12 :         if( (f23 * sin(x)) < 0.0 )
     513           0 :             x *= -1.0; //todo ??
     514             :     }
     515           0 :     else if (nRotationDeg == 90 || nRotationDeg == 270)
     516             :     {
     517             :         //sE!=0 cE!=0 cR==0
     518             :         //z = +- F_PI/2;
     519             :         //x = +- F_PI/2;
     520           0 :         z = F_PI/2;
     521           0 :         x = F_PI/2;
     522           0 :         double sR = sin(R);
     523           0 :         if( sR<0.0 )
     524           0 :             x *= -1.0; //different signs for x and z
     525             : 
     526             :         //use element 21:
     527           0 :         double cy = sR*sin(E)/sin(z);
     528           0 :         lcl_ensureIntervalMinus1To1(cy);
     529           0 :         y = acos(cy);
     530             : 
     531             :         //use element 22 for sign:
     532           0 :         if( (sin(x)*sin(y)*sin(z)*cos(E))<0.0)
     533           0 :             y *= -1.0;
     534             :     }
     535             :     else
     536             :     {
     537           0 :         z = atan(tan(R) * sin(E));
     538           0 :         if(cos(z)==0.0)
     539             :         {
     540             :             OSL_FAIL("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
     541           0 :             return;
     542             :         }
     543           0 :         double cy = cos(R)/cos(z);
     544           0 :         lcl_ensureIntervalMinus1To1(cy);
     545           0 :         y = acos(cy);
     546             : 
     547             :         //element 12 in 23
     548           0 :         double fDenominator = cos(z)*(1.0-pow(sin(y),2));
     549           0 :         if(fDenominator==0.0)
     550             :         {
     551             :             OSL_FAIL("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
     552           0 :             return;
     553             :         }
     554           0 :         double sx = cos(R)*sin(E)/fDenominator;
     555           0 :         lcl_ensureIntervalMinus1To1(sx);
     556           0 :         x = asin( sx );
     557             : 
     558             :         //use element 13 for sign:
     559           0 :         double f13a = cos(x)*cos(z)*sin(y);
     560           0 :         double f13b = sin(R)-sx*sin(z);
     561           0 :         if( (f13b*f13a)<0.0 )
     562             :         {
     563             :             //change x or y
     564             :             //use element 22 for further investigations:
     565             :             //try
     566           0 :             y *= -1;
     567           0 :             double f22a = cos(x)*cos(z);
     568           0 :             double f22b = cos(E)-(sx*sin(y)*sin(z));
     569           0 :             if( (f22a*f22b)<0.0 )
     570             :             {
     571           0 :                 y *= -1;
     572           0 :                 x=(F_PI-x);
     573             :             }
     574             :         }
     575             :         else
     576             :         {
     577             :             //change nothing or both
     578             :             //use element 22 for further investigations:
     579           0 :             double f22a = cos(x)*cos(z);
     580           0 :             double f22b = cos(E)-(sx*sin(y)*sin(z));
     581           0 :             if( (f22a*f22b)<0.0 )
     582             :             {
     583           0 :                 y *= -1;
     584           0 :                 x=(F_PI-x);
     585             :             }
     586             :         }
     587             :     }
     588             : }
     589             : 
     590          16 : void ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
     591             :     sal_Int32& rnElevationDeg, sal_Int32& rnRotationDeg,
     592             :     double fXRad, double fYRad, double fZRad)
     593             : {
     594             :     // for a description of the algorithm see issue 72994
     595             :     //http://www.openoffice.org/issues/show_bug.cgi?id=72994
     596             :     //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
     597             : 
     598          16 :     double R = 0.0; //Rotation in Rad
     599          16 :     double E = 0.0; //Elevation in Rad
     600             : 
     601          16 :     double& x = fXRad;
     602          16 :     double& y = fYRad;
     603          16 :     double& z = fZRad;
     604             : 
     605          16 :     double f11 = cos(y)*cos(z);
     606             : 
     607          16 :     if( lcl_isSinZero(y) )
     608             :     {
     609             :         //siny == 0
     610             : 
     611          10 :         if( lcl_isCosZero(x) )
     612             :         {
     613             :             //siny == 0 && cosx == 0
     614             : 
     615           0 :             if( lcl_isSinZero(z) )
     616             :             {
     617             :                 //siny == 0 && cosx == 0 && sinz == 0
     618             :                 //example: x=+-90 y=0oder180 z=0(oder180)
     619             : 
     620             :                 //element 13+11
     621           0 :                 if( f11 > 0 )
     622           0 :                     R = 0.0;
     623             :                 else
     624           0 :                     R = F_PI;
     625             : 
     626             :                 //element 23
     627           0 :                 double f23 = cos(z)*sin(x) / cos(R);
     628           0 :                 if( f23 > 0 )
     629           0 :                     E = F_PI/2.0;
     630             :                 else
     631           0 :                     E = -F_PI/2.0;
     632             :             }
     633           0 :             else if( lcl_isCosZero(z) )
     634             :             {
     635             :                 //siny == 0 && cosx == 0 && cosz == 0
     636             :                 //example: x=+-90 y=0oder180 z=+-90
     637             : 
     638           0 :                 double f13 = sin(x)*sin(z);
     639             :                 //element 13+11
     640           0 :                 if( f13 > 0 )
     641           0 :                     R = F_PI/2.0;
     642             :                 else
     643           0 :                     R = -F_PI/2.0;
     644             : 
     645             :                 //element 21
     646           0 :                 double f21 = cos(y)*sin(z) / sin(R);
     647           0 :                 if( f21 > 0 )
     648           0 :                     E = F_PI/2.0;
     649             :                 else
     650           0 :                     E = -F_PI/2.0;
     651             :             }
     652             :             else
     653             :             {
     654             :                 //siny == 0 && cosx == 0 && cosz != 0 && sinz != 0
     655             :                 //element 11 && 13
     656           0 :                 double f13 = sin(x)*sin(z);
     657           0 :                 R = atan( f13/f11 );
     658             : 
     659           0 :                 if(f11<0)
     660           0 :                     R+=F_PI;
     661             : 
     662             :                 //element 23
     663           0 :                 double f23 = cos(z)*sin(x);
     664           0 :                 if( f23/cos(R) > 0 )
     665           0 :                     E = F_PI/2.0;
     666             :                 else
     667           0 :                     E = -F_PI/2.0;
     668             :             }
     669             :         }
     670          10 :         else if( lcl_isSinZero(x) )
     671             :         {
     672             :             //sinY==0 sinX==0
     673             :             //element 13+11
     674           0 :             if( f11 > 0 )
     675           0 :                 R = 0.0;
     676             :             else
     677           0 :                 R = F_PI;
     678             : 
     679           0 :             double f22 = cos(x)*cos(z);
     680           0 :             if( f22 > 0 )
     681           0 :                 E = 0.0;
     682             :             else
     683           0 :                 E = F_PI;
     684             :         }
     685          10 :         else if( lcl_isSinZero(z) )
     686             :         {
     687             :             //sinY==0 sinZ==0 sinx!=0 cosx!=0
     688             :             //element 13+11
     689          10 :             if( f11 > 0 )
     690          10 :                 R = 0.0;
     691             :             else
     692           0 :                 R = F_PI;
     693             : 
     694             :             //element 22 && 23
     695          10 :             double f22 = cos(x)*cos(z);
     696          10 :             double f23 = cos(z)*sin(x);
     697          10 :             E = atan( f23/(f22*cos(R)) );
     698          10 :             if( (f22*cos(E))<0 )
     699           0 :                 E+=F_PI;
     700             :         }
     701           0 :         else if( lcl_isCosZero(z) )
     702             :         {
     703             :             //sinY == 0 && cosZ == 0 && cosx != 0 && sinx != 0
     704           0 :             double f13 = sin(x)*sin(z);
     705             :             //element 13+11
     706           0 :             if( f13 > 0 )
     707           0 :                 R = F_PI/2.0;
     708             :             else
     709           0 :                 R = -F_PI/2.0;
     710             : 
     711             :             //element 21+22
     712           0 :             double f21 = cos(y)*sin(z);
     713           0 :             if( f21/sin(R) > 0 )
     714           0 :                 E = F_PI/2.0;
     715             :             else
     716           0 :                 E = -F_PI/2.0;
     717             :         }
     718             :         else
     719             :         {
     720             :             //sinY == 0 && all other !=0
     721           0 :             double f13 = sin(x)*sin(z);
     722           0 :             R = atan( f13/f11 );
     723           0 :             if( (f11*cos(R))<0.0 )
     724           0 :                 R+=F_PI;
     725             : 
     726           0 :             double f22 = cos(x)*cos(z);
     727           0 :             if( !lcl_isCosZero(R) )
     728           0 :                 E = atan( cos(z)*sin(x) /( f22*cos(R) ) );
     729             :             else
     730           0 :                 E = atan( cos(y)*sin(z) /( f22*sin(R) ) );
     731           0 :             if( (f22*cos(E))<0 )
     732           0 :                 E+=F_PI;
     733             :         }
     734             :     }
     735           6 :     else if( lcl_isCosZero(y) )
     736             :     {
     737             :         //cosY==0
     738             : 
     739           0 :         double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
     740           0 :         if( f13 >= 0 )
     741           0 :             R = F_PI/2.0;
     742             :         else
     743           0 :             R = -F_PI/2.0;
     744             : 
     745           0 :         double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
     746           0 :         if( f22 >= 0 )
     747           0 :             E = 0.0;
     748             :         else
     749           0 :             E = F_PI;
     750             :     }
     751           6 :     else if( lcl_isSinZero(x) )
     752             :     {
     753             :         //cosY!=0 sinY!=0 sinX=0
     754           0 :         if( lcl_isSinZero(z) )
     755             :         {
     756             :             //cosY!=0 sinY!=0 sinX=0 sinZ=0
     757           0 :             double f13 = cos(x)*cos(z)*sin(y);
     758           0 :             R = atan( f13/f11 );
     759             :             //R = asin(f13);
     760           0 :             if( f11<0 )
     761           0 :                 R+=F_PI;
     762             : 
     763           0 :             double f22 = cos(x)*cos(z);
     764           0 :             if( f22>0 )
     765           0 :                 E = 0.0;
     766             :             else
     767           0 :                 E = F_PI;
     768             :         }
     769           0 :         else if( lcl_isCosZero(z) )
     770             :         {
     771             :             //cosY!=0 sinY!=0 sinX=0 cosZ=0
     772           0 :             R = x;
     773           0 :             E = y;//or -y
     774             :             //use 23 for 'signs'
     775           0 :             double f23 =  -1.0*cos(x)*sin(y)*sin(z);
     776           0 :             if( (f23*cos(R)*sin(E))<0.0 )
     777             :             {
     778             :                 //change R or E
     779           0 :                 E = -y;
     780             :             }
     781             :         }
     782             :         else
     783             :         {
     784             :             //cosY!=0 sinY!=0 sinX=0 sinZ!=0 cosZ!=0
     785           0 :             double f13 = cos(x)*cos(z)*sin(y);
     786           0 :             R = atan( f13/f11 );
     787             : 
     788           0 :             if( f11<0 )
     789           0 :                 R+=F_PI;
     790             : 
     791           0 :             double f21 = cos(y)*sin(z);
     792           0 :             double f22 = cos(x)*cos(z);
     793           0 :             E = atan(f21/(f22*sin(R)) );
     794             : 
     795           0 :             if( (f22*cos(E))<0.0 )
     796           0 :                 E+=F_PI;
     797             :         }
     798             :     }
     799           6 :     else if( lcl_isCosZero(x) )
     800             :     {
     801             :         //cosY!=0 sinY!=0 cosX=0
     802             : 
     803           0 :         if( lcl_isSinZero(z) )
     804             :         {
     805             :             //cosY!=0 sinY!=0 cosX=0 sinZ=0
     806           0 :             R=0;//13 -> R=0 or F_PI
     807           0 :             if( f11<0.0 )
     808           0 :                 R=F_PI;
     809           0 :             E=F_PI/2;//22 -> E=+-F_PI/2
     810             :             //use element 11 and 23 for sign
     811           0 :             double f23 = cos(z)*sin(x);
     812           0 :             if( (f11*f23*sin(E))<0.0 )
     813           0 :                 E=-F_PI/2.0;
     814             :         }
     815           0 :         else if( lcl_isCosZero(z) )
     816             :         {
     817             :             //cosY!=0 sinY!=0 cosX=0 cosZ=0
     818             :             //element 11 & 13:
     819           0 :             if( (sin(x)*sin(z))>0.0 )
     820           0 :                 R=F_PI/2.0;
     821             :             else
     822           0 :                 R=-F_PI/2.0;
     823             :             //element 22:
     824           0 :             E=acos( sin(x)*sin(y)*sin(z));
     825             :             //use element 21 for sign:
     826           0 :             if( (cos(y)*sin(z)*sin(R)*sin(E))<0.0 )
     827           0 :                 E*=-1.0;
     828             :         }
     829             :         else
     830             :         {
     831             :             //cosY!=0 sinY!=0 cosX=0 sinZ!=0 cosZ!=0
     832             :             //element 13/11
     833           0 :             R = atan( sin(x)*sin(z)/(cos(y)*cos(z)) );
     834             :             //use 13 for 'sign'
     835           0 :             if( (sin(x)*sin(z))<0.0 )
     836           0 :                 R += F_PI;
     837             :             //element 22
     838           0 :             E = acos(sin(x)*sin(y)*sin(z) );
     839             :             //use 21 for sign
     840           0 :             if( (cos(y)*sin(z)*sin(R)*sin(E))<0.0 )
     841           0 :                 E*=-1.0;
     842             :         }
     843             :     }
     844           6 :     else if( lcl_isSinZero(z) )
     845             :     {
     846             :         //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ=0
     847             :         //element 11
     848           0 :         R=y;
     849             :         //use elenment 13 for sign
     850           0 :         if( (cos(x)*cos(z)*sin(y)*sin(R))<0.0 )
     851           0 :             R*=-1.0;
     852             :         //element 22
     853           0 :         E = acos( cos(x)*cos(z) );
     854             :         //use element 23 for sign
     855           0 :         if( (cos(z)*sin(x)*cos(R)*sin(E))<0.0 )
     856           0 :             E*=-1.0;
     857             :     }
     858           6 :     else if( lcl_isCosZero(z) )
     859             :     {
     860             :         //cosY!=0 sinY!=0 sinX!=0 cosX!=0 cosZ=0
     861             :         //element 21/23
     862           0 :         R=atan(-cos(y)/(cos(x)*sin(y)));
     863             :         //use element 13 for 'sign'
     864           0 :         if( (sin(x)*sin(z)*sin(R))<0.0 )
     865           0 :             R+=F_PI;
     866             :         //element 21/22
     867           0 :         E=atan( cos(y)*sin(z)/(sin(R)*sin(x)*sin(y)*sin(z)) );
     868             :         //use element 23 for 'sign'
     869           0 :         if( (-cos(x)*sin(y)*sin(z)*cos(R)*sin(E))<0.0 )
     870           0 :             E+=F_PI;
     871             :     }
     872             :     else
     873             :     {
     874             :         //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ!=0 cosZ!=0
     875             :         //13/11:
     876           6 :         double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
     877           6 :         R = atan( f13/ f11 );
     878           6 :         if(f11<0.0)
     879           0 :             R+=F_PI;
     880           6 :         double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
     881           6 :         double f23 = cos(x)*sin(y)*sin(z)-cos(z)*sin(x);
     882             :         //23/22:
     883           6 :         E = atan( -1.0*f23/(f22*cos(R)) );
     884           6 :         if(f22<0.0)
     885           0 :             E+=F_PI;
     886             :     }
     887             : 
     888          16 :     rnElevationDeg = ::basegfx::fround( BaseGFXHelper::Rad2Deg( E ) );
     889          16 :     rnRotationDeg = ::basegfx::fround( BaseGFXHelper::Rad2Deg( R ) );
     890          16 : }
     891             : 
     892         140 : double ThreeDHelper::getValueClippedToRange( double fAngle, const double& fPositivLimit )
     893             : {
     894         140 :     if( fAngle<-1*fPositivLimit )
     895           7 :         fAngle=-1*fPositivLimit;
     896         133 :     else if( fAngle>fPositivLimit )
     897           0 :         fAngle=fPositivLimit;
     898         140 :     return fAngle;
     899             : }
     900             : 
     901          70 : double ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()
     902             : {
     903          70 :     return 90.0;
     904             : }
     905             : 
     906          70 : double ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()
     907             : {
     908          70 :     return 45.0;
     909             : }
     910             : 
     911          70 : void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad, double& rfYAngleRad )
     912             : {
     913          70 :     rfXAngleRad = ThreeDHelper::getValueClippedToRange(rfXAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
     914          70 :     rfYAngleRad = ThreeDHelper::getValueClippedToRange(rfYAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
     915          70 : }
     916             : 
     917         226 : void ThreeDHelper::getRotationAngleFromDiagram(
     918             :         const Reference< beans::XPropertySet >& xSceneProperties, double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad )
     919             : {
     920             :     //takes the camera and the transformation matrix into account
     921             : 
     922         226 :     rfXAngleRad = rfYAngleRad = rfZAngleRad = 0.0;
     923             : 
     924         226 :     if( !xSceneProperties.is() )
     925         226 :         return;
     926             : 
     927             :     //get camera rotation
     928         226 :     ::basegfx::B3DHomMatrix aFixCameraRotationMatrix( lcl_getCameraMatrix( xSceneProperties ) );
     929         226 :     BaseGFXHelper::ReduceToRotationMatrix( aFixCameraRotationMatrix );
     930             : 
     931             :     //get scene rotation
     932         452 :     ::basegfx::B3DHomMatrix aSceneRotation;
     933             :     {
     934         226 :         drawing::HomogenMatrix aHomMatrix;
     935         226 :         if( xSceneProperties->getPropertyValue( "D3DTransformMatrix") >>= aHomMatrix )
     936             :         {
     937         226 :             aSceneRotation = BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aHomMatrix );
     938         226 :             BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
     939             :         }
     940             :     }
     941             : 
     942         452 :     ::basegfx::B3DHomMatrix aResultRotation = aFixCameraRotationMatrix * aSceneRotation;
     943         452 :     ::basegfx::B3DTuple aRotation( BaseGFXHelper::GetRotationFromMatrix( aResultRotation ) );
     944             : 
     945         226 :     rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getX());
     946         226 :     rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getY());
     947         226 :     rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getZ());
     948             : 
     949         226 :     if(rfZAngleRad<(-F_PI/2) || rfZAngleRad>(F_PI/2))
     950             :     {
     951           0 :         rfZAngleRad-=F_PI;
     952           0 :         rfXAngleRad-=F_PI;
     953           0 :         rfYAngleRad=(F_PI-rfYAngleRad);
     954             : 
     955           0 :         rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfXAngleRad);
     956           0 :         rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfYAngleRad);
     957           0 :         rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfZAngleRad);
     958         226 :     }
     959             : }
     960             : 
     961           0 : void ThreeDHelper::switchRightAngledAxes( const Reference< beans::XPropertySet >& xSceneProperties, sal_Bool bRightAngledAxes, bool bRotateLights )
     962             : {
     963             :     try
     964             :     {
     965           0 :         if( xSceneProperties.is() )
     966             :         {
     967           0 :             sal_Bool bOldRightAngledAxes = sal_False;
     968           0 :             xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bOldRightAngledAxes;
     969           0 :             if( bOldRightAngledAxes!=bRightAngledAxes)
     970             :             {
     971           0 :                 xSceneProperties->setPropertyValue( "RightAngledAxes", uno::makeAny( bRightAngledAxes ));
     972           0 :                 if( bRotateLights )
     973             :                 {
     974           0 :                     if(bRightAngledAxes)
     975             :                     {
     976           0 :                         ::basegfx::B3DHomMatrix aInverseRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
     977           0 :                         lcl_rotateLights( aInverseRotation, xSceneProperties );
     978             :                     }
     979             :                     else
     980             :                     {
     981           0 :                         ::basegfx::B3DHomMatrix aCompleteRotation( lcl_getCompleteRotationMatrix( xSceneProperties ) );
     982           0 :                         lcl_rotateLights( aCompleteRotation, xSceneProperties );
     983             :                     }
     984             :                 }
     985             :             }
     986             :         }
     987             :     }
     988           0 :     catch( const uno::Exception & ex )
     989             :     {
     990             :         ASSERT_EXCEPTION( ex );
     991             :     }
     992           0 : }
     993             : 
     994          60 : void ThreeDHelper::setRotationAngleToDiagram(
     995             :     const Reference< beans::XPropertySet >& xSceneProperties
     996             :         , double fXAngleRad, double fYAngleRad, double fZAngleRad )
     997             : {
     998             :     //the rotation of the camera is not touched but taken into account
     999             :     //the rotation difference is applied to the transformation matrix
    1000             : 
    1001             :     //the light sources will be adapted also
    1002             : 
    1003          60 :     if( !xSceneProperties.is() )
    1004          60 :         return;
    1005             : 
    1006             :     try
    1007             :     {
    1008             :         //remind old rotation for adaption of light directions
    1009          60 :         ::basegfx::B3DHomMatrix aInverseOldRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
    1010             : 
    1011         120 :         ::basegfx::B3DHomMatrix aInverseCameraRotation;
    1012             :         {
    1013             :             ::basegfx::B3DTuple aR( BaseGFXHelper::GetRotationFromMatrix(
    1014          60 :                     lcl_getCameraMatrix( xSceneProperties ) ) );
    1015          60 :             aInverseCameraRotation.rotate( 0.0, 0.0, -aR.getZ() );
    1016          60 :             aInverseCameraRotation.rotate( 0.0, -aR.getY(), 0.0 );
    1017          60 :             aInverseCameraRotation.rotate( -aR.getX(), 0.0, 0.0 );
    1018             :         }
    1019             : 
    1020         120 :         ::basegfx::B3DHomMatrix aCumulatedRotation;
    1021          60 :         aCumulatedRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
    1022             : 
    1023             :         //calculate new scene matrix
    1024         120 :         ::basegfx::B3DHomMatrix aSceneRotation = aInverseCameraRotation*aCumulatedRotation;
    1025          60 :         BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
    1026             : 
    1027             :         //set new rotation to transformation matrix
    1028          60 :         xSceneProperties->setPropertyValue(
    1029          60 :             "D3DTransformMatrix", uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
    1030             : 
    1031             :         //rotate lights if RightAngledAxes are not set or not supported
    1032          60 :         sal_Bool bRightAngledAxes = sal_False;
    1033          60 :         xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
    1034         120 :         uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
    1035         228 :         if(!bRightAngledAxes || !ChartTypeHelper::isSupportingRightAngledAxes(
    1036         204 :                     DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
    1037             :         {
    1038          12 :             ::basegfx::B3DHomMatrix aNewRotation;
    1039          12 :             aNewRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
    1040          12 :             lcl_rotateLights( aNewRotation*aInverseOldRotation, xSceneProperties );
    1041          60 :         }
    1042             :     }
    1043           0 :     catch( const uno::Exception & ex )
    1044             :     {
    1045             :         ASSERT_EXCEPTION( ex );
    1046             :     }
    1047             : }
    1048             : 
    1049          82 : void ThreeDHelper::getRotationFromDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
    1050             :             , sal_Int32& rnHorizontalAngleDegree, sal_Int32& rnVerticalAngleDegree )
    1051             : {
    1052             :     double fXAngle, fYAngle, fZAngle;
    1053          82 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
    1054             : 
    1055          82 :     if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1056             :     {
    1057             :         ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
    1058          16 :             rnHorizontalAngleDegree, rnVerticalAngleDegree, fXAngle, fYAngle, fZAngle);
    1059          16 :         rnVerticalAngleDegree*=-1;
    1060             :     }
    1061             :     else
    1062             :     {
    1063          66 :         fXAngle = BaseGFXHelper::Rad2Deg( fXAngle );
    1064          66 :         fYAngle = BaseGFXHelper::Rad2Deg( fYAngle );
    1065          66 :         fZAngle = BaseGFXHelper::Rad2Deg( fZAngle );
    1066             : 
    1067          66 :         rnHorizontalAngleDegree = ::basegfx::fround(fXAngle);
    1068          66 :         rnVerticalAngleDegree = ::basegfx::fround(-1.0*fYAngle);
    1069             :         //nZRotation = ::basegfx::fround(-1.0*fZAngle);
    1070             :     }
    1071             : 
    1072          82 :     lcl_shiftAngleToIntervalMinus180To180( rnHorizontalAngleDegree );
    1073          82 :     lcl_shiftAngleToIntervalMinus180To180( rnVerticalAngleDegree );
    1074          82 : }
    1075             : 
    1076          60 : void ThreeDHelper::setRotationToDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
    1077             :             , sal_Int32 nHorizontalAngleDegree, sal_Int32 nVerticalYAngleDegree )
    1078             : {
    1079             :     //todo: x and y is not equal to horz and vert in case of RightAngledAxes==false
    1080          60 :     double fXAngle = BaseGFXHelper::Deg2Rad( nHorizontalAngleDegree );
    1081          60 :     double fYAngle = BaseGFXHelper::Deg2Rad( -1*nVerticalYAngleDegree );
    1082          60 :     double fZAngle = 0.0;
    1083             : 
    1084          60 :     if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1085             :         ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
    1086          12 :             nHorizontalAngleDegree, -1*nVerticalYAngleDegree, fXAngle, fYAngle, fZAngle );
    1087             : 
    1088          60 :     ThreeDHelper::setRotationAngleToDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
    1089          60 : }
    1090             : 
    1091          64 : void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance, double& rfMaximumDistance )
    1092             : {
    1093          64 :     rfMinimumDistance = 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
    1094          64 :     rfMaximumDistance = 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
    1095          64 : }
    1096             : 
    1097          23 : void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance )
    1098             : {
    1099             :     double fMin, fMax;
    1100          23 :     getCameraDistanceRange( fMin, fMax );
    1101          23 :     if( rfCameraDistance < fMin )
    1102           0 :         rfCameraDistance = fMin;
    1103          23 :     if( rfCameraDistance > fMax )
    1104           0 :         rfCameraDistance = fMax;
    1105          23 : }
    1106             : 
    1107          23 : double ThreeDHelper::getCameraDistance(
    1108             :         const Reference< beans::XPropertySet >& xSceneProperties )
    1109             : {
    1110          23 :     double fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;
    1111             : 
    1112          23 :     if( !xSceneProperties.is() )
    1113           0 :         return fCameraDistance;
    1114             : 
    1115             :     try
    1116             :     {
    1117          23 :         drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
    1118          23 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
    1119          23 :         ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
    1120          23 :         fCameraDistance = aVRP.getLength();
    1121             : 
    1122          23 :         ensureCameraDistanceRange( fCameraDistance );
    1123             :     }
    1124           0 :     catch( const uno::Exception & ex )
    1125             :     {
    1126             :         ASSERT_EXCEPTION( ex );
    1127             :     }
    1128          23 :     return fCameraDistance;
    1129             : }
    1130             : 
    1131          30 : void ThreeDHelper::setCameraDistance(
    1132             :         const Reference< beans::XPropertySet >& xSceneProperties, double fCameraDistance )
    1133             : {
    1134          30 :     if( !xSceneProperties.is() )
    1135          30 :         return;
    1136             : 
    1137             :     try
    1138             :     {
    1139          30 :         if( fCameraDistance <= 0 )
    1140           0 :             fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;
    1141             : 
    1142          30 :         drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
    1143          30 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
    1144          30 :         ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
    1145          30 :         if( ::basegfx::fTools::equalZero( aVRP.getLength() ) )
    1146           0 :             aVRP = ::basegfx::B3DVector(0,0,1);
    1147          30 :         aVRP.setLength(fCameraDistance);
    1148          30 :         aCG.vrp = BaseGFXHelper::B3DVectorToPosition3D( aVRP );
    1149             : 
    1150          30 :         xSceneProperties->setPropertyValue( "D3DCameraGeometry", uno::makeAny( aCG ));
    1151             :     }
    1152           0 :     catch( const uno::Exception & ex )
    1153             :     {
    1154             :         ASSERT_EXCEPTION( ex );
    1155             :     }
    1156             : }
    1157             : 
    1158          11 : double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance )
    1159             : {
    1160             :     double fMin, fMax;
    1161          11 :     ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    1162             :     //fMax <-> 0; fMin <->100
    1163             :     //a/x + b = y
    1164          11 :     double a = 100.0*fMax*fMin/(fMax-fMin);
    1165          11 :     double b = -a/fMax;
    1166             : 
    1167          11 :     double fRet = a/fCameraDistance + b;
    1168             : 
    1169          11 :     return fRet;
    1170             : }
    1171             : 
    1172          30 : double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective )
    1173             : {
    1174             :     double fMin, fMax;
    1175          30 :     ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    1176             :     //fMax <-> 0; fMin <->100
    1177             :     //a/x + b = y
    1178          30 :     double a = 100.0*fMax*fMin/(fMax-fMin);
    1179          30 :     double b = -a/fMax;
    1180             : 
    1181          30 :     double fRet = a/(fPerspective - b);
    1182             : 
    1183          30 :     return fRet;
    1184             : }
    1185             : 
    1186          13 : ThreeDLookScheme ThreeDHelper::detectScheme( const uno::Reference< XDiagram >& xDiagram )
    1187             : {
    1188          13 :     ThreeDLookScheme aScheme = ThreeDLookScheme_Unknown;
    1189             : 
    1190             :     sal_Int32 nRoundedEdges;
    1191             :     sal_Int32 nObjectLines;
    1192          13 :     ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );
    1193             : 
    1194             :     //get shade mode and light settings:
    1195          13 :     drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
    1196          13 :     uno::Reference< beans::XPropertySet > xDiagramProps( xDiagram, uno::UNO_QUERY );
    1197             :     try
    1198             :     {
    1199          13 :         if( xDiagramProps.is() )
    1200          13 :             xDiagramProps->getPropertyValue( "D3DSceneShadeMode" )>>= aShadeMode;
    1201             :     }
    1202           0 :     catch( const uno::Exception & ex )
    1203             :     {
    1204             :         ASSERT_EXCEPTION( ex );
    1205             :     }
    1206             : 
    1207          13 :     if( lcl_isSimpleScheme( aShadeMode, nRoundedEdges, nObjectLines, xDiagram ) )
    1208             :     {
    1209           0 :         if( lcl_isSimpleLightScheme(xDiagramProps) )
    1210           0 :             aScheme = ThreeDLookScheme_Simple;
    1211             :     }
    1212          13 :     else if( lcl_isRealisticScheme( aShadeMode, nRoundedEdges, nObjectLines ) )
    1213             :     {
    1214          11 :         if( lcl_isRealisticLightScheme(xDiagramProps) )
    1215          11 :             aScheme = ThreeDLookScheme_Realistic;
    1216             :     }
    1217             : 
    1218          13 :     return aScheme;
    1219             : }
    1220             : 
    1221         147 : void ThreeDHelper::setScheme( const uno::Reference< XDiagram >& xDiagram, ThreeDLookScheme aScheme )
    1222             : {
    1223         147 :     if( aScheme == ThreeDLookScheme_Unknown )
    1224         149 :         return;
    1225             : 
    1226             :     drawing::ShadeMode aShadeMode;
    1227             :     sal_Int32 nRoundedEdges;
    1228             :     sal_Int32 nObjectLines;
    1229             : 
    1230         145 :     if( aScheme == ThreeDLookScheme_Simple )
    1231           0 :         lcl_setSimpleScheme(aShadeMode,nRoundedEdges,nObjectLines,xDiagram);
    1232             :     else
    1233         145 :         lcl_setRealisticScheme(aShadeMode,nRoundedEdges,nObjectLines);
    1234             : 
    1235             :     try
    1236             :     {
    1237         145 :         ThreeDHelper::setRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );
    1238             : 
    1239         145 :         uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY );
    1240         145 :         if( xProp.is() )
    1241             :         {
    1242             :             drawing::ShadeMode aOldShadeMode;
    1243         435 :             if( ! ( (xProp->getPropertyValue( "D3DSceneShadeMode" )>>=aOldShadeMode) &&
    1244         435 :                     aOldShadeMode == aShadeMode ))
    1245             :             {
    1246           0 :                 xProp->setPropertyValue( "D3DSceneShadeMode", uno::makeAny( aShadeMode ));
    1247             :             }
    1248             :         }
    1249             : 
    1250         145 :         lcl_setLightsForScheme( xProp, aScheme );
    1251             :     }
    1252           0 :     catch( const uno::Exception & ex )
    1253             :     {
    1254             :         ASSERT_EXCEPTION( ex );
    1255             :     }
    1256             : 
    1257             : }
    1258             : 
    1259           0 : void ThreeDHelper::set3DSettingsToDefault( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1260             : {
    1261           0 :     Reference< beans::XPropertyState > xState( xSceneProperties, uno::UNO_QUERY );
    1262           0 :     if(xState.is())
    1263             :     {
    1264           0 :         xState->setPropertyToDefault( "D3DSceneDistance");
    1265           0 :         xState->setPropertyToDefault( "D3DSceneFocalLength");
    1266             :     }
    1267           0 :     ThreeDHelper::setDefaultRotation( xSceneProperties );
    1268           0 :     ThreeDHelper::setDefaultIllumination( xSceneProperties );
    1269           0 : }
    1270             : 
    1271          11 : void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties, bool bPieOrDonut )
    1272             : {
    1273          11 :     if( !xSceneProperties.is() )
    1274          11 :         return;
    1275             : 
    1276          11 :     drawing::CameraGeometry aCameraGeo( ThreeDHelper::getDefaultCameraGeometry( bPieOrDonut ) );
    1277          11 :     xSceneProperties->setPropertyValue( "D3DCameraGeometry", uno::makeAny( aCameraGeo ));
    1278             : 
    1279          11 :     ::basegfx::B3DHomMatrix aSceneRotation;
    1280          11 :     if( bPieOrDonut )
    1281          11 :         aSceneRotation.rotate( -F_PI/3.0, 0, 0 );
    1282          11 :     xSceneProperties->setPropertyValue( "D3DTransformMatrix",
    1283          11 :         uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
    1284             : }
    1285             : 
    1286           0 : void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1287             : {
    1288           0 :     bool bPieOrDonut( DiagramHelper::isPieOrDonutChart( uno::Reference< XDiagram >(xSceneProperties, uno::UNO_QUERY) ) );
    1289           0 :     ThreeDHelper::setDefaultRotation( xSceneProperties, bPieOrDonut );
    1290           0 : }
    1291             : 
    1292           0 : void ThreeDHelper::setDefaultIllumination( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1293             : {
    1294           0 :     if( !xSceneProperties.is() )
    1295           0 :         return;
    1296             : 
    1297           0 :     drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
    1298             :     try
    1299             :     {
    1300           0 :         xSceneProperties->getPropertyValue( "D3DSceneShadeMode" )>>= aShadeMode;
    1301           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1, uno::makeAny( sal_False ) );
    1302           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3, uno::makeAny( sal_False ) );
    1303           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4, uno::makeAny( sal_False ) );
    1304           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5, uno::makeAny( sal_False ) );
    1305           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6, uno::makeAny( sal_False ) );
    1306           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7, uno::makeAny( sal_False ) );
    1307           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8, uno::makeAny( sal_False ) );
    1308             :     }
    1309           0 :     catch( const uno::Exception & ex )
    1310             :     {
    1311             :         ASSERT_EXCEPTION( ex );
    1312             :     }
    1313             : 
    1314           0 :     ThreeDLookScheme aScheme = (drawing::ShadeMode_FLAT==aShadeMode) ? ThreeDLookScheme_Simple : ThreeDLookScheme_Realistic;
    1315           0 :     lcl_setLightsForScheme( xSceneProperties, aScheme );
    1316             : }
    1317             : 
    1318          13 : void ThreeDHelper::getRoundedEdgesAndObjectLines(
    1319             :             const uno::Reference< XDiagram > & xDiagram
    1320             :             , sal_Int32& rnRoundedEdges, sal_Int32& rnObjectLines )
    1321             : {
    1322          13 :     rnRoundedEdges = -1;
    1323          13 :     rnObjectLines = -1;
    1324             :     try
    1325             :     {
    1326          13 :         bool bDifferentRoundedEdges = false;
    1327          13 :         bool bDifferentObjectLines = false;
    1328             : 
    1329          13 :         drawing::LineStyle aLineStyle( drawing::LineStyle_SOLID );
    1330             : 
    1331             :         ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
    1332          13 :             DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
    1333          13 :         sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
    1334             : 
    1335          26 :         OUString aPercentDiagonalPropertyName( "PercentDiagonal" );
    1336          26 :         OUString aBorderStylePropertyName( "BorderStyle" );
    1337             : 
    1338         116 :         for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
    1339             :         {
    1340         103 :             uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
    1341         206 :             uno::Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
    1342         103 :             if(!nS)
    1343             :             {
    1344          13 :                 rnRoundedEdges = 0;
    1345             :                 try
    1346             :                 {
    1347          13 :                     sal_Int16 nPercentDiagonal = 0;
    1348             : 
    1349          13 :                     xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
    1350          13 :                     rnRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
    1351             : 
    1352          26 :                     if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1353          26 :                         , aPercentDiagonalPropertyName, uno::makeAny(nPercentDiagonal) ) )
    1354           0 :                         bDifferentRoundedEdges = true;
    1355             :                 }
    1356           0 :                 catch( const uno::Exception& e )
    1357             :                 {
    1358             :                     ASSERT_EXCEPTION( e );
    1359           0 :                     bDifferentRoundedEdges = true;
    1360             :                 }
    1361             :                 try
    1362             :                 {
    1363          13 :                     xProp->getPropertyValue( aBorderStylePropertyName ) >>= aLineStyle;
    1364             : 
    1365          26 :                     if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1366          26 :                         , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
    1367           0 :                         bDifferentObjectLines = true;
    1368             :                 }
    1369           0 :                 catch( const uno::Exception& e )
    1370             :                 {
    1371             :                     ASSERT_EXCEPTION( e );
    1372           0 :                     bDifferentObjectLines = true;
    1373             :                 }
    1374             :             }
    1375             :             else
    1376             :             {
    1377          90 :                 if( !bDifferentRoundedEdges )
    1378             :                 {
    1379          72 :                     sal_Int16 nPercentDiagonal = 0;
    1380          72 :                     xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
    1381          72 :                     sal_Int32 nCurrentRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
    1382         218 :                     if(nCurrentRoundedEdges!=rnRoundedEdges
    1383         284 :                         || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1384         282 :                             , aPercentDiagonalPropertyName, uno::makeAny( static_cast< sal_Int16 >(rnRoundedEdges) ) ) )
    1385             :                     {
    1386           2 :                         bDifferentRoundedEdges = true;
    1387           2 :                         nCurrentRoundedEdges = -1;
    1388             :                     }
    1389             :                 }
    1390             : 
    1391          90 :                 if( !bDifferentObjectLines )
    1392             :                 {
    1393             :                     drawing::LineStyle aCurrentLineStyle;
    1394          90 :                     xProp->getPropertyValue( aBorderStylePropertyName ) >>= aCurrentLineStyle;
    1395         270 :                     if(aCurrentLineStyle!=aLineStyle
    1396         360 :                         || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1397         360 :                             , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
    1398           0 :                         bDifferentObjectLines = true;
    1399             :                 }
    1400             :             }
    1401         103 :             if( bDifferentRoundedEdges && bDifferentObjectLines )
    1402           0 :                 break;
    1403         103 :         }
    1404             : 
    1405             :         //set rnObjectLines
    1406          13 :         rnObjectLines = 0;
    1407          13 :         if( bDifferentObjectLines )
    1408           0 :             rnObjectLines = -1;
    1409          13 :         else if( aLineStyle == drawing::LineStyle_SOLID )
    1410          15 :             rnObjectLines = 1;
    1411             :     }
    1412           0 :     catch( const uno::Exception& e )
    1413             :     {
    1414             :         ASSERT_EXCEPTION( e );
    1415             :     }
    1416          13 : }
    1417             : 
    1418         145 : void ThreeDHelper::setRoundedEdgesAndObjectLines(
    1419             :             const uno::Reference< XDiagram > & xDiagram
    1420             :             , sal_Int32 nRoundedEdges, sal_Int32 nObjectLines )
    1421             : {
    1422         145 :     if( (nRoundedEdges<0||nRoundedEdges>100) && nObjectLines!=0 && nObjectLines!=1 )
    1423         145 :         return;
    1424             : 
    1425         145 :     drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
    1426         145 :     if(nObjectLines==1)
    1427           0 :         aLineStyle = drawing::LineStyle_SOLID;
    1428             : 
    1429         145 :     uno::Any aALineStyle( uno::makeAny(aLineStyle));
    1430         290 :     uno::Any aARoundedEdges( uno::makeAny( static_cast< sal_Int16 >( nRoundedEdges )));
    1431             : 
    1432             :     ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
    1433         290 :         DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
    1434         145 :     sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
    1435         644 :     for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
    1436             :     {
    1437         499 :         uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
    1438             : 
    1439         499 :         if( nRoundedEdges>=0 && nRoundedEdges<=100 )
    1440         499 :             DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "PercentDiagonal", aARoundedEdges );
    1441             : 
    1442         499 :         if( nObjectLines==0 || nObjectLines==1 )
    1443         499 :             DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", aALineStyle );
    1444         644 :     }
    1445             : }
    1446             : 
    1447          24 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const Reference< beans::XPropertySet >& xSceneProperties )
    1448             : {
    1449          24 :     CuboidPlanePosition eRet(CuboidPlanePosition_Left);
    1450             : 
    1451          24 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1452          24 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1453          24 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1454             :     {
    1455          20 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1456          20 :         fZAngleRad=0.0;
    1457             :     }
    1458          24 :     if( sin(fYAngleRad)>0.0 )
    1459           0 :         eRet = CuboidPlanePosition_Right;
    1460          24 :     return eRet;
    1461             : }
    1462             : 
    1463          24 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const Reference< beans::XPropertySet >& xSceneProperties )
    1464             : {
    1465          24 :     CuboidPlanePosition eRet(CuboidPlanePosition_Back);
    1466             : 
    1467          24 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1468          24 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1469          24 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1470             :     {
    1471          20 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1472          20 :         fZAngleRad=0.0;
    1473             :     }
    1474          24 :     if( cos(fXAngleRad)*cos(fYAngleRad)<0.0 )
    1475           0 :         eRet = CuboidPlanePosition_Front;
    1476          24 :     return eRet;
    1477             : }
    1478             : 
    1479          24 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const Reference< beans::XPropertySet >& xSceneProperties )
    1480             : {
    1481          24 :     CuboidPlanePosition eRet(CuboidPlanePosition_Bottom);
    1482             : 
    1483          24 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1484          24 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1485          24 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1486             :     {
    1487          20 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1488          20 :         fZAngleRad=0.0;
    1489             :     }
    1490          24 :     if( sin(fXAngleRad)*cos(fYAngleRad)<0.0 )
    1491           2 :         eRet = CuboidPlanePosition_Top;
    1492          24 :     return eRet;
    1493             : }
    1494             : 
    1495             : } //namespace chart
    1496             : 
    1497             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10