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