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