LCOV - code coverage report
Current view: top level - libreoffice/chart2/source/tools - ThreeDHelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 53 761 7.0 %
Date: 2012-12-27 Functions: 5 50 10.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10