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

Generated by: LCOV version 1.10