LCOV - code coverage report
Current view: top level - chart2/source/tools - ThreeDHelper.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 771 0.0 %
Date: 2014-04-14 Functions: 0 50 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #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           0 : bool lcl_isRightAngledAxesSetAndSupported( const Reference< beans::XPropertySet >& xSceneProperties )
      48             : {
      49           0 :     sal_Bool bRightAngledAxes = sal_False;
      50           0 :     if( xSceneProperties.is() )
      51             :     {
      52           0 :         xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
      53           0 :         if(bRightAngledAxes)
      54             :         {
      55           0 :             uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
      56           0 :             if( ChartTypeHelper::isSupportingRightAngledAxes(
      57           0 :                     DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
      58             :             {
      59           0 :                 return true;
      60           0 :             }
      61             :         }
      62             :     }
      63           0 :     return false;
      64             : }
      65             : 
      66           0 : void lcl_RotateLightSource( const Reference< beans::XPropertySet >& xSceneProperties
      67             :                            , const OUString& rLightSourceDirection
      68             :                            , const OUString& rLightSourceOn
      69             :                            , const ::basegfx::B3DHomMatrix& rRotationMatrix )
      70             : {
      71           0 :     if( xSceneProperties.is() )
      72             :     {
      73           0 :         sal_Bool bLightOn = sal_False;
      74           0 :         if( xSceneProperties->getPropertyValue( rLightSourceOn ) >>= bLightOn )
      75             :         {
      76           0 :             if( bLightOn )
      77             :             {
      78           0 :                 drawing::Direction3D aLight;
      79           0 :                 if( xSceneProperties->getPropertyValue( rLightSourceDirection ) >>= aLight )
      80             :                 {
      81           0 :                     ::basegfx::B3DVector aLightVector( BaseGFXHelper::Direction3DToB3DVector( aLight ) );
      82           0 :                     aLightVector = rRotationMatrix*aLightVector;
      83             : 
      84           0 :                     xSceneProperties->setPropertyValue( rLightSourceDirection
      85           0 :                         , uno::makeAny( BaseGFXHelper::B3DVectorToDirection3D( aLightVector ) ) );
      86             :                 }
      87             :             }
      88             :         }
      89             :     }
      90           0 : }
      91             : 
      92           0 : void lcl_rotateLights( const ::basegfx::B3DHomMatrix& rLightRottion, const Reference< beans::XPropertySet >& xSceneProperties )
      93             : {
      94           0 :     if(!xSceneProperties.is())
      95           0 :         return;
      96             : 
      97           0 :     ::basegfx::B3DHomMatrix aLightRottion( rLightRottion );
      98           0 :     BaseGFXHelper::ReduceToRotationMatrix( aLightRottion );
      99             : 
     100           0 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection1", "D3DSceneLightOn1", aLightRottion );
     101           0 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection2", "D3DSceneLightOn2", aLightRottion );
     102           0 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection3", "D3DSceneLightOn3", aLightRottion );
     103           0 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection4", "D3DSceneLightOn4", aLightRottion );
     104           0 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection5", "D3DSceneLightOn5", aLightRottion );
     105           0 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection6", "D3DSceneLightOn6", aLightRottion );
     106           0 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection7", "D3DSceneLightOn7", aLightRottion );
     107           0 :     lcl_RotateLightSource( xSceneProperties, "D3DSceneLightDirection8", "D3DSceneLightOn8", aLightRottion );
     108             : }
     109             : 
     110           0 : ::basegfx::B3DHomMatrix lcl_getInverseRotationMatrix( const Reference< beans::XPropertySet >& xSceneProperties )
     111             : {
     112           0 :     ::basegfx::B3DHomMatrix aInverseRotation;
     113           0 :     double fXAngleRad=0.0;
     114           0 :     double fYAngleRad=0.0;
     115           0 :     double fZAngleRad=0.0;
     116             :     ThreeDHelper::getRotationAngleFromDiagram(
     117           0 :         xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
     118           0 :     aInverseRotation.rotate( 0.0, 0.0, -fZAngleRad );
     119           0 :     aInverseRotation.rotate( 0.0, -fYAngleRad, 0.0 );
     120           0 :     aInverseRotation.rotate( -fXAngleRad, 0.0, 0.0 );
     121           0 :     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           0 : bool lcl_isEqual( const drawing::Direction3D& rA, const drawing::Direction3D& rB )
     137             : {
     138           0 :     return ::rtl::math::approxEqual(rA.DirectionX, rB.DirectionX)
     139           0 :         && ::rtl::math::approxEqual(rA.DirectionY, rB.DirectionY)
     140           0 :         && ::rtl::math::approxEqual(rA.DirectionZ, rB.DirectionZ);
     141             : }
     142             : 
     143           0 : bool lcl_isLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, bool bRealistic )
     144             : {
     145           0 :     if(!xDiagramProps.is())
     146           0 :         return false;
     147             : 
     148           0 :     sal_Bool bIsOn = sal_False;
     149           0 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2 ) >>= bIsOn;
     150           0 :     if(!bIsOn)
     151           0 :         return false;
     152             : 
     153           0 :     uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
     154           0 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     155             : 
     156           0 :     sal_Int32 nColor = 0;
     157           0 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2 ) >>= nColor;
     158           0 :     if( nColor != ::chart::ChartTypeHelper::getDefaultDirectLightColor( !bRealistic, xChartType ) )
     159           0 :         return false;
     160             : 
     161           0 :     sal_Int32 nAmbientColor = 0;
     162           0 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR ) >>= nAmbientColor;
     163           0 :     if( nAmbientColor != ::chart::ChartTypeHelper::getDefaultAmbientLightColor( !bRealistic, xChartType ) )
     164           0 :         return false;
     165             : 
     166           0 :     drawing::Direction3D aDirection(0,0,0);
     167           0 :     xDiagramProps->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2 ) >>= aDirection;
     168             : 
     169             :     drawing::Direction3D aDefaultDirection( bRealistic
     170             :         ? ChartTypeHelper::getDefaultRealisticLightDirection(xChartType)
     171           0 :         : ChartTypeHelper::getDefaultSimpleLightDirection(xChartType) );
     172             : 
     173             :     //rotate default light direction when right angled axes are off but supported
     174             :     {
     175           0 :         sal_Bool bRightAngledAxes = sal_False;
     176           0 :         xDiagramProps->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
     177           0 :         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           0 :     return lcl_isEqual( aDirection, aDefaultDirection );
     192             : }
     193             : 
     194           0 : bool lcl_isRealisticLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps )
     195             : {
     196           0 :     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           0 : void lcl_setLightsForScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, const ThreeDLookScheme& rScheme )
     203             : {
     204           0 :     if(!xDiagramProps.is())
     205           0 :         return;
     206           0 :     if( rScheme == ThreeDLookScheme_Unknown)
     207           0 :         return;
     208             : 
     209           0 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2, uno::makeAny( sal_True ) );
     210             : 
     211           0 :     uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
     212           0 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     213           0 :     uno::Any aADirection( uno::makeAny( rScheme == ThreeDLookScheme_Simple
     214             :         ? ChartTypeHelper::getDefaultSimpleLightDirection(xChartType)
     215           0 :         : ChartTypeHelper::getDefaultRealisticLightDirection(xChartType) ) );
     216             : 
     217           0 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2, aADirection );
     218             :     //rotate light direction when right angled axes are off but supported
     219             :     {
     220           0 :         sal_Bool bRightAngledAxes = sal_False;
     221           0 :         xDiagramProps->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
     222           0 :         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           0 :     sal_Int32 nColor = ::chart::ChartTypeHelper::getDefaultDirectLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
     234           0 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2, uno::makeAny( nColor ) );
     235             : 
     236           0 :     sal_Int32 nAmbientColor = ::chart::ChartTypeHelper::getDefaultAmbientLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
     237           0 :     xDiagramProps->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR, uno::makeAny( nAmbientColor ) );
     238             : }
     239             : 
     240           0 : bool lcl_isRealisticScheme( drawing::ShadeMode aShadeMode
     241             :                     , sal_Int32 nRoundedEdges
     242             :                     , sal_Int32 nObjectLines )
     243             : {
     244           0 :     if(aShadeMode!=drawing::ShadeMode_SMOOTH)
     245           0 :         return false;
     246           0 :     if(nRoundedEdges!=5)
     247           0 :         return false;
     248           0 :     if(nObjectLines!=0)
     249           0 :         return false;
     250           0 :     return true;
     251             : }
     252             : 
     253           0 : bool lcl_isSimpleScheme( drawing::ShadeMode aShadeMode
     254             :                     , sal_Int32 nRoundedEdges
     255             :                     , sal_Int32 nObjectLines
     256             :                     , const uno::Reference< XDiagram >& xDiagram )
     257             : {
     258           0 :     if(aShadeMode!=drawing::ShadeMode_FLAT)
     259           0 :         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           0 : void lcl_setRealisticScheme( drawing::ShadeMode& rShadeMode
     273             :                     , sal_Int32& rnRoundedEdges
     274             :                     , sal_Int32& rnObjectLines )
     275             : {
     276           0 :     rShadeMode = drawing::ShadeMode_SMOOTH;
     277           0 :     rnRoundedEdges = 5;
     278           0 :     rnObjectLines = 0;
     279           0 : }
     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           0 : drawing::CameraGeometry ThreeDHelper::getDefaultCameraGeometry( bool bPie )
     296             : {
     297             :     // ViewReferencePoint (Point on the View plane)
     298           0 :     drawing::Position3D vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
     299             :     // ViewPlaneNormal (Normal to the View Plane)
     300           0 :     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           0 :     drawing::Direction3D vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
     304             : 
     305           0 :     if( bPie )
     306             :     {
     307           0 :         vrp = drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspecitve
     308           0 :         vpn = drawing::Direction3D( 0.0, 0.0, 1.0 );
     309           0 :         vup = drawing::Direction3D( 0.0, 1.0, 0.0 );
     310             :     }
     311             : 
     312           0 :     return drawing::CameraGeometry( vrp, vpn, vup );
     313             : }
     314             : 
     315             : namespace
     316             : {
     317           0 : ::basegfx::B3DHomMatrix lcl_getCameraMatrix( const uno::Reference< beans::XPropertySet >& xSceneProperties )
     318             : {
     319           0 :     drawing::HomogenMatrix aCameraMatrix;
     320             : 
     321           0 :     drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
     322           0 :     if( xSceneProperties.is() )
     323           0 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
     324             : 
     325           0 :     ::basegfx::B3DVector aVPN( BaseGFXHelper::Direction3DToB3DVector( aCG.vpn ) );
     326           0 :     ::basegfx::B3DVector aVUP( BaseGFXHelper::Direction3DToB3DVector( aCG.vup ) );
     327             : 
     328             :     //normalize vectors:
     329           0 :     aVPN.normalize();
     330           0 :     aVUP.normalize();
     331             : 
     332           0 :     ::basegfx::B3DVector aCross = ::basegfx::cross( aVUP, aVPN );
     333             : 
     334             :     //first line is VUP x VPN
     335           0 :     aCameraMatrix.Line1.Column1 = aCross[0];
     336           0 :     aCameraMatrix.Line1.Column2 = aCross[1];
     337           0 :     aCameraMatrix.Line1.Column3 = aCross[2];
     338           0 :     aCameraMatrix.Line1.Column4 = 0.0;
     339             : 
     340             :     //second line is VUP
     341           0 :     aCameraMatrix.Line2.Column1 = aVUP[0];
     342           0 :     aCameraMatrix.Line2.Column2 = aVUP[1];
     343           0 :     aCameraMatrix.Line2.Column3 = aVUP[2];
     344           0 :     aCameraMatrix.Line2.Column4 = 0.0;
     345             : 
     346             :     //third line is VPN
     347           0 :     aCameraMatrix.Line3.Column1 = aVPN[0];
     348           0 :     aCameraMatrix.Line3.Column2 = aVPN[1];
     349           0 :     aCameraMatrix.Line3.Column3 = aVPN[2];
     350           0 :     aCameraMatrix.Line3.Column4 = 0.0;
     351             : 
     352             :     //fourth line is 0 0 0 1
     353           0 :     aCameraMatrix.Line4.Column1 = 0.0;
     354           0 :     aCameraMatrix.Line4.Column2 = 0.0;
     355           0 :     aCameraMatrix.Line4.Column3 = 0.0;
     356           0 :     aCameraMatrix.Line4.Column4 = 1.0;
     357             : 
     358           0 :     return BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aCameraMatrix );
     359             : }
     360             : 
     361           0 : double lcl_shiftAngleToIntervalMinusPiToPi( double fAngleRad )
     362             : {
     363             :     //valid range:  ]-Pi,Pi]
     364           0 :     while( fAngleRad<=-F_PI )
     365           0 :         fAngleRad+=(2*F_PI);
     366           0 :     while( fAngleRad>F_PI )
     367           0 :         fAngleRad-=(2*F_PI);
     368           0 :     return fAngleRad;
     369             : }
     370             : 
     371           0 : void lcl_shiftAngleToIntervalMinus180To180( sal_Int32& rnAngleDegree )
     372             : {
     373             :     //valid range:  ]-180,180]
     374           0 :     while( rnAngleDegree<=-180 )
     375           0 :         rnAngleDegree+=360;
     376           0 :     while( rnAngleDegree>180 )
     377           0 :         rnAngleDegree-=360;
     378           0 : }
     379             : 
     380           0 : void lcl_shiftAngleToIntervalZeroTo360( sal_Int32& rnAngleDegree )
     381             : {
     382             :     //valid range:  [0,360[
     383           0 :     while( rnAngleDegree<0 )
     384           0 :         rnAngleDegree+=360;
     385           0 :     while( rnAngleDegree>=360 )
     386           0 :         rnAngleDegree-=360;
     387           0 : }
     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           0 : bool lcl_isSinZero( double fAngleRad )
     398             : {
     399           0 :     return ::basegfx::fTools::equalZero( sin(fAngleRad), 0.0000001 );
     400             : }
     401           0 : bool lcl_isCosZero( double fAngleRad )
     402             : {
     403           0 :     return ::basegfx::fTools::equalZero( cos(fAngleRad), 0.0000001 );
     404             : }
     405             : 
     406             : }
     407             : 
     408           0 : 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           0 :     lcl_shiftAngleToIntervalZeroTo360( nElevationDeg );
     417           0 :     lcl_shiftAngleToIntervalZeroTo360( nRotationDeg );
     418             : 
     419           0 :     double& x = rfXAngleRad;
     420           0 :     double& y = rfYAngleRad;
     421           0 :     double& z = rfZAngleRad;
     422             : 
     423           0 :     double E = F_PI*nElevationDeg/180; //elevation in Rad
     424           0 :     double R = F_PI*nRotationDeg/180; //rotation in Rad
     425             : 
     426           0 :     if( (nRotationDeg == 0 || nRotationDeg == 180 )
     427           0 :         && ( 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           0 :     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           0 :     else if( (nRotationDeg == 0 || nRotationDeg == 180 )
     455           0 :         && ( 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           0 :     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           0 :     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           0 :     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           0 :     else if ( nRotationDeg == 0 || nRotationDeg == 180 )
     506             :     {
     507             :         //sE!=0 cE!=0 sR==0
     508           0 :         z = 0.0;
     509           0 :         x = E;
     510           0 :         y = R;
     511           0 :         double f23 = cos(R)*sin(E);
     512           0 :         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           0 : 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           0 :     double R = 0.0; //Rotation in Rad
     599           0 :     double E = 0.0; //Elevation in Rad
     600             : 
     601           0 :     double& x = fXRad;
     602           0 :     double& y = fYRad;
     603           0 :     double& z = fZRad;
     604             : 
     605           0 :     double f11 = cos(y)*cos(z);
     606             : 
     607           0 :     if( lcl_isSinZero(y) )
     608             :     {
     609             :         //siny == 0
     610             : 
     611           0 :         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           0 :         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           0 :         else if( lcl_isSinZero(z) )
     686             :         {
     687             :             //sinY==0 sinZ==0 sinx!=0 cosx!=0
     688             :             //element 13+11
     689           0 :             if( f11 > 0 )
     690           0 :                 R = 0.0;
     691             :             else
     692           0 :                 R = F_PI;
     693             : 
     694             :             //element 22 && 23
     695           0 :             double f22 = cos(x)*cos(z);
     696           0 :             double f23 = cos(z)*sin(x);
     697           0 :             E = atan( f23/(f22*cos(R)) );
     698           0 :             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           0 :     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           0 :     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           0 :     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           0 :     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           0 :     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           0 :         double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
     877           0 :         R = atan( f13/ f11 );
     878           0 :         if(f11<0.0)
     879           0 :             R+=F_PI;
     880           0 :         double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
     881           0 :         double f23 = cos(x)*sin(y)*sin(z)-cos(z)*sin(x);
     882             :         //23/22:
     883           0 :         E = atan( -1.0*f23/(f22*cos(R)) );
     884           0 :         if(f22<0.0)
     885           0 :             E+=F_PI;
     886             :     }
     887             : 
     888           0 :     rnElevationDeg = ::basegfx::fround( BaseGFXHelper::Rad2Deg( E ) );
     889           0 :     rnRotationDeg = ::basegfx::fround( BaseGFXHelper::Rad2Deg( R ) );
     890           0 : }
     891             : 
     892           0 : double ThreeDHelper::getValueClippedToRange( double fAngle, const double& fPositivLimit )
     893             : {
     894           0 :     if( fAngle<-1*fPositivLimit )
     895           0 :         fAngle=-1*fPositivLimit;
     896           0 :     else if( fAngle>fPositivLimit )
     897           0 :         fAngle=fPositivLimit;
     898           0 :     return fAngle;
     899             : }
     900             : 
     901           0 : double ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()
     902             : {
     903           0 :     return 90.0;
     904             : }
     905             : 
     906           0 : double ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()
     907             : {
     908           0 :     return 45.0;
     909             : }
     910             : 
     911           0 : void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad, double& rfYAngleRad )
     912             : {
     913           0 :     rfXAngleRad = ThreeDHelper::getValueClippedToRange(rfXAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
     914           0 :     rfYAngleRad = ThreeDHelper::getValueClippedToRange(rfYAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
     915           0 : }
     916             : 
     917           0 : void ThreeDHelper::getRotationAngleFromDiagram(
     918             :         const Reference< beans::XPropertySet >& xSceneProperties, double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad )
     919             : {
     920             :     //takes the camera and the transformation matrix into account
     921             : 
     922           0 :     rfXAngleRad = rfYAngleRad = rfZAngleRad = 0.0;
     923             : 
     924           0 :     if( !xSceneProperties.is() )
     925           0 :         return;
     926             : 
     927             :     //get camera rotation
     928           0 :     ::basegfx::B3DHomMatrix aFixCameraRotationMatrix( lcl_getCameraMatrix( xSceneProperties ) );
     929           0 :     BaseGFXHelper::ReduceToRotationMatrix( aFixCameraRotationMatrix );
     930             : 
     931             :     //get scene rotation
     932           0 :     ::basegfx::B3DHomMatrix aSceneRotation;
     933             :     {
     934           0 :         drawing::HomogenMatrix aHomMatrix;
     935           0 :         if( xSceneProperties->getPropertyValue( "D3DTransformMatrix") >>= aHomMatrix )
     936             :         {
     937           0 :             aSceneRotation = BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aHomMatrix );
     938           0 :             BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
     939             :         }
     940             :     }
     941             : 
     942           0 :     ::basegfx::B3DHomMatrix aResultRotation = aFixCameraRotationMatrix * aSceneRotation;
     943           0 :     ::basegfx::B3DTuple aRotation( BaseGFXHelper::GetRotationFromMatrix( aResultRotation ) );
     944             : 
     945           0 :     rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getX());
     946           0 :     rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getY());
     947           0 :     rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getZ());
     948             : 
     949           0 :     if(rfZAngleRad<(-F_PI/2) || rfZAngleRad>(F_PI/2))
     950             :     {
     951           0 :         rfZAngleRad-=F_PI;
     952           0 :         rfXAngleRad-=F_PI;
     953           0 :         rfYAngleRad=(F_PI-rfYAngleRad);
     954             : 
     955           0 :         rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfXAngleRad);
     956           0 :         rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfYAngleRad);
     957           0 :         rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfZAngleRad);
     958           0 :     }
     959             : }
     960             : 
     961           0 : void ThreeDHelper::switchRightAngledAxes( const Reference< beans::XPropertySet >& xSceneProperties, sal_Bool bRightAngledAxes, bool bRotateLights )
     962             : {
     963             :     try
     964             :     {
     965           0 :         if( xSceneProperties.is() )
     966             :         {
     967           0 :             sal_Bool bOldRightAngledAxes = sal_False;
     968           0 :             xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bOldRightAngledAxes;
     969           0 :             if( bOldRightAngledAxes!=bRightAngledAxes)
     970             :             {
     971           0 :                 xSceneProperties->setPropertyValue( "RightAngledAxes", uno::makeAny( bRightAngledAxes ));
     972           0 :                 if( bRotateLights )
     973             :                 {
     974           0 :                     if(bRightAngledAxes)
     975             :                     {
     976           0 :                         ::basegfx::B3DHomMatrix aInverseRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
     977           0 :                         lcl_rotateLights( aInverseRotation, xSceneProperties );
     978             :                     }
     979             :                     else
     980             :                     {
     981           0 :                         ::basegfx::B3DHomMatrix aCompleteRotation( lcl_getCompleteRotationMatrix( xSceneProperties ) );
     982           0 :                         lcl_rotateLights( aCompleteRotation, xSceneProperties );
     983             :                     }
     984             :                 }
     985             :             }
     986             :         }
     987             :     }
     988           0 :     catch( const uno::Exception & ex )
     989             :     {
     990             :         ASSERT_EXCEPTION( ex );
     991             :     }
     992           0 : }
     993             : 
     994           0 : void ThreeDHelper::setRotationAngleToDiagram(
     995             :     const Reference< beans::XPropertySet >& xSceneProperties
     996             :         , double fXAngleRad, double fYAngleRad, double fZAngleRad )
     997             : {
     998             :     //the rotation of the camera is not touched but taken into account
     999             :     //the rotation difference is applied to the transformation matrix
    1000             : 
    1001             :     //the light sources will be adapted also
    1002             : 
    1003           0 :     if( !xSceneProperties.is() )
    1004           0 :         return;
    1005             : 
    1006             :     try
    1007             :     {
    1008             :         //remind old rotation for adaption of light directions
    1009           0 :         ::basegfx::B3DHomMatrix aInverseOldRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
    1010             : 
    1011           0 :         ::basegfx::B3DHomMatrix aInverseCameraRotation;
    1012             :         {
    1013             :             ::basegfx::B3DTuple aR( BaseGFXHelper::GetRotationFromMatrix(
    1014           0 :                     lcl_getCameraMatrix( xSceneProperties ) ) );
    1015           0 :             aInverseCameraRotation.rotate( 0.0, 0.0, -aR.getZ() );
    1016           0 :             aInverseCameraRotation.rotate( 0.0, -aR.getY(), 0.0 );
    1017           0 :             aInverseCameraRotation.rotate( -aR.getX(), 0.0, 0.0 );
    1018             :         }
    1019             : 
    1020           0 :         ::basegfx::B3DHomMatrix aCumulatedRotation;
    1021           0 :         aCumulatedRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
    1022             : 
    1023             :         //calculate new scene matrix
    1024           0 :         ::basegfx::B3DHomMatrix aSceneRotation = aInverseCameraRotation*aCumulatedRotation;
    1025           0 :         BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
    1026             : 
    1027             :         //set new rotation to transformation matrix
    1028           0 :         xSceneProperties->setPropertyValue(
    1029           0 :             "D3DTransformMatrix", uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
    1030             : 
    1031             :         //rotate lights if RightAngledAxes are not set or not supported
    1032           0 :         sal_Bool bRightAngledAxes = sal_False;
    1033           0 :         xSceneProperties->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes;
    1034           0 :         uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
    1035           0 :         if(!bRightAngledAxes || !ChartTypeHelper::isSupportingRightAngledAxes(
    1036           0 :                     DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
    1037             :         {
    1038           0 :             ::basegfx::B3DHomMatrix aNewRotation;
    1039           0 :             aNewRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
    1040           0 :             lcl_rotateLights( aNewRotation*aInverseOldRotation, xSceneProperties );
    1041           0 :         }
    1042             :     }
    1043           0 :     catch( const uno::Exception & ex )
    1044             :     {
    1045             :         ASSERT_EXCEPTION( ex );
    1046             :     }
    1047             : }
    1048             : 
    1049           0 : void ThreeDHelper::getRotationFromDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
    1050             :             , sal_Int32& rnHorizontalAngleDegree, sal_Int32& rnVerticalAngleDegree )
    1051             : {
    1052             :     double fXAngle, fYAngle, fZAngle;
    1053           0 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
    1054             : 
    1055           0 :     if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1056             :     {
    1057             :         ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
    1058           0 :             rnHorizontalAngleDegree, rnVerticalAngleDegree, fXAngle, fYAngle, fZAngle);
    1059           0 :         rnVerticalAngleDegree*=-1;
    1060             :     }
    1061             :     else
    1062             :     {
    1063           0 :         fXAngle = BaseGFXHelper::Rad2Deg( fXAngle );
    1064           0 :         fYAngle = BaseGFXHelper::Rad2Deg( fYAngle );
    1065           0 :         fZAngle = BaseGFXHelper::Rad2Deg( fZAngle );
    1066             : 
    1067           0 :         rnHorizontalAngleDegree = ::basegfx::fround(fXAngle);
    1068           0 :         rnVerticalAngleDegree = ::basegfx::fround(-1.0*fYAngle);
    1069             :         //nZRotation = ::basegfx::fround(-1.0*fZAngle);
    1070             :     }
    1071             : 
    1072           0 :     lcl_shiftAngleToIntervalMinus180To180( rnHorizontalAngleDegree );
    1073           0 :     lcl_shiftAngleToIntervalMinus180To180( rnVerticalAngleDegree );
    1074           0 : }
    1075             : 
    1076           0 : void ThreeDHelper::setRotationToDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
    1077             :             , sal_Int32 nHorizontalAngleDegree, sal_Int32 nVerticalYAngleDegree )
    1078             : {
    1079             :     //todo: x and y is not equal to horz and vert in case of RightAngledAxes==false
    1080           0 :     double fXAngle = BaseGFXHelper::Deg2Rad( nHorizontalAngleDegree );
    1081           0 :     double fYAngle = BaseGFXHelper::Deg2Rad( -1*nVerticalYAngleDegree );
    1082           0 :     double fZAngle = 0.0;
    1083             : 
    1084           0 :     if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1085             :         ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
    1086           0 :             nHorizontalAngleDegree, -1*nVerticalYAngleDegree, fXAngle, fYAngle, fZAngle );
    1087             : 
    1088           0 :     ThreeDHelper::setRotationAngleToDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
    1089           0 : }
    1090             : 
    1091           0 : void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance, double& rfMaximumDistance )
    1092             : {
    1093           0 :     rfMinimumDistance = 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
    1094           0 :     rfMaximumDistance = 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
    1095           0 : }
    1096             : 
    1097           0 : void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance )
    1098             : {
    1099             :     double fMin, fMax;
    1100           0 :     getCameraDistanceRange( fMin, fMax );
    1101           0 :     if( rfCameraDistance < fMin )
    1102           0 :         rfCameraDistance = fMin;
    1103           0 :     if( rfCameraDistance > fMax )
    1104           0 :         rfCameraDistance = fMax;
    1105           0 : }
    1106             : 
    1107           0 : double ThreeDHelper::getCameraDistance(
    1108             :         const Reference< beans::XPropertySet >& xSceneProperties )
    1109             : {
    1110           0 :     double fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;
    1111             : 
    1112           0 :     if( !xSceneProperties.is() )
    1113           0 :         return fCameraDistance;
    1114             : 
    1115             :     try
    1116             :     {
    1117           0 :         drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
    1118           0 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
    1119           0 :         ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
    1120           0 :         fCameraDistance = aVRP.getLength();
    1121             : 
    1122           0 :         ensureCameraDistanceRange( fCameraDistance );
    1123             :     }
    1124           0 :     catch( const uno::Exception & ex )
    1125             :     {
    1126             :         ASSERT_EXCEPTION( ex );
    1127             :     }
    1128           0 :     return fCameraDistance;
    1129             : }
    1130             : 
    1131           0 : void ThreeDHelper::setCameraDistance(
    1132             :         const Reference< beans::XPropertySet >& xSceneProperties, double fCameraDistance )
    1133             : {
    1134           0 :     if( !xSceneProperties.is() )
    1135           0 :         return;
    1136             : 
    1137             :     try
    1138             :     {
    1139           0 :         if( fCameraDistance <= 0 )
    1140           0 :             fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;
    1141             : 
    1142           0 :         drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
    1143           0 :         xSceneProperties->getPropertyValue( "D3DCameraGeometry" ) >>= aCG;
    1144           0 :         ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
    1145           0 :         if( ::basegfx::fTools::equalZero( aVRP.getLength() ) )
    1146           0 :             aVRP = ::basegfx::B3DVector(0,0,1);
    1147           0 :         aVRP.setLength(fCameraDistance);
    1148           0 :         aCG.vrp = BaseGFXHelper::B3DVectorToPosition3D( aVRP );
    1149             : 
    1150           0 :         xSceneProperties->setPropertyValue( "D3DCameraGeometry", uno::makeAny( aCG ));
    1151             :     }
    1152           0 :     catch( const uno::Exception & ex )
    1153             :     {
    1154             :         ASSERT_EXCEPTION( ex );
    1155             :     }
    1156             : }
    1157             : 
    1158           0 : double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance )
    1159             : {
    1160             :     double fMin, fMax;
    1161           0 :     ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    1162             :     //fMax <-> 0; fMin <->100
    1163             :     //a/x + b = y
    1164           0 :     double a = 100.0*fMax*fMin/(fMax-fMin);
    1165           0 :     double b = -a/fMax;
    1166             : 
    1167           0 :     double fRet = a/fCameraDistance + b;
    1168             : 
    1169           0 :     return fRet;
    1170             : }
    1171             : 
    1172           0 : double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective )
    1173             : {
    1174             :     double fMin, fMax;
    1175           0 :     ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    1176             :     //fMax <-> 0; fMin <->100
    1177             :     //a/x + b = y
    1178           0 :     double a = 100.0*fMax*fMin/(fMax-fMin);
    1179           0 :     double b = -a/fMax;
    1180             : 
    1181           0 :     double fRet = a/(fPerspective - b);
    1182             : 
    1183           0 :     return fRet;
    1184             : }
    1185             : 
    1186           0 : ThreeDLookScheme ThreeDHelper::detectScheme( const uno::Reference< XDiagram >& xDiagram )
    1187             : {
    1188           0 :     ThreeDLookScheme aScheme = ThreeDLookScheme_Unknown;
    1189             : 
    1190             :     sal_Int32 nRoundedEdges;
    1191             :     sal_Int32 nObjectLines;
    1192           0 :     ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );
    1193             : 
    1194             :     //get shade mode and light settings:
    1195           0 :     drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
    1196           0 :     uno::Reference< beans::XPropertySet > xDiagramProps( xDiagram, uno::UNO_QUERY );
    1197             :     try
    1198             :     {
    1199           0 :         if( xDiagramProps.is() )
    1200           0 :             xDiagramProps->getPropertyValue( "D3DSceneShadeMode" )>>= aShadeMode;
    1201             :     }
    1202           0 :     catch( const uno::Exception & ex )
    1203             :     {
    1204             :         ASSERT_EXCEPTION( ex );
    1205             :     }
    1206             : 
    1207           0 :     if( lcl_isSimpleScheme( aShadeMode, nRoundedEdges, nObjectLines, xDiagram ) )
    1208             :     {
    1209           0 :         if( lcl_isSimpleLightScheme(xDiagramProps) )
    1210           0 :             aScheme = ThreeDLookScheme_Simple;
    1211             :     }
    1212           0 :     else if( lcl_isRealisticScheme( aShadeMode, nRoundedEdges, nObjectLines ) )
    1213             :     {
    1214           0 :         if( lcl_isRealisticLightScheme(xDiagramProps) )
    1215           0 :             aScheme = ThreeDLookScheme_Realistic;
    1216             :     }
    1217             : 
    1218           0 :     return aScheme;
    1219             : }
    1220             : 
    1221           0 : void ThreeDHelper::setScheme( const uno::Reference< XDiagram >& xDiagram, ThreeDLookScheme aScheme )
    1222             : {
    1223           0 :     if( aScheme == ThreeDLookScheme_Unknown )
    1224           0 :         return;
    1225             : 
    1226             :     drawing::ShadeMode aShadeMode;
    1227             :     sal_Int32 nRoundedEdges;
    1228             :     sal_Int32 nObjectLines;
    1229             : 
    1230           0 :     if( aScheme == ThreeDLookScheme_Simple )
    1231           0 :         lcl_setSimpleScheme(aShadeMode,nRoundedEdges,nObjectLines,xDiagram);
    1232             :     else
    1233           0 :         lcl_setRealisticScheme(aShadeMode,nRoundedEdges,nObjectLines);
    1234             : 
    1235             :     try
    1236             :     {
    1237           0 :         ThreeDHelper::setRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );
    1238             : 
    1239           0 :         uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY );
    1240           0 :         if( xProp.is() )
    1241             :         {
    1242             :             drawing::ShadeMode aOldShadeMode;
    1243           0 :             if( ! ( (xProp->getPropertyValue( "D3DSceneShadeMode" )>>=aOldShadeMode) &&
    1244           0 :                     aOldShadeMode == aShadeMode ))
    1245             :             {
    1246           0 :                 xProp->setPropertyValue( "D3DSceneShadeMode", uno::makeAny( aShadeMode ));
    1247             :             }
    1248             :         }
    1249             : 
    1250           0 :         lcl_setLightsForScheme( xProp, aScheme );
    1251             :     }
    1252           0 :     catch( const uno::Exception & ex )
    1253             :     {
    1254             :         ASSERT_EXCEPTION( ex );
    1255             :     }
    1256             : 
    1257             : }
    1258             : 
    1259           0 : void ThreeDHelper::set3DSettingsToDefault( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1260             : {
    1261           0 :     Reference< beans::XPropertyState > xState( xSceneProperties, uno::UNO_QUERY );
    1262           0 :     if(xState.is())
    1263             :     {
    1264           0 :         xState->setPropertyToDefault( "D3DSceneDistance");
    1265           0 :         xState->setPropertyToDefault( "D3DSceneFocalLength");
    1266             :     }
    1267           0 :     ThreeDHelper::setDefaultRotation( xSceneProperties );
    1268           0 :     ThreeDHelper::setDefaultIllumination( xSceneProperties );
    1269           0 : }
    1270             : 
    1271           0 : void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties, bool bPieOrDonut )
    1272             : {
    1273           0 :     if( !xSceneProperties.is() )
    1274           0 :         return;
    1275             : 
    1276           0 :     drawing::CameraGeometry aCameraGeo( ThreeDHelper::getDefaultCameraGeometry( bPieOrDonut ) );
    1277           0 :     xSceneProperties->setPropertyValue( "D3DCameraGeometry", uno::makeAny( aCameraGeo ));
    1278             : 
    1279           0 :     ::basegfx::B3DHomMatrix aSceneRotation;
    1280           0 :     if( bPieOrDonut )
    1281           0 :         aSceneRotation.rotate( -F_PI/3.0, 0, 0 );
    1282           0 :     xSceneProperties->setPropertyValue( "D3DTransformMatrix",
    1283           0 :         uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
    1284             : }
    1285             : 
    1286           0 : void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1287             : {
    1288           0 :     bool bPieOrDonut( DiagramHelper::isPieOrDonutChart( uno::Reference< XDiagram >(xSceneProperties, uno::UNO_QUERY) ) );
    1289           0 :     ThreeDHelper::setDefaultRotation( xSceneProperties, bPieOrDonut );
    1290           0 : }
    1291             : 
    1292           0 : void ThreeDHelper::setDefaultIllumination( const uno::Reference< beans::XPropertySet >& xSceneProperties )
    1293             : {
    1294           0 :     if( !xSceneProperties.is() )
    1295           0 :         return;
    1296             : 
    1297           0 :     drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
    1298             :     try
    1299             :     {
    1300           0 :         xSceneProperties->getPropertyValue( "D3DSceneShadeMode" )>>= aShadeMode;
    1301           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1, uno::makeAny( sal_False ) );
    1302           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3, uno::makeAny( sal_False ) );
    1303           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4, uno::makeAny( sal_False ) );
    1304           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5, uno::makeAny( sal_False ) );
    1305           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6, uno::makeAny( sal_False ) );
    1306           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7, uno::makeAny( sal_False ) );
    1307           0 :         xSceneProperties->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8, uno::makeAny( sal_False ) );
    1308             :     }
    1309           0 :     catch( const uno::Exception & ex )
    1310             :     {
    1311             :         ASSERT_EXCEPTION( ex );
    1312             :     }
    1313             : 
    1314           0 :     ThreeDLookScheme aScheme = (drawing::ShadeMode_FLAT==aShadeMode) ? ThreeDLookScheme_Simple : ThreeDLookScheme_Realistic;
    1315           0 :     lcl_setLightsForScheme( xSceneProperties, aScheme );
    1316             : }
    1317             : 
    1318           0 : void ThreeDHelper::getRoundedEdgesAndObjectLines(
    1319             :             const uno::Reference< XDiagram > & xDiagram
    1320             :             , sal_Int32& rnRoundedEdges, sal_Int32& rnObjectLines )
    1321             : {
    1322           0 :     rnRoundedEdges = -1;
    1323           0 :     rnObjectLines = -1;
    1324             :     try
    1325             :     {
    1326           0 :         bool bDifferentRoundedEdges = false;
    1327           0 :         bool bDifferentObjectLines = false;
    1328             : 
    1329           0 :         drawing::LineStyle aLineStyle( drawing::LineStyle_SOLID );
    1330             : 
    1331             :         ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
    1332           0 :             DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
    1333           0 :         sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
    1334             : 
    1335           0 :         OUString aPercentDiagonalPropertyName( "PercentDiagonal" );
    1336           0 :         OUString aBorderStylePropertyName( "BorderStyle" );
    1337             : 
    1338           0 :         for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
    1339             :         {
    1340           0 :             uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
    1341           0 :             uno::Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
    1342           0 :             if(!nS)
    1343             :             {
    1344           0 :                 rnRoundedEdges = 0;
    1345             :                 try
    1346             :                 {
    1347           0 :                     sal_Int16 nPercentDiagonal = 0;
    1348             : 
    1349           0 :                     xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
    1350           0 :                     rnRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
    1351             : 
    1352           0 :                     if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1353           0 :                         , aPercentDiagonalPropertyName, uno::makeAny(nPercentDiagonal) ) )
    1354           0 :                         bDifferentRoundedEdges = true;
    1355             :                 }
    1356           0 :                 catch( const uno::Exception& e )
    1357             :                 {
    1358             :                     ASSERT_EXCEPTION( e );
    1359           0 :                     bDifferentRoundedEdges = true;
    1360             :                 }
    1361             :                 try
    1362             :                 {
    1363           0 :                     xProp->getPropertyValue( aBorderStylePropertyName ) >>= aLineStyle;
    1364             : 
    1365           0 :                     if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1366           0 :                         , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
    1367           0 :                         bDifferentObjectLines = true;
    1368             :                 }
    1369           0 :                 catch( const uno::Exception& e )
    1370             :                 {
    1371             :                     ASSERT_EXCEPTION( e );
    1372           0 :                     bDifferentObjectLines = true;
    1373             :                 }
    1374             :             }
    1375             :             else
    1376             :             {
    1377           0 :                 if( !bDifferentRoundedEdges )
    1378             :                 {
    1379           0 :                     sal_Int16 nPercentDiagonal = 0;
    1380           0 :                     xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
    1381           0 :                     sal_Int32 nCurrentRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
    1382           0 :                     if(nCurrentRoundedEdges!=rnRoundedEdges
    1383           0 :                         || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1384           0 :                             , aPercentDiagonalPropertyName, uno::makeAny( static_cast< sal_Int16 >(rnRoundedEdges) ) ) )
    1385             :                     {
    1386           0 :                         bDifferentRoundedEdges = true;
    1387           0 :                         nCurrentRoundedEdges = -1;
    1388             :                     }
    1389             :                 }
    1390             : 
    1391           0 :                 if( !bDifferentObjectLines )
    1392             :                 {
    1393             :                     drawing::LineStyle aCurrentLineStyle;
    1394           0 :                     xProp->getPropertyValue( aBorderStylePropertyName ) >>= aCurrentLineStyle;
    1395           0 :                     if(aCurrentLineStyle!=aLineStyle
    1396           0 :                         || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
    1397           0 :                             , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
    1398           0 :                         bDifferentObjectLines = true;
    1399             :                 }
    1400             :             }
    1401           0 :             if( bDifferentRoundedEdges && bDifferentObjectLines )
    1402           0 :                 break;
    1403           0 :         }
    1404             : 
    1405             :         //set rnObjectLines
    1406           0 :         rnObjectLines = 0;
    1407           0 :         if( bDifferentObjectLines )
    1408           0 :             rnObjectLines = -1;
    1409           0 :         else if( aLineStyle == drawing::LineStyle_SOLID )
    1410           0 :             rnObjectLines = 1;
    1411             :     }
    1412           0 :     catch( const uno::Exception& e )
    1413             :     {
    1414             :         ASSERT_EXCEPTION( e );
    1415             :     }
    1416           0 : }
    1417             : 
    1418           0 : void ThreeDHelper::setRoundedEdgesAndObjectLines(
    1419             :             const uno::Reference< XDiagram > & xDiagram
    1420             :             , sal_Int32 nRoundedEdges, sal_Int32 nObjectLines )
    1421             : {
    1422           0 :     if( (nRoundedEdges<0||nRoundedEdges>100) && nObjectLines!=0 && nObjectLines!=1 )
    1423           0 :         return;
    1424             : 
    1425           0 :     drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
    1426           0 :     if(nObjectLines==1)
    1427           0 :         aLineStyle = drawing::LineStyle_SOLID;
    1428             : 
    1429           0 :     uno::Any aALineStyle( uno::makeAny(aLineStyle));
    1430           0 :     uno::Any aARoundedEdges( uno::makeAny( static_cast< sal_Int16 >( nRoundedEdges )));
    1431             : 
    1432             :     ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
    1433           0 :         DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
    1434           0 :     sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
    1435           0 :     for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
    1436             :     {
    1437           0 :         uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
    1438             : 
    1439           0 :         if( nRoundedEdges>=0 && nRoundedEdges<=100 )
    1440           0 :             DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "PercentDiagonal", aARoundedEdges );
    1441             : 
    1442           0 :         if( nObjectLines==0 || nObjectLines==1 )
    1443           0 :             DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", aALineStyle );
    1444           0 :     }
    1445             : }
    1446             : 
    1447           0 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const Reference< beans::XPropertySet >& xSceneProperties )
    1448             : {
    1449           0 :     CuboidPlanePosition eRet(CuboidPlanePosition_Left);
    1450             : 
    1451           0 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1452           0 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1453           0 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1454             :     {
    1455           0 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1456           0 :         fZAngleRad=0.0;
    1457             :     }
    1458           0 :     if( sin(fYAngleRad)>0.0 )
    1459           0 :         eRet = CuboidPlanePosition_Right;
    1460           0 :     return eRet;
    1461             : }
    1462             : 
    1463           0 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const Reference< beans::XPropertySet >& xSceneProperties )
    1464             : {
    1465           0 :     CuboidPlanePosition eRet(CuboidPlanePosition_Back);
    1466             : 
    1467           0 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1468           0 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1469           0 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1470             :     {
    1471           0 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1472           0 :         fZAngleRad=0.0;
    1473             :     }
    1474           0 :     if( cos(fXAngleRad)*cos(fYAngleRad)<0.0 )
    1475           0 :         eRet = CuboidPlanePosition_Front;
    1476           0 :     return eRet;
    1477             : }
    1478             : 
    1479           0 : CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const Reference< beans::XPropertySet >& xSceneProperties )
    1480             : {
    1481           0 :     CuboidPlanePosition eRet(CuboidPlanePosition_Bottom);
    1482             : 
    1483           0 :     double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
    1484           0 :     ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
    1485           0 :     if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
    1486             :     {
    1487           0 :         ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
    1488           0 :         fZAngleRad=0.0;
    1489             :     }
    1490           0 :     if( sin(fXAngleRad)*cos(fYAngleRad)<0.0 )
    1491           0 :         eRet = CuboidPlanePosition_Top;
    1492           0 :     return eRet;
    1493             : }
    1494             : 
    1495             : } //namespace chart
    1496             : 
    1497             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10