LCOV - code coverage report
Current view: top level - chart2/source/tools - ThreeDHelper.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 437 764 57.2 %
Date: 2015-06-13 12:38:46 Functions: 40 48 83.3 %
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         500 : bool lcl_isRightAngledAxesSetAndSupported( const Reference< beans::XPropertySet >& xSceneProperties )
      48             : {
      49         500 :     if( xSceneProperties.is() )
      50             :     {
      51         500 :         bool bRightAngledAxes = false;
      52         500 :         xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
      53         500 :         if(bRightAngledAxes)
      54             :         {
      55         358 :             uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
      56         716 :             if( ChartTypeHelper::isSupportingRightAngledAxes(
      57         716 :                     DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
      58             :             {
      59         358 :                 return true;
      60           0 :             }
      61             :         }
      62             :     }
      63         142 :     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 :         bool bLightOn = 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          72 : ::basegfx::B3DHomMatrix lcl_getInverseRotationMatrix( const Reference< beans::XPropertySet >& xSceneProperties )
     111             : {
     112          72 :     ::basegfx::B3DHomMatrix aInverseRotation;
     113          72 :     double fXAngleRad=0.0;
     114          72 :     double fYAngleRad=0.0;
     115          72 :     double fZAngleRad=0.0;
     116             :     ThreeDHelper::getRotationAngleFromDiagram(
     117          72 :         xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
     118          72 :     aInverseRotation.rotate( 0.0, 0.0, -fZAngleRad );
     119          72 :     aInverseRotation.rotate( 0.0, -fYAngleRad, 0.0 );
     120          72 :     aInverseRotation.rotate( -fXAngleRad, 0.0, 0.0 );
     121          72 :     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           3 : bool lcl_isEqual( const drawing::Direction3D& rA, const drawing::Direction3D& rB )
     137             : {
     138           3 :     return ::rtl::math::approxEqual(rA.DirectionX, rB.DirectionX)
     139           3 :         && ::rtl::math::approxEqual(rA.DirectionY, rB.DirectionY)
     140           6 :         && ::rtl::math::approxEqual(rA.DirectionZ, rB.DirectionZ);
     141             : }
     142             : 
     143           3 : bool lcl_isLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, bool bRealistic )
     144             : {
     145           3 :     if(!xDiagramProps.is())
     146           0 :         return false;
     147             : 
     148           3 :     bool bIsOn = false;
     149           3 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2 ) >>= bIsOn;
     150           3 :     if(!bIsOn)
     151           0 :         return false;
     152             : 
     153           3 :     uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
     154           6 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     155             : 
     156           3 :     sal_Int32 nColor = 0;
     157           3 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2 ) >>= nColor;
     158           3 :     if( nColor != ::chart::ChartTypeHelper::getDefaultDirectLightColor( !bRealistic, xChartType ) )
     159           0 :         return false;
     160             : 
     161           3 :     sal_Int32 nAmbientColor = 0;
     162           3 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR ) >>= nAmbientColor;
     163           3 :     if( nAmbientColor != ::chart::ChartTypeHelper::getDefaultAmbientLightColor( !bRealistic, xChartType ) )
     164           0 :         return false;
     165             : 
     166           3 :     drawing::Direction3D aDirection(0,0,0);
     167           3 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2 ) >>= aDirection;
     168             : 
     169             :     drawing::Direction3D aDefaultDirection( bRealistic
     170             :         ? ChartTypeHelper::getDefaultRealisticLightDirection(xChartType)
     171           3 :         : ChartTypeHelper::getDefaultSimpleLightDirection(xChartType) );
     172             : 
     173             :     //rotate default light direction when right angled axes are off but supported
     174             :     {
     175           3 :         bool bRightAngledAxes = false;
     176           3 :         xDiagramProps->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
     177           3 :         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           6 :     return lcl_isEqual( aDirection, aDefaultDirection );
     192             : }
     193             : 
     194           3 : bool lcl_isRealisticLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps )
     195             : {
     196           3 :     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          17 : void lcl_setLightsForScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, const ThreeDLookScheme& rScheme )
     203             : {
     204          17 :     if(!xDiagramProps.is())
     205           0 :         return;
     206          17 :     if( rScheme == ThreeDLookScheme_Unknown)
     207           0 :         return;
     208             : 
     209          17 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2, uno::makeAny( sal_True ) );
     210             : 
     211          17 :     uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
     212          34 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     213          17 :     uno::Any aADirection( uno::makeAny( rScheme == ThreeDLookScheme_Simple
     214             :         ? ChartTypeHelper::getDefaultSimpleLightDirection(xChartType)
     215          34 :         : ChartTypeHelper::getDefaultRealisticLightDirection(xChartType) ) );
     216             : 
     217          17 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2, aADirection );
     218             :     //rotate light direction when right angled axes are off but supported
     219             :     {
     220          17 :         bool bRightAngledAxes = false;
     221          17 :         xDiagramProps->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
     222          17 :         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          17 :     sal_Int32 nColor = ::chart::ChartTypeHelper::getDefaultDirectLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
     234          17 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2, uno::makeAny( nColor ) );
     235             : 
     236          17 :     sal_Int32 nAmbientColor = ::chart::ChartTypeHelper::getDefaultAmbientLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
     237          34 :     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          10 :         return false;
     248           3 :     if(nObjectLines!=0)
     249           0 :         return false;
     250           3 :     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          17 : void lcl_setRealisticScheme( drawing::ShadeMode& rShadeMode
     273             :                     , sal_Int32& rnRoundedEdges
     274             :                     , sal_Int32& rnObjectLines )
     275             : {
     276          17 :     rShadeMode = drawing::ShadeMode_SMOOTH;
     277          17 :     rnRoundedEdges = 5;
     278          17 :     rnObjectLines = 0;
     279          17 : }
     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        1058 : drawing::CameraGeometry ThreeDHelper::getDefaultCameraGeometry( bool bPie )
     296             : {
     297             :     // ViewReferencePoint (Point on the View plane)
     298        1058 :     drawing::Position3D vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
     299             :     // ViewPlaneNormal (Normal to the View Plane)
     300        1058 :     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        1058 :     drawing::Direction3D vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
     304             : 
     305        1058 :     if( bPie )
     306             :     {
     307           8 :         vrp = drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspecitve
     308           8 :         vpn = drawing::Direction3D( 0.0, 0.0, 1.0 );
     309           8 :         vup = drawing::Direction3D( 0.0, 1.0, 0.0 );
     310             :     }
     311             : 
     312        1058 :     return drawing::CameraGeometry( vrp, vpn, vup );
     313             : }
     314             : 
     315             : namespace
     316             : {
     317         627 : ::basegfx::B3DHomMatrix lcl_getCameraMatrix( const uno::Reference< beans::XPropertySet >& xSceneProperties )
     318             : {
     319         627 :     drawing::HomogenMatrix aCameraMatrix;
     320             : 
     321         627 :     drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
     322         627 :     if( xSceneProperties.is() )
     323         627 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
     324             : 
     325         627 :     ::basegfx::B3DVector aVPN( BaseGFXHelper::Direction3DToB3DVector( aCG.vpn ) );
     326        1254 :     ::basegfx::B3DVector aVUP( BaseGFXHelper::Direction3DToB3DVector( aCG.vup ) );
     327             : 
     328             :     //normalize vectors:
     329         627 :     aVPN.normalize();
     330         627 :     aVUP.normalize();
     331             : 
     332        1254 :     ::basegfx::B3DVector aCross = ::basegfx::cross( aVUP, aVPN );
     333             : 
     334             :     //first line is VUP x VPN
     335         627 :     aCameraMatrix.Line1.Column1 = aCross[0];
     336         627 :     aCameraMatrix.Line1.Column2 = aCross[1];
     337         627 :     aCameraMatrix.Line1.Column3 = aCross[2];
     338         627 :     aCameraMatrix.Line1.Column4 = 0.0;
     339             : 
     340             :     //second line is VUP
     341         627 :     aCameraMatrix.Line2.Column1 = aVUP[0];
     342         627 :     aCameraMatrix.Line2.Column2 = aVUP[1];
     343         627 :     aCameraMatrix.Line2.Column3 = aVUP[2];
     344         627 :     aCameraMatrix.Line2.Column4 = 0.0;
     345             : 
     346             :     //third line is VPN
     347         627 :     aCameraMatrix.Line3.Column1 = aVPN[0];
     348         627 :     aCameraMatrix.Line3.Column2 = aVPN[1];
     349         627 :     aCameraMatrix.Line3.Column3 = aVPN[2];
     350         627 :     aCameraMatrix.Line3.Column4 = 0.0;
     351             : 
     352             :     //fourth line is 0 0 0 1
     353         627 :     aCameraMatrix.Line4.Column1 = 0.0;
     354         627 :     aCameraMatrix.Line4.Column2 = 0.0;
     355         627 :     aCameraMatrix.Line4.Column3 = 0.0;
     356         627 :     aCameraMatrix.Line4.Column4 = 1.0;
     357             : 
     358        1254 :     return BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aCameraMatrix );
     359             : }
     360             : 
     361        1665 : double lcl_shiftAngleToIntervalMinusPiToPi( double fAngleRad )
     362             : {
     363             :     //valid range:  ]-Pi,Pi]
     364        3330 :     while( fAngleRad<=-F_PI )
     365           0 :         fAngleRad+=(2*F_PI);
     366        3330 :     while( fAngleRad>F_PI )
     367           0 :         fAngleRad-=(2*F_PI);
     368        1665 :     return fAngleRad;
     369             : }
     370             : 
     371         196 : void lcl_shiftAngleToIntervalMinus180To180( sal_Int32& rnAngleDegree )
     372             : {
     373             :     //valid range:  ]-180,180]
     374         392 :     while( rnAngleDegree<=-180 )
     375           0 :         rnAngleDegree+=360;
     376         392 :     while( rnAngleDegree>180 )
     377           0 :         rnAngleDegree-=360;
     378         196 : }
     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         504 : double ThreeDHelper::getValueClippedToRange( double fAngle, const double& fPositivLimit )
     893             : {
     894         504 :     if( fAngle<-1*fPositivLimit )
     895          14 :         fAngle=-1*fPositivLimit;
     896         490 :     else if( fAngle>fPositivLimit )
     897           0 :         fAngle=fPositivLimit;
     898         504 :     return fAngle;
     899             : }
     900             : 
     901         252 : void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad, double& rfYAngleRad )
     902             : {
     903         252 :     rfXAngleRad = ThreeDHelper::getValueClippedToRange(rfXAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
     904         252 :     rfYAngleRad = ThreeDHelper::getValueClippedToRange(rfYAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
     905         252 : }
     906             : 
     907         555 : void ThreeDHelper::getRotationAngleFromDiagram(
     908             :         const Reference< beans::XPropertySet >& xSceneProperties, double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad )
     909             : {
     910             :     //takes the camera and the transformation matrix into account
     911             : 
     912         555 :     rfXAngleRad = rfYAngleRad = rfZAngleRad = 0.0;
     913             : 
     914         555 :     if( !xSceneProperties.is() )
     915         555 :         return;
     916             : 
     917             :     //get camera rotation
     918         555 :     ::basegfx::B3DHomMatrix aFixCameraRotationMatrix( lcl_getCameraMatrix( xSceneProperties ) );
     919         555 :     BaseGFXHelper::ReduceToRotationMatrix( aFixCameraRotationMatrix );
     920             : 
     921             :     //get scene rotation
     922        1110 :     ::basegfx::B3DHomMatrix aSceneRotation;
     923             :     {
     924         555 :         drawing::HomogenMatrix aHomMatrix;
     925         555 :         if( xSceneProperties->getPropertyValue( "D3DTransformMatrix") >>= aHomMatrix )
     926             :         {
     927         555 :             aSceneRotation = BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aHomMatrix );
     928         555 :             BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
     929             :         }
     930             :     }
     931             : 
     932        1110 :     ::basegfx::B3DHomMatrix aResultRotation = aFixCameraRotationMatrix * aSceneRotation;
     933        1110 :     ::basegfx::B3DTuple aRotation( BaseGFXHelper::GetRotationFromMatrix( aResultRotation ) );
     934             : 
     935         555 :     rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getX());
     936         555 :     rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getY());
     937         555 :     rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getZ());
     938             : 
     939         555 :     if(rfZAngleRad<(-F_PI/2) || rfZAngleRad>(F_PI/2))
     940             :     {
     941           0 :         rfZAngleRad-=F_PI;
     942           0 :         rfXAngleRad-=F_PI;
     943           0 :         rfYAngleRad=(F_PI-rfYAngleRad);
     944             : 
     945           0 :         rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfXAngleRad);
     946           0 :         rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfYAngleRad);
     947           0 :         rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfZAngleRad);
     948         555 :     }
     949             : }
     950             : 
     951           0 : void ThreeDHelper::switchRightAngledAxes( const Reference< beans::XPropertySet >& xSceneProperties, bool bRightAngledAxes, bool bRotateLights )
     952             : {
     953             :     try
     954             :     {
     955           0 :         if( xSceneProperties.is() )
     956             :         {
     957           0 :             bool bOldRightAngledAxes = false;
     958           0 :             xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bOldRightAngledAxes;
     959           0 :             if( bOldRightAngledAxes!=bRightAngledAxes)
     960             :             {
     961           0 :                 xSceneProperties->setPropertyValue( "RightAngledAxes", uno::makeAny( bRightAngledAxes ));
     962           0 :                 if( bRotateLights )
     963             :                 {
     964           0 :                     if(bRightAngledAxes)
     965             :                     {
     966           0 :                         ::basegfx::B3DHomMatrix aInverseRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
     967           0 :                         lcl_rotateLights( aInverseRotation, xSceneProperties );
     968             :                     }
     969             :                     else
     970             :                     {
     971           0 :                         ::basegfx::B3DHomMatrix aCompleteRotation( lcl_getCompleteRotationMatrix( xSceneProperties ) );
     972           0 :                         lcl_rotateLights( aCompleteRotation, xSceneProperties );
     973             :                     }
     974             :                 }
     975             :             }
     976             :         }
     977             :     }
     978           0 :     catch( const uno::Exception & ex )
     979             :     {
     980             :         ASSERT_EXCEPTION( ex );
     981             :     }
     982           0 : }
     983             : 
     984          72 : void ThreeDHelper::setRotationAngleToDiagram(
     985             :     const Reference< beans::XPropertySet >& xSceneProperties
     986             :         , double fXAngleRad, double fYAngleRad, double fZAngleRad )
     987             : {
     988             :     //the rotation of the camera is not touched but taken into account
     989             :     //the rotation difference is applied to the transformation matrix
     990             : 
     991             :     //the light sources will be adapted also
     992             : 
     993          72 :     if( !xSceneProperties.is() )
     994          72 :         return;
     995             : 
     996             :     try
     997             :     {
     998             :         //remind old rotation for adaption of light directions
     999          72 :         ::basegfx::B3DHomMatrix aInverseOldRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
    1000             : 
    1001         144 :         ::basegfx::B3DHomMatrix aInverseCameraRotation;
    1002             :         {
    1003             :             ::basegfx::B3DTuple aR( BaseGFXHelper::GetRotationFromMatrix(
    1004          72 :                     lcl_getCameraMatrix( xSceneProperties ) ) );
    1005          72 :             aInverseCameraRotation.rotate( 0.0, 0.0, -aR.getZ() );
    1006          72 :             aInverseCameraRotation.rotate( 0.0, -aR.getY(), 0.0 );
    1007          72 :             aInverseCameraRotation.rotate( -aR.getX(), 0.0, 0.0 );
    1008             :         }
    1009             : 
    1010         144 :         ::basegfx::B3DHomMatrix aCumulatedRotation;
    1011          72 :         aCumulatedRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
    1012             : 
    1013             :         //calculate new scene matrix
    1014         144 :         ::basegfx::B3DHomMatrix aSceneRotation = aInverseCameraRotation*aCumulatedRotation;
    1015          72 :         BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
    1016             : 
    1017             :         //set new rotation to transformation matrix
    1018          72 :         xSceneProperties->setPropertyValue(
    1019          72 :             "D3DTransformMatrix", uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
    1020             : 
    1021             :         //rotate lights if RightAngledAxes are not set or not supported
    1022          72 :         bool bRightAngledAxes = false;
    1023          72 :         xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
    1024         144 :         uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
    1025         276 :         if(!bRightAngledAxes || !ChartTypeHelper::isSupportingRightAngledAxes(
    1026         252 :                     DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
    1027             :         {
    1028          12 :             ::basegfx::B3DHomMatrix aNewRotation;
    1029          12 :             aNewRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
    1030          12 :             lcl_rotateLights( aNewRotation*aInverseOldRotation, xSceneProperties );
    1031          72 :         }
    1032             :     }
    1033           0 :     catch( const uno::Exception & ex )
    1034             :     {
    1035             :         ASSERT_EXCEPTION( ex );
    1036             :     }
    1037             : }
    1038             : 
    1039          98 : void ThreeDHelper::getRotationFromDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
    1040             :             , sal_Int32& rnHorizontalAngleDegree, sal_Int32& rnVerticalAngleDegree )
    1041             : {
    1042             :     double fXAngle, fYAngle, fZAngle;
    1043          98 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
    1044             : 
    1045          98 :     if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1046             :     {
    1047             :         ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
    1048          16 :             rnHorizontalAngleDegree, rnVerticalAngleDegree, fXAngle, fYAngle, fZAngle);
    1049          16 :         rnVerticalAngleDegree*=-1;
    1050             :     }
    1051             :     else
    1052             :     {
    1053          82 :         fXAngle = BaseGFXHelper::Rad2Deg( fXAngle );
    1054          82 :         fYAngle = BaseGFXHelper::Rad2Deg( fYAngle );
    1055          82 :         fZAngle = BaseGFXHelper::Rad2Deg( fZAngle );
    1056             : 
    1057          82 :         rnHorizontalAngleDegree = ::basegfx::fround(fXAngle);
    1058          82 :         rnVerticalAngleDegree = ::basegfx::fround(-1.0*fYAngle);
    1059             :         //nZRotation = ::basegfx::fround(-1.0*fZAngle);
    1060             :     }
    1061             : 
    1062          98 :     lcl_shiftAngleToIntervalMinus180To180( rnHorizontalAngleDegree );
    1063          98 :     lcl_shiftAngleToIntervalMinus180To180( rnVerticalAngleDegree );
    1064          98 : }
    1065             : 
    1066          72 : void ThreeDHelper::setRotationToDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
    1067             :             , sal_Int32 nHorizontalAngleDegree, sal_Int32 nVerticalYAngleDegree )
    1068             : {
    1069             :     //todo: x and y is not equal to horz and vert in case of RightAngledAxes==false
    1070          72 :     double fXAngle = BaseGFXHelper::Deg2Rad( nHorizontalAngleDegree );
    1071          72 :     double fYAngle = BaseGFXHelper::Deg2Rad( -1*nVerticalYAngleDegree );
    1072          72 :     double fZAngle = 0.0;
    1073             : 
    1074          72 :     if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1075             :         ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
    1076          12 :             nHorizontalAngleDegree, -1*nVerticalYAngleDegree, fXAngle, fYAngle, fZAngle );
    1077             : 
    1078          72 :     ThreeDHelper::setRotationAngleToDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
    1079          72 : }
    1080             : 
    1081         117 : void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance, double& rfMaximumDistance )
    1082             : {
    1083         117 :     rfMinimumDistance = 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
    1084         117 :     rfMaximumDistance = 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
    1085         117 : }
    1086             : 
    1087          68 : void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance )
    1088             : {
    1089             :     double fMin, fMax;
    1090          68 :     getCameraDistanceRange( fMin, fMax );
    1091          68 :     if( rfCameraDistance < fMin )
    1092           0 :         rfCameraDistance = fMin;
    1093          68 :     if( rfCameraDistance > fMax )
    1094           0 :         rfCameraDistance = fMax;
    1095          68 : }
    1096             : 
    1097          68 : double ThreeDHelper::getCameraDistance(
    1098             :         const Reference< beans::XPropertySet >& xSceneProperties )
    1099             : {
    1100          68 :     double fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;
    1101             : 
    1102          68 :     if( !xSceneProperties.is() )
    1103           0 :         return fCameraDistance;
    1104             : 
    1105             :     try
    1106             :     {
    1107          68 :         drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
    1108          68 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
    1109          68 :         ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
    1110          68 :         fCameraDistance = aVRP.getLength();
    1111             : 
    1112          68 :         ensureCameraDistanceRange( fCameraDistance );
    1113             :     }
    1114           0 :     catch( const uno::Exception & ex )
    1115             :     {
    1116             :         ASSERT_EXCEPTION( ex );
    1117             :     }
    1118          68 :     return fCameraDistance;
    1119             : }
    1120             : 
    1121          36 : void ThreeDHelper::setCameraDistance(
    1122             :         const Reference< beans::XPropertySet >& xSceneProperties, double fCameraDistance )
    1123             : {
    1124          36 :     if( !xSceneProperties.is() )
    1125          36 :         return;
    1126             : 
    1127             :     try
    1128             :     {
    1129          36 :         if( fCameraDistance <= 0 )
    1130           0 :             fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;
    1131             : 
    1132          36 :         drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
    1133          36 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
    1134          36 :         ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
    1135          36 :         if( ::basegfx::fTools::equalZero( aVRP.getLength() ) )
    1136           0 :             aVRP = ::basegfx::B3DVector(0,0,1);
    1137          36 :         aVRP.setLength(fCameraDistance);
    1138          36 :         aCG.vrp = BaseGFXHelper::B3DVectorToPosition3D( aVRP );
    1139             : 
    1140          36 :         xSceneProperties->setPropertyValue( "D3DCameraGeometry", uno::makeAny( aCG ));
    1141             :     }
    1142           0 :     catch( const uno::Exception & ex )
    1143             :     {
    1144             :         ASSERT_EXCEPTION( ex );
    1145             :     }
    1146             : }
    1147             : 
    1148          13 : double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance )
    1149             : {
    1150             :     double fMin, fMax;
    1151          13 :     ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    1152             :     //fMax <-> 0; fMin <->100
    1153             :     //a/x + b = y
    1154          13 :     double a = 100.0*fMax*fMin/(fMax-fMin);
    1155          13 :     double b = -a/fMax;
    1156             : 
    1157          13 :     double fRet = a/fCameraDistance + b;
    1158             : 
    1159          13 :     return fRet;
    1160             : }
    1161             : 
    1162          36 : double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective )
    1163             : {
    1164             :     double fMin, fMax;
    1165          36 :     ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    1166             :     //fMax <-> 0; fMin <->100
    1167             :     //a/x + b = y
    1168          36 :     double a = 100.0*fMax*fMin/(fMax-fMin);
    1169          36 :     double b = -a/fMax;
    1170             : 
    1171          36 :     double fRet = a/(fPerspective - b);
    1172             : 
    1173          36 :     return fRet;
    1174             : }
    1175             : 
    1176          13 : ThreeDLookScheme ThreeDHelper::detectScheme( const uno::Reference< XDiagram >& xDiagram )
    1177             : {
    1178          13 :     ThreeDLookScheme aScheme = ThreeDLookScheme_Unknown;
    1179             : 
    1180             :     sal_Int32 nRoundedEdges;
    1181             :     sal_Int32 nObjectLines;
    1182          13 :     ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );
    1183             : 
    1184             :     //get shade mode and light settings:
    1185          13 :     drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
    1186          13 :     uno::Reference< beans::XPropertySet > xDiagramProps( xDiagram, uno::UNO_QUERY );
    1187             :     try
    1188             :     {
    1189          13 :         if( xDiagramProps.is() )
    1190          13 :             xDiagramProps->getPropertyValue( "D3DSceneShadeMode" )>>= aShadeMode;
    1191             :     }
    1192           0 :     catch( const uno::Exception & ex )
    1193             :     {
    1194             :         ASSERT_EXCEPTION( ex );
    1195             :     }
    1196             : 
    1197          13 :     if( lcl_isSimpleScheme( aShadeMode, nRoundedEdges, nObjectLines, xDiagram ) )
    1198             :     {
    1199           0 :         if( lcl_isSimpleLightScheme(xDiagramProps) )
    1200           0 :             aScheme = ThreeDLookScheme_Simple;
    1201             :     }
    1202          13 :     else if( lcl_isRealisticScheme( aShadeMode, nRoundedEdges, nObjectLines ) )
    1203             :     {
    1204           3 :         if( lcl_isRealisticLightScheme(xDiagramProps) )
    1205           3 :             aScheme = ThreeDLookScheme_Realistic;
    1206             :     }
    1207             : 
    1208          13 :     return aScheme;
    1209             : }
    1210             : 
    1211          27 : void ThreeDHelper::setScheme( const uno::Reference< XDiagram >& xDiagram, ThreeDLookScheme aScheme )
    1212             : {
    1213          27 :     if( aScheme == ThreeDLookScheme_Unknown )
    1214          37 :         return;
    1215             : 
    1216             :     drawing::ShadeMode aShadeMode;
    1217             :     sal_Int32 nRoundedEdges;
    1218             :     sal_Int32 nObjectLines;
    1219             : 
    1220          17 :     if( aScheme == ThreeDLookScheme_Simple )
    1221           0 :         lcl_setSimpleScheme(aShadeMode,nRoundedEdges,nObjectLines,xDiagram);
    1222             :     else
    1223          17 :         lcl_setRealisticScheme(aShadeMode,nRoundedEdges,nObjectLines);
    1224             : 
    1225             :     try
    1226             :     {
    1227          17 :         ThreeDHelper::setRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );
    1228             : 
    1229          17 :         uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY );
    1230          17 :         if( xProp.is() )
    1231             :         {
    1232             :             drawing::ShadeMode aOldShadeMode;
    1233          51 :             if( ! ( (xProp->getPropertyValue( "D3DSceneShadeMode" )>>=aOldShadeMode) &&
    1234          51 :                     aOldShadeMode == aShadeMode ))
    1235             :             {
    1236           0 :                 xProp->setPropertyValue( "D3DSceneShadeMode", uno::makeAny( aShadeMode ));
    1237             :             }
    1238             :         }
    1239             : 
    1240          17 :         lcl_setLightsForScheme( xProp, aScheme );
    1241             :     }
    1242           0 :     catch( const uno::Exception & ex )
    1243             :     {
    1244             :         ASSERT_EXCEPTION( ex );
    1245             :     }
    1246             : 
    1247             : }
    1248             : 
    1249           0 : void ThreeDHelper::set3DSettingsToDefault( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1250             : {
    1251           0 :     Reference< beans::XPropertyState > xState( xSceneProperties, uno::UNO_QUERY );
    1252           0 :     if(xState.is())
    1253             :     {
    1254           0 :         xState->setPropertyToDefault( "D3DSceneDistance");
    1255           0 :         xState->setPropertyToDefault( "D3DSceneFocalLength");
    1256             :     }
    1257           0 :     ThreeDHelper::setDefaultRotation( xSceneProperties );
    1258           0 :     ThreeDHelper::setDefaultIllumination( xSceneProperties );
    1259           0 : }
    1260             : 
    1261           8 : void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties, bool bPieOrDonut )
    1262             : {
    1263           8 :     if( !xSceneProperties.is() )
    1264           8 :         return;
    1265             : 
    1266           8 :     drawing::CameraGeometry aCameraGeo( ThreeDHelper::getDefaultCameraGeometry( bPieOrDonut ) );
    1267           8 :     xSceneProperties->setPropertyValue( "D3DCameraGeometry", uno::makeAny( aCameraGeo ));
    1268             : 
    1269           8 :     ::basegfx::B3DHomMatrix aSceneRotation;
    1270           8 :     if( bPieOrDonut )
    1271           8 :         aSceneRotation.rotate( -F_PI/3.0, 0, 0 );
    1272           8 :     xSceneProperties->setPropertyValue( "D3DTransformMatrix",
    1273           8 :         uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
    1274             : }
    1275             : 
    1276           0 : void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1277             : {
    1278           0 :     bool bPieOrDonut( DiagramHelper::isPieOrDonutChart( uno::Reference< XDiagram >(xSceneProperties, uno::UNO_QUERY) ) );
    1279           0 :     ThreeDHelper::setDefaultRotation( xSceneProperties, bPieOrDonut );
    1280           0 : }
    1281             : 
    1282           0 : void ThreeDHelper::setDefaultIllumination( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1283             : {
    1284           0 :     if( !xSceneProperties.is() )
    1285           0 :         return;
    1286             : 
    1287           0 :     drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
    1288             :     try
    1289             :     {
    1290           0 :         xSceneProperties->getPropertyValue( "D3DSceneShadeMode" )>>= aShadeMode;
    1291           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1, uno::makeAny( sal_False ) );
    1292           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3, uno::makeAny( sal_False ) );
    1293           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4, uno::makeAny( sal_False ) );
    1294           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5, uno::makeAny( sal_False ) );
    1295           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6, uno::makeAny( sal_False ) );
    1296           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7, uno::makeAny( sal_False ) );
    1297           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8, uno::makeAny( sal_False ) );
    1298             :     }
    1299           0 :     catch( const uno::Exception & ex )
    1300             :     {
    1301             :         ASSERT_EXCEPTION( ex );
    1302             :     }
    1303             : 
    1304           0 :     ThreeDLookScheme aScheme = (drawing::ShadeMode_FLAT==aShadeMode) ? ThreeDLookScheme_Simple : ThreeDLookScheme_Realistic;
    1305           0 :     lcl_setLightsForScheme( xSceneProperties, aScheme );
    1306             : }
    1307             : 
    1308          13 : void ThreeDHelper::getRoundedEdgesAndObjectLines(
    1309             :             const uno::Reference< XDiagram > & xDiagram
    1310             :             , sal_Int32& rnRoundedEdges, sal_Int32& rnObjectLines )
    1311             : {
    1312          13 :     rnRoundedEdges = -1;
    1313          13 :     rnObjectLines = -1;
    1314             :     try
    1315             :     {
    1316          13 :         bool bDifferentRoundedEdges = false;
    1317          13 :         bool bDifferentObjectLines = false;
    1318             : 
    1319          13 :         drawing::LineStyle aLineStyle( drawing::LineStyle_SOLID );
    1320             : 
    1321             :         ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
    1322          13 :             DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
    1323          13 :         sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
    1324             : 
    1325          26 :         OUString aPercentDiagonalPropertyName( "PercentDiagonal" );
    1326          26 :         OUString aBorderStylePropertyName( "BorderStyle" );
    1327             : 
    1328         116 :         for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
    1329             :         {
    1330         103 :             uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
    1331         206 :             uno::Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
    1332         103 :             if(!nS)
    1333             :             {
    1334          13 :                 rnRoundedEdges = 0;
    1335             :                 try
    1336             :                 {
    1337          13 :                     sal_Int16 nPercentDiagonal = 0;
    1338             : 
    1339          13 :                     xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
    1340          13 :                     rnRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
    1341             : 
    1342          26 :                     if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1343          26 :                         , aPercentDiagonalPropertyName, uno::makeAny(nPercentDiagonal) ) )
    1344           0 :                         bDifferentRoundedEdges = true;
    1345             :                 }
    1346           0 :                 catch( const uno::Exception& e )
    1347             :                 {
    1348             :                     ASSERT_EXCEPTION( e );
    1349           0 :                     bDifferentRoundedEdges = true;
    1350             :                 }
    1351             :                 try
    1352             :                 {
    1353          13 :                     xProp->getPropertyValue( aBorderStylePropertyName ) >>= aLineStyle;
    1354             : 
    1355          26 :                     if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1356          26 :                         , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
    1357           0 :                         bDifferentObjectLines = true;
    1358             :                 }
    1359           0 :                 catch( const uno::Exception& e )
    1360             :                 {
    1361             :                     ASSERT_EXCEPTION( e );
    1362           0 :                     bDifferentObjectLines = true;
    1363             :                 }
    1364             :             }
    1365             :             else
    1366             :             {
    1367          90 :                 if( !bDifferentRoundedEdges )
    1368             :                 {
    1369          90 :                     sal_Int16 nPercentDiagonal = 0;
    1370          90 :                     xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
    1371          90 :                     sal_Int32 nCurrentRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
    1372         270 :                     if(nCurrentRoundedEdges!=rnRoundedEdges
    1373         360 :                         || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1374         360 :                             , aPercentDiagonalPropertyName, uno::makeAny( static_cast< sal_Int16 >(rnRoundedEdges) ) ) )
    1375             :                     {
    1376           0 :                         bDifferentRoundedEdges = true;
    1377           0 :                         nCurrentRoundedEdges = -1;
    1378             :                     }
    1379             :                 }
    1380             : 
    1381          90 :                 if( !bDifferentObjectLines )
    1382             :                 {
    1383             :                     drawing::LineStyle aCurrentLineStyle;
    1384          90 :                     xProp->getPropertyValue( aBorderStylePropertyName ) >>= aCurrentLineStyle;
    1385         270 :                     if(aCurrentLineStyle!=aLineStyle
    1386         360 :                         || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1387         360 :                             , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
    1388           0 :                         bDifferentObjectLines = true;
    1389             :                 }
    1390             :             }
    1391         103 :             if( bDifferentRoundedEdges && bDifferentObjectLines )
    1392           0 :                 break;
    1393         103 :         }
    1394             : 
    1395             :         //set rnObjectLines
    1396          13 :         rnObjectLines = 0;
    1397          13 :         if( bDifferentObjectLines )
    1398           0 :             rnObjectLines = -1;
    1399          13 :         else if( aLineStyle == drawing::LineStyle_SOLID )
    1400          19 :             rnObjectLines = 1;
    1401             :     }
    1402           0 :     catch( const uno::Exception& e )
    1403             :     {
    1404             :         ASSERT_EXCEPTION( e );
    1405             :     }
    1406          13 : }
    1407             : 
    1408          17 : void ThreeDHelper::setRoundedEdgesAndObjectLines(
    1409             :             const uno::Reference< XDiagram > & xDiagram
    1410             :             , sal_Int32 nRoundedEdges, sal_Int32 nObjectLines )
    1411             : {
    1412          17 :     if( (nRoundedEdges<0||nRoundedEdges>100) && nObjectLines!=0 && nObjectLines!=1 )
    1413          17 :         return;
    1414             : 
    1415          17 :     drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
    1416          17 :     if(nObjectLines==1)
    1417           0 :         aLineStyle = drawing::LineStyle_SOLID;
    1418             : 
    1419          17 :     uno::Any aALineStyle( uno::makeAny(aLineStyle));
    1420          34 :     uno::Any aARoundedEdges( uno::makeAny( static_cast< sal_Int16 >( nRoundedEdges )));
    1421             : 
    1422             :     ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
    1423          34 :         DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
    1424          17 :     sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
    1425          68 :     for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
    1426             :     {
    1427          51 :         uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
    1428             : 
    1429          51 :         if( nRoundedEdges>=0 && nRoundedEdges<=100 )
    1430          51 :             DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "PercentDiagonal", aARoundedEdges );
    1431             : 
    1432          51 :         if( nObjectLines==0 || nObjectLines==1 )
    1433          51 :             DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", aALineStyle );
    1434          68 :     }
    1435             : }
    1436             : 
    1437         110 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const Reference< beans::XPropertySet >& xSceneProperties )
    1438             : {
    1439         110 :     CuboidPlanePosition eRet(CuboidPlanePosition_Left);
    1440             : 
    1441         110 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1442         110 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1443         110 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1444             :     {
    1445          72 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1446             :     }
    1447         110 :     if( sin(fYAngleRad)>0.0 )
    1448           0 :         eRet = CuboidPlanePosition_Right;
    1449         110 :     return eRet;
    1450             : }
    1451             : 
    1452         110 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const Reference< beans::XPropertySet >& xSceneProperties )
    1453             : {
    1454         110 :     CuboidPlanePosition eRet(CuboidPlanePosition_Back);
    1455             : 
    1456         110 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1457         110 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1458         110 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1459             :     {
    1460          72 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1461             :     }
    1462         110 :     if( cos(fXAngleRad)*cos(fYAngleRad)<0.0 )
    1463           0 :         eRet = CuboidPlanePosition_Front;
    1464         110 :     return eRet;
    1465             : }
    1466             : 
    1467         110 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const Reference< beans::XPropertySet >& xSceneProperties )
    1468             : {
    1469         110 :     CuboidPlanePosition eRet(CuboidPlanePosition_Bottom);
    1470             : 
    1471         110 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1472         110 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1473         110 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1474             :     {
    1475          72 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1476             :     }
    1477         110 :     if( sin(fXAngleRad)*cos(fYAngleRad)<0.0 )
    1478          12 :         eRet = CuboidPlanePosition_Top;
    1479         110 :     return eRet;
    1480             : }
    1481             : 
    1482             : } //namespace chart
    1483             : 
    1484             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11