1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "ThreeDHelper.hxx"
23 #include "DiagramHelper.hxx"
24 #include "ChartTypeHelper.hxx"
25 #include "BaseGFXHelper.hxx"
26 #include "DataSeriesHelper.hxx"
27 #include "defines.hxx"
29 #include <editeng/unoprnms.hxx>
30 #include <com/sun/star/beans/XPropertyState.hpp>
31 #include <com/sun/star/chart2/XDiagram.hpp>
32 #include <com/sun/star/drawing/LineStyle.hpp>
34 //.............................................................................
37 //.............................................................................
38 using namespace ::com::sun::star
;
39 using namespace ::com::sun::star::chart2
;
41 using ::com::sun::star::uno::Reference
;
42 using ::com::sun::star::uno::Sequence
;
43 using ::rtl::math::cos
;
44 using ::rtl::math::sin
;
45 using ::rtl::math::tan
;
50 bool lcl_isRightAngledAxesSetAndSupported( const Reference
< beans::XPropertySet
>& xSceneProperties
)
52 sal_Bool bRightAngledAxes
= sal_False
;
53 if( xSceneProperties
.is() )
55 xSceneProperties
->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes
;
58 uno::Reference
< chart2::XDiagram
> xDiagram( xSceneProperties
, uno::UNO_QUERY
);
59 if( ChartTypeHelper::isSupportingRightAngledAxes(
60 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
69 void lcl_RotateLightSource( const Reference
< beans::XPropertySet
>& xSceneProperties
70 , const OUString
& rLightSourceDirection
71 , const OUString
& rLightSourceOn
72 , const ::basegfx::B3DHomMatrix
& rRotationMatrix
)
74 if( xSceneProperties
.is() )
76 sal_Bool bLightOn
= sal_False
;
77 if( xSceneProperties
->getPropertyValue( rLightSourceOn
) >>= bLightOn
)
81 drawing::Direction3D aLight
;
82 if( xSceneProperties
->getPropertyValue( rLightSourceDirection
) >>= aLight
)
84 ::basegfx::B3DVector
aLightVector( BaseGFXHelper::Direction3DToB3DVector( aLight
) );
85 aLightVector
= rRotationMatrix
*aLightVector
;
87 xSceneProperties
->setPropertyValue( rLightSourceDirection
88 , uno::makeAny( BaseGFXHelper::B3DVectorToDirection3D( aLightVector
) ) );
95 void lcl_rotateLights( const ::basegfx::B3DHomMatrix
& rLightRottion
, const Reference
< beans::XPropertySet
>& xSceneProperties
)
97 if(!xSceneProperties
.is())
100 ::basegfx::B3DHomMatrix
aLightRottion( rLightRottion
);
101 BaseGFXHelper::ReduceToRotationMatrix( aLightRottion
);
103 lcl_RotateLightSource( xSceneProperties
, "D3DSceneLightDirection1", "D3DSceneLightOn1", aLightRottion
);
104 lcl_RotateLightSource( xSceneProperties
, "D3DSceneLightDirection2", "D3DSceneLightOn2", aLightRottion
);
105 lcl_RotateLightSource( xSceneProperties
, "D3DSceneLightDirection3", "D3DSceneLightOn3", aLightRottion
);
106 lcl_RotateLightSource( xSceneProperties
, "D3DSceneLightDirection4", "D3DSceneLightOn4", aLightRottion
);
107 lcl_RotateLightSource( xSceneProperties
, "D3DSceneLightDirection5", "D3DSceneLightOn5", aLightRottion
);
108 lcl_RotateLightSource( xSceneProperties
, "D3DSceneLightDirection6", "D3DSceneLightOn6", aLightRottion
);
109 lcl_RotateLightSource( xSceneProperties
, "D3DSceneLightDirection7", "D3DSceneLightOn7", aLightRottion
);
110 lcl_RotateLightSource( xSceneProperties
, "D3DSceneLightDirection8", "D3DSceneLightOn8", aLightRottion
);
113 ::basegfx::B3DHomMatrix
lcl_getInverseRotationMatrix( const Reference
< beans::XPropertySet
>& xSceneProperties
)
115 ::basegfx::B3DHomMatrix aInverseRotation
;
116 double fXAngleRad
=0.0;
117 double fYAngleRad
=0.0;
118 double fZAngleRad
=0.0;
119 ThreeDHelper::getRotationAngleFromDiagram(
120 xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
121 aInverseRotation
.rotate( 0.0, 0.0, -fZAngleRad
);
122 aInverseRotation
.rotate( 0.0, -fYAngleRad
, 0.0 );
123 aInverseRotation
.rotate( -fXAngleRad
, 0.0, 0.0 );
124 return aInverseRotation
;
127 ::basegfx::B3DHomMatrix
lcl_getCompleteRotationMatrix( const Reference
< beans::XPropertySet
>& xSceneProperties
)
129 ::basegfx::B3DHomMatrix aCompleteRotation
;
130 double fXAngleRad
=0.0;
131 double fYAngleRad
=0.0;
132 double fZAngleRad
=0.0;
133 ThreeDHelper::getRotationAngleFromDiagram(
134 xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
135 aCompleteRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
136 return aCompleteRotation
;
139 bool lcl_isEqual( const drawing::Direction3D
& rA
, const drawing::Direction3D
& rB
)
141 return ::rtl::math::approxEqual(rA
.DirectionX
, rB
.DirectionX
)
142 && ::rtl::math::approxEqual(rA
.DirectionY
, rB
.DirectionY
)
143 && ::rtl::math::approxEqual(rA
.DirectionZ
, rB
.DirectionZ
);
146 bool lcl_isLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
, bool bRealistic
)
148 if(!xDiagramProps
.is())
151 sal_Bool bIsOn
= sal_False
;
152 xDiagramProps
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2
) >>= bIsOn
;
156 uno::Reference
< chart2::XDiagram
> xDiagram( xDiagramProps
, uno::UNO_QUERY
);
157 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
159 sal_Int32 nColor
= 0;
160 xDiagramProps
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
) >>= nColor
;
161 if( nColor
!= ::chart::ChartTypeHelper::getDefaultDirectLightColor( !bRealistic
, xChartType
) )
164 sal_Int32 nAmbientColor
= 0;
165 xDiagramProps
->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR
) >>= nAmbientColor
;
166 if( nAmbientColor
!= ::chart::ChartTypeHelper::getDefaultAmbientLightColor( !bRealistic
, xChartType
) )
169 drawing::Direction3D
aDirection(0,0,0);
170 xDiagramProps
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
) >>= aDirection
;
172 drawing::Direction3D
aDefaultDirection( bRealistic
173 ? ChartTypeHelper::getDefaultRealisticLightDirection(xChartType
)
174 : ChartTypeHelper::getDefaultSimpleLightDirection(xChartType
) );
176 //rotate default light direction when right angled axes are off but supported
178 sal_Bool bRightAngledAxes
= sal_False
;
179 xDiagramProps
->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes
;
180 if(!bRightAngledAxes
)
182 if( ChartTypeHelper::isSupportingRightAngledAxes(
183 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
185 ::basegfx::B3DHomMatrix
aRotation( lcl_getCompleteRotationMatrix( xDiagramProps
) );
186 BaseGFXHelper::ReduceToRotationMatrix( aRotation
);
187 ::basegfx::B3DVector
aLightVector( BaseGFXHelper::Direction3DToB3DVector( aDefaultDirection
) );
188 aLightVector
= aRotation
*aLightVector
;
189 aDefaultDirection
= BaseGFXHelper::B3DVectorToDirection3D( aLightVector
);
194 return lcl_isEqual( aDirection
, aDefaultDirection
);
197 bool lcl_isRealisticLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
)
199 return lcl_isLightScheme( xDiagramProps
, true /*bRealistic*/ );
201 bool lcl_isSimpleLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
)
203 return lcl_isLightScheme( xDiagramProps
, false /*bRealistic*/ );
205 void lcl_setLightsForScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
, const ThreeDLookScheme
& rScheme
)
207 if(!xDiagramProps
.is())
209 if( rScheme
== ThreeDLookScheme_Unknown
)
212 xDiagramProps
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2
, uno::makeAny( sal_True
) );
214 uno::Reference
< chart2::XDiagram
> xDiagram( xDiagramProps
, uno::UNO_QUERY
);
215 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
216 uno::Any
aADirection( uno::makeAny( rScheme
== ThreeDLookScheme_Simple
217 ? ChartTypeHelper::getDefaultSimpleLightDirection(xChartType
)
218 : ChartTypeHelper::getDefaultRealisticLightDirection(xChartType
) ) );
220 xDiagramProps
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
, aADirection
);
221 //rotate light direction when right angled axes are off but supported
223 sal_Bool bRightAngledAxes
= sal_False
;
224 xDiagramProps
->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes
;
225 if(!bRightAngledAxes
)
227 if( ChartTypeHelper::isSupportingRightAngledAxes( xChartType
) )
229 ::basegfx::B3DHomMatrix
aRotation( lcl_getCompleteRotationMatrix( xDiagramProps
) );
230 BaseGFXHelper::ReduceToRotationMatrix( aRotation
);
231 lcl_RotateLightSource( xDiagramProps
, "D3DSceneLightDirection2", "D3DSceneLightOn2", aRotation
);
236 sal_Int32 nColor
= ::chart::ChartTypeHelper::getDefaultDirectLightColor( rScheme
==ThreeDLookScheme_Simple
, xChartType
);
237 xDiagramProps
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
, uno::makeAny( nColor
) );
239 sal_Int32 nAmbientColor
= ::chart::ChartTypeHelper::getDefaultAmbientLightColor( rScheme
==ThreeDLookScheme_Simple
, xChartType
);
240 xDiagramProps
->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR
, uno::makeAny( nAmbientColor
) );
243 bool lcl_isRealisticScheme( drawing::ShadeMode aShadeMode
244 , sal_Int32 nRoundedEdges
245 , sal_Int32 nObjectLines
)
247 if(aShadeMode
!=drawing::ShadeMode_SMOOTH
)
256 bool lcl_isSimpleScheme( drawing::ShadeMode aShadeMode
257 , sal_Int32 nRoundedEdges
258 , sal_Int32 nObjectLines
259 , const uno::Reference
< XDiagram
>& xDiagram
)
261 if(aShadeMode
!=drawing::ShadeMode_FLAT
)
267 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
268 return ChartTypeHelper::noBordersForSimpleScheme( xChartType
);
275 void lcl_setRealisticScheme( drawing::ShadeMode
& rShadeMode
276 , sal_Int32
& rnRoundedEdges
277 , sal_Int32
& rnObjectLines
)
279 rShadeMode
= drawing::ShadeMode_SMOOTH
;
284 void lcl_setSimpleScheme( drawing::ShadeMode
& rShadeMode
285 , sal_Int32
& rnRoundedEdges
286 , sal_Int32
& rnObjectLines
287 , const uno::Reference
< XDiagram
>& xDiagram
)
289 rShadeMode
= drawing::ShadeMode_FLAT
;
292 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
293 rnObjectLines
= ChartTypeHelper::noBordersForSimpleScheme( xChartType
) ? 0 : 1;
296 } //end anonymous namespace
299 drawing::CameraGeometry
ThreeDHelper::getDefaultCameraGeometry( bool bPie
)
301 // ViewReferencePoint (Point on the View plane)
302 drawing::Position3D
vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
303 // ViewPlaneNormal (Normal to the View Plane)
304 drawing::Direction3D
vpn(0.416199821709347, 0.173649045905254, 0.892537795986984);
305 // ViewUpVector (determines the v-axis direction on the view plane as
306 // projection of VUP parallel to VPN onto th view pane)
307 drawing::Direction3D
vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
311 vrp
= drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspecitve
312 vpn
= drawing::Direction3D( 0.0, 0.0, 1.0 );
313 vup
= drawing::Direction3D( 0.0, 1.0, 0.0 );
316 return drawing::CameraGeometry( vrp
, vpn
, vup
);
321 ::basegfx::B3DHomMatrix
lcl_getCameraMatrix( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
323 drawing::HomogenMatrix aCameraMatrix
;
325 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
326 if( xSceneProperties
.is() )
327 xSceneProperties
->getPropertyValue( "D3DCameraGeometry" ) >>= aCG
;
329 ::basegfx::B3DVector
aVPN( BaseGFXHelper::Direction3DToB3DVector( aCG
.vpn
) );
330 ::basegfx::B3DVector
aVUP( BaseGFXHelper::Direction3DToB3DVector( aCG
.vup
) );
336 ::basegfx::B3DVector aCross
= ::basegfx::cross( aVUP
, aVPN
);
338 //first line is VUP x VPN
339 aCameraMatrix
.Line1
.Column1
= aCross
[0];
340 aCameraMatrix
.Line1
.Column2
= aCross
[1];
341 aCameraMatrix
.Line1
.Column3
= aCross
[2];
342 aCameraMatrix
.Line1
.Column4
= 0.0;
345 aCameraMatrix
.Line2
.Column1
= aVUP
[0];
346 aCameraMatrix
.Line2
.Column2
= aVUP
[1];
347 aCameraMatrix
.Line2
.Column3
= aVUP
[2];
348 aCameraMatrix
.Line2
.Column4
= 0.0;
351 aCameraMatrix
.Line3
.Column1
= aVPN
[0];
352 aCameraMatrix
.Line3
.Column2
= aVPN
[1];
353 aCameraMatrix
.Line3
.Column3
= aVPN
[2];
354 aCameraMatrix
.Line3
.Column4
= 0.0;
356 //fourth line is 0 0 0 1
357 aCameraMatrix
.Line4
.Column1
= 0.0;
358 aCameraMatrix
.Line4
.Column2
= 0.0;
359 aCameraMatrix
.Line4
.Column3
= 0.0;
360 aCameraMatrix
.Line4
.Column4
= 1.0;
362 return BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aCameraMatrix
);
365 double lcl_shiftAngleToIntervalMinusPiToPi( double fAngleRad
)
367 //valid range: ]-Pi,Pi]
368 while( fAngleRad
<=-F_PI
)
370 while( fAngleRad
>F_PI
)
375 void lcl_shiftAngleToIntervalMinus180To180( sal_Int32
& rnAngleDegree
)
377 //valid range: ]-180,180]
378 while( rnAngleDegree
<=-180 )
380 while( rnAngleDegree
>180 )
384 void lcl_shiftAngleToIntervalZeroTo360( sal_Int32
& rnAngleDegree
)
386 //valid range: [0,360[
387 while( rnAngleDegree
<0 )
389 while( rnAngleDegree
>=360 )
393 void lcl_ensureIntervalMinus1To1( double& rSinOrCos
)
395 if (rSinOrCos
< -1.0)
397 else if (rSinOrCos
> 1.0)
401 bool lcl_isSinZero( double fAngleRad
)
403 return ::basegfx::fTools::equalZero( sin(fAngleRad
), 0.0000001 );
405 bool lcl_isCosZero( double fAngleRad
)
407 return ::basegfx::fTools::equalZero( cos(fAngleRad
), 0.0000001 );
412 void ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
413 sal_Int32 nElevationDeg
, sal_Int32 nRotationDeg
,
414 double& rfXAngleRad
, double& rfYAngleRad
, double& rfZAngleRad
)
416 // for a description of the algorithm see issue 72994
417 //http://www.openoffice.org/issues/show_bug.cgi?id=72994
418 //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
420 lcl_shiftAngleToIntervalZeroTo360( nElevationDeg
);
421 lcl_shiftAngleToIntervalZeroTo360( nRotationDeg
);
423 double& x
= rfXAngleRad
;
424 double& y
= rfYAngleRad
;
425 double& z
= rfZAngleRad
;
427 double E
= F_PI
*nElevationDeg
/180; //elevation in Rad
428 double R
= F_PI
*nRotationDeg
/180; //rotation in Rad
430 if( (nRotationDeg
== 0 || nRotationDeg
== 180 )
431 && ( nElevationDeg
== 90 || nElevationDeg
== 270 ) )
436 double f23
= cos(R
)*sin(E
);
443 else if( ( nRotationDeg
== 90 || nRotationDeg
== 270 )
444 && ( nElevationDeg
== 90 || nElevationDeg
== 270 ) )
453 if( (sin(R
)*sin(E
))>0 )
458 else if( (nRotationDeg
== 0 || nRotationDeg
== 180 )
459 && ( nElevationDeg
== 0 || nElevationDeg
== 180 ) )
466 else if( ( nRotationDeg
== 90 || nRotationDeg
== 270 )
467 && ( nElevationDeg
== 0 || nElevationDeg
== 180 ) )
472 if( (sin(R
)/cos(E
))>0 )
482 else if ( nElevationDeg
== 0 || nElevationDeg
== 180 )
488 //use element 13 for sign
489 if((cos(x
)*sin(y
)*sin(R
))<0.0)
492 else if ( nElevationDeg
== 90 || nElevationDeg
== 270 )
495 //element 12 + 22 --> y=0 or F_PI and x=+-F_PI/2
497 z
= atan(sin(R
)/(cos(R
)*sin(E
)));
498 //use element 13 for sign for x
499 if( (sin(R
)*sin(z
))>0.0 )
503 //use element 21 for y
504 if( (sin(R
)*sin(E
)*sin(z
))>0.0)
509 else if ( nRotationDeg
== 0 || nRotationDeg
== 180 )
515 double f23
= cos(R
)*sin(E
);
516 if( (f23
* sin(x
)) < 0.0 )
519 else if (nRotationDeg
== 90 || nRotationDeg
== 270)
528 x
*= -1.0; //different signs for x and z
531 double cy
= sR
*sin(E
)/sin(z
);
532 lcl_ensureIntervalMinus1To1(cy
);
535 //use element 22 for sign:
536 if( (sin(x
)*sin(y
)*sin(z
)*cos(E
))<0.0)
541 z
= atan(tan(R
) * sin(E
));
544 OSL_FAIL("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
547 double cy
= cos(R
)/cos(z
);
548 lcl_ensureIntervalMinus1To1(cy
);
552 double fDenominator
= cos(z
)*(1.0-pow(sin(y
),2));
553 if(fDenominator
==0.0)
555 OSL_FAIL("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
558 double sx
= cos(R
)*sin(E
)/fDenominator
;
559 lcl_ensureIntervalMinus1To1(sx
);
562 //use element 13 for sign:
563 double f13a
= cos(x
)*cos(z
)*sin(y
);
564 double f13b
= sin(R
)-sx
*sin(z
);
565 if( (f13b
*f13a
)<0.0 )
568 //use element 22 for further investigations:
571 double f22a
= cos(x
)*cos(z
);
572 double f22b
= cos(E
)-(sx
*sin(y
)*sin(z
));
573 if( (f22a
*f22b
)<0.0 )
581 //change nothing or both
582 //use element 22 for further investigations:
583 double f22a
= cos(x
)*cos(z
);
584 double f22b
= cos(E
)-(sx
*sin(y
)*sin(z
));
585 if( (f22a
*f22b
)<0.0 )
594 void ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
595 sal_Int32
& rnElevationDeg
, sal_Int32
& rnRotationDeg
,
596 double fXRad
, double fYRad
, double fZRad
)
598 // for a description of the algorithm see issue 72994
599 //http://www.openoffice.org/issues/show_bug.cgi?id=72994
600 //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
602 double R
= 0.0; //Rotation in Rad
603 double E
= 0.0; //Elevation in Rad
609 double f11
= cos(y
)*cos(z
);
611 if( lcl_isSinZero(y
) )
615 if( lcl_isCosZero(x
) )
617 //siny == 0 && cosx == 0
619 if( lcl_isSinZero(z
) )
621 //siny == 0 && cosx == 0 && sinz == 0
622 //example: x=+-90 y=0oder180 z=0(oder180)
631 double f23
= cos(z
)*sin(x
) / cos(R
);
637 else if( lcl_isCosZero(z
) )
639 //siny == 0 && cosx == 0 && cosz == 0
640 //example: x=+-90 y=0oder180 z=+-90
642 double f13
= sin(x
)*sin(z
);
650 double f21
= cos(y
)*sin(z
) / sin(R
);
658 //siny == 0 && cosx == 0 && cosz != 0 && sinz != 0
660 double f13
= sin(x
)*sin(z
);
667 double f23
= cos(z
)*sin(x
);
674 else if( lcl_isSinZero(x
) )
683 double f22
= cos(x
)*cos(z
);
689 else if( lcl_isSinZero(z
) )
691 //sinY==0 sinZ==0 sinx!=0 cosx!=0
699 double f22
= cos(x
)*cos(z
);
700 double f23
= cos(z
)*sin(x
);
701 E
= atan( f23
/(f22
*cos(R
)) );
705 else if( lcl_isCosZero(z
) )
707 //sinY == 0 && cosZ == 0 && cosx != 0 && sinx != 0
708 double f13
= sin(x
)*sin(z
);
716 double f21
= cos(y
)*sin(z
);
724 //sinY == 0 && all other !=0
725 double f13
= sin(x
)*sin(z
);
727 if( (f11
*cos(R
))<0.0 )
730 double f22
= cos(x
)*cos(z
);
731 if( !lcl_isCosZero(R
) )
732 E
= atan( cos(z
)*sin(x
) /( f22
*cos(R
) ) );
734 E
= atan( cos(y
)*sin(z
) /( f22
*sin(R
) ) );
739 else if( lcl_isCosZero(y
) )
743 double f13
= sin(x
)*sin(z
)+cos(x
)*cos(z
)*sin(y
);
749 double f22
= cos(x
)*cos(z
)+sin(x
)*sin(y
)*sin(z
);
755 else if( lcl_isSinZero(x
) )
757 //cosY!=0 sinY!=0 sinX=0
758 if( lcl_isSinZero(z
) )
760 //cosY!=0 sinY!=0 sinX=0 sinZ=0
761 double f13
= cos(x
)*cos(z
)*sin(y
);
767 double f22
= cos(x
)*cos(z
);
773 else if( lcl_isCosZero(z
) )
775 //cosY!=0 sinY!=0 sinX=0 cosZ=0
779 double f23
= -1.0*cos(x
)*sin(y
)*sin(z
);
780 if( (f23
*cos(R
)*sin(E
))<0.0 )
788 //cosY!=0 sinY!=0 sinX=0 sinZ!=0 cosZ!=0
789 double f13
= cos(x
)*cos(z
)*sin(y
);
795 double f21
= cos(y
)*sin(z
);
796 double f22
= cos(x
)*cos(z
);
797 E
= atan(f21
/(f22
*sin(R
)) );
799 if( (f22
*cos(E
))<0.0 )
803 else if( lcl_isCosZero(x
) )
805 //cosY!=0 sinY!=0 cosX=0
807 if( lcl_isSinZero(z
) )
809 //cosY!=0 sinY!=0 cosX=0 sinZ=0
810 R
=0;//13 -> R=0 or F_PI
813 E
=F_PI
/2;//22 -> E=+-F_PI/2
814 //use element 11 and 23 for sign
815 double f23
= cos(z
)*sin(x
);
816 if( (f11
*f23
*sin(E
))<0.0 )
819 else if( lcl_isCosZero(z
) )
821 //cosY!=0 sinY!=0 cosX=0 cosZ=0
823 if( (sin(x
)*sin(z
))>0.0 )
828 E
=acos( sin(x
)*sin(y
)*sin(z
));
829 //use element 21 for sign:
830 if( (cos(y
)*sin(z
)*sin(R
)*sin(E
))<0.0 )
835 //cosY!=0 sinY!=0 cosX=0 sinZ!=0 cosZ!=0
837 R
= atan( sin(x
)*sin(z
)/(cos(y
)*cos(z
)) );
839 if( (sin(x
)*sin(z
))<0.0 )
842 E
= acos(sin(x
)*sin(y
)*sin(z
) );
844 if( (cos(y
)*sin(z
)*sin(R
)*sin(E
))<0.0 )
848 else if( lcl_isSinZero(z
) )
850 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ=0
853 //use elenment 13 for sign
854 if( (cos(x
)*cos(z
)*sin(y
)*sin(R
))<0.0 )
857 E
= acos( cos(x
)*cos(z
) );
858 //use element 23 for sign
859 if( (cos(z
)*sin(x
)*cos(R
)*sin(E
))<0.0 )
862 else if( lcl_isCosZero(z
) )
864 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 cosZ=0
866 R
=atan(-cos(y
)/(cos(x
)*sin(y
)));
867 //use element 13 for 'sign'
868 if( (sin(x
)*sin(z
)*sin(R
))<0.0 )
871 E
=atan( cos(y
)*sin(z
)/(sin(R
)*sin(x
)*sin(y
)*sin(z
)) );
872 //use element 23 for 'sign'
873 if( (-cos(x
)*sin(y
)*sin(z
)*cos(R
)*sin(E
))<0.0 )
878 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ!=0 cosZ!=0
880 double f13
= sin(x
)*sin(z
)+cos(x
)*cos(z
)*sin(y
);
881 R
= atan( f13
/ f11
);
884 double f22
= cos(x
)*cos(z
)+sin(x
)*sin(y
)*sin(z
);
885 double f23
= cos(x
)*sin(y
)*sin(z
)-cos(z
)*sin(x
);
887 E
= atan( -1.0*f23
/(f22
*cos(R
)) );
892 rnElevationDeg
= ::basegfx::fround( BaseGFXHelper::Rad2Deg( E
) );
893 rnRotationDeg
= ::basegfx::fround( BaseGFXHelper::Rad2Deg( R
) );
896 double ThreeDHelper::getValueClippedToRange( double fAngle
, const double& fPositivLimit
)
898 if( fAngle
<-1*fPositivLimit
)
899 fAngle
=-1*fPositivLimit
;
900 else if( fAngle
>fPositivLimit
)
901 fAngle
=fPositivLimit
;
905 double ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()
910 double ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()
915 void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad
, double& rfYAngleRad
)
917 rfXAngleRad
= ThreeDHelper::getValueClippedToRange(rfXAngleRad
, BaseGFXHelper::Deg2Rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
918 rfYAngleRad
= ThreeDHelper::getValueClippedToRange(rfYAngleRad
, BaseGFXHelper::Deg2Rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
921 void ThreeDHelper::getRotationAngleFromDiagram(
922 const Reference
< beans::XPropertySet
>& xSceneProperties
, double& rfXAngleRad
, double& rfYAngleRad
, double& rfZAngleRad
)
924 //takes the camera and the transformation matrix into account
926 rfXAngleRad
= rfYAngleRad
= rfZAngleRad
= 0.0;
928 if( !xSceneProperties
.is() )
931 //get camera rotation
932 ::basegfx::B3DHomMatrix
aFixCameraRotationMatrix( lcl_getCameraMatrix( xSceneProperties
) );
933 BaseGFXHelper::ReduceToRotationMatrix( aFixCameraRotationMatrix
);
936 ::basegfx::B3DHomMatrix aSceneRotation
;
938 drawing::HomogenMatrix aHomMatrix
;
939 if( xSceneProperties
->getPropertyValue( "D3DTransformMatrix") >>= aHomMatrix
)
941 aSceneRotation
= BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aHomMatrix
);
942 BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation
);
946 ::basegfx::B3DHomMatrix aResultRotation
= aFixCameraRotationMatrix
* aSceneRotation
;
947 ::basegfx::B3DTuple
aRotation( BaseGFXHelper::GetRotationFromMatrix( aResultRotation
) );
949 rfXAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getX());
950 rfYAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getY());
951 rfZAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getZ());
953 if(rfZAngleRad
<(-F_PI
/2) || rfZAngleRad
>(F_PI
/2))
957 rfYAngleRad
=(F_PI
-rfYAngleRad
);
959 rfXAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfXAngleRad
);
960 rfYAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfYAngleRad
);
961 rfZAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfZAngleRad
);
965 void ThreeDHelper::switchRightAngledAxes( const Reference
< beans::XPropertySet
>& xSceneProperties
, sal_Bool bRightAngledAxes
, bool bRotateLights
)
969 if( xSceneProperties
.is() )
971 sal_Bool bOldRightAngledAxes
= sal_False
;
972 xSceneProperties
->getPropertyValue( "RightAngledAxes") >>= bOldRightAngledAxes
;
973 if( bOldRightAngledAxes
!=bRightAngledAxes
)
975 xSceneProperties
->setPropertyValue( "RightAngledAxes", uno::makeAny( bRightAngledAxes
));
980 ::basegfx::B3DHomMatrix
aInverseRotation( lcl_getInverseRotationMatrix( xSceneProperties
) );
981 lcl_rotateLights( aInverseRotation
, xSceneProperties
);
985 ::basegfx::B3DHomMatrix
aCompleteRotation( lcl_getCompleteRotationMatrix( xSceneProperties
) );
986 lcl_rotateLights( aCompleteRotation
, xSceneProperties
);
992 catch( const uno::Exception
& ex
)
994 ASSERT_EXCEPTION( ex
);
998 void ThreeDHelper::setRotationAngleToDiagram(
999 const Reference
< beans::XPropertySet
>& xSceneProperties
1000 , double fXAngleRad
, double fYAngleRad
, double fZAngleRad
)
1002 //the rotation of the camera is not touched but taken into account
1003 //the rotation difference is applied to the transformation matrix
1005 //the light sources will be adapted also
1007 if( !xSceneProperties
.is() )
1012 //remind old rotation for adaption of light directions
1013 ::basegfx::B3DHomMatrix
aInverseOldRotation( lcl_getInverseRotationMatrix( xSceneProperties
) );
1015 ::basegfx::B3DHomMatrix aInverseCameraRotation
;
1017 ::basegfx::B3DTuple
aR( BaseGFXHelper::GetRotationFromMatrix(
1018 lcl_getCameraMatrix( xSceneProperties
) ) );
1019 aInverseCameraRotation
.rotate( 0.0, 0.0, -aR
.getZ() );
1020 aInverseCameraRotation
.rotate( 0.0, -aR
.getY(), 0.0 );
1021 aInverseCameraRotation
.rotate( -aR
.getX(), 0.0, 0.0 );
1024 ::basegfx::B3DHomMatrix aCumulatedRotation
;
1025 aCumulatedRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
1027 //calculate new scene matrix
1028 ::basegfx::B3DHomMatrix aSceneRotation
= aInverseCameraRotation
*aCumulatedRotation
;
1029 BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation
);
1031 //set new rotation to transformation matrix
1032 xSceneProperties
->setPropertyValue(
1033 "D3DTransformMatrix", uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation
)));
1035 //rotate lights if RightAngledAxes are not set or not supported
1036 sal_Bool bRightAngledAxes
= sal_False
;
1037 xSceneProperties
->getPropertyValue( "RightAngledAxes") >>= bRightAngledAxes
;
1038 uno::Reference
< chart2::XDiagram
> xDiagram( xSceneProperties
, uno::UNO_QUERY
);
1039 if(!bRightAngledAxes
|| !ChartTypeHelper::isSupportingRightAngledAxes(
1040 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
1042 ::basegfx::B3DHomMatrix aNewRotation
;
1043 aNewRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
1044 lcl_rotateLights( aNewRotation
*aInverseOldRotation
, xSceneProperties
);
1047 catch( const uno::Exception
& ex
)
1049 ASSERT_EXCEPTION( ex
);
1053 void ThreeDHelper::getRotationFromDiagram( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
1054 , sal_Int32
& rnHorizontalAngleDegree
, sal_Int32
& rnVerticalAngleDegree
)
1056 double fXAngle
, fYAngle
, fZAngle
;
1057 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngle
, fYAngle
, fZAngle
);
1059 if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1061 ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
1062 rnHorizontalAngleDegree
, rnVerticalAngleDegree
, fXAngle
, fYAngle
, fZAngle
);
1063 rnVerticalAngleDegree
*=-1;
1067 fXAngle
= BaseGFXHelper::Rad2Deg( fXAngle
);
1068 fYAngle
= BaseGFXHelper::Rad2Deg( fYAngle
);
1069 fZAngle
= BaseGFXHelper::Rad2Deg( fZAngle
);
1071 rnHorizontalAngleDegree
= ::basegfx::fround(fXAngle
);
1072 rnVerticalAngleDegree
= ::basegfx::fround(-1.0*fYAngle
);
1073 //nZRotation = ::basegfx::fround(-1.0*fZAngle);
1076 lcl_shiftAngleToIntervalMinus180To180( rnHorizontalAngleDegree
);
1077 lcl_shiftAngleToIntervalMinus180To180( rnVerticalAngleDegree
);
1080 void ThreeDHelper::setRotationToDiagram( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
1081 , sal_Int32 nHorizontalAngleDegree
, sal_Int32 nVerticalYAngleDegree
)
1083 //todo: x and y is not equal to horz and vert in case of RightAngledAxes==false
1084 double fXAngle
= BaseGFXHelper::Deg2Rad( nHorizontalAngleDegree
);
1085 double fYAngle
= BaseGFXHelper::Deg2Rad( -1*nVerticalYAngleDegree
);
1086 double fZAngle
= 0.0;
1088 if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1089 ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
1090 nHorizontalAngleDegree
, -1*nVerticalYAngleDegree
, fXAngle
, fYAngle
, fZAngle
);
1092 ThreeDHelper::setRotationAngleToDiagram( xSceneProperties
, fXAngle
, fYAngle
, fZAngle
);
1095 void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance
, double& rfMaximumDistance
)
1097 rfMinimumDistance
= 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME
;//empiric value
1098 rfMaximumDistance
= 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME
;//empiric value
1101 void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance
)
1104 getCameraDistanceRange( fMin
, fMax
);
1105 if( rfCameraDistance
< fMin
)
1106 rfCameraDistance
= fMin
;
1107 if( rfCameraDistance
> fMax
)
1108 rfCameraDistance
= fMax
;
1111 double ThreeDHelper::getCameraDistance(
1112 const Reference
< beans::XPropertySet
>& xSceneProperties
)
1114 double fCameraDistance
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
1116 if( !xSceneProperties
.is() )
1117 return fCameraDistance
;
1121 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
1122 xSceneProperties
->getPropertyValue( "D3DCameraGeometry" ) >>= aCG
;
1123 ::basegfx::B3DVector
aVRP( BaseGFXHelper::Position3DToB3DVector( aCG
.vrp
) );
1124 fCameraDistance
= aVRP
.getLength();
1126 ensureCameraDistanceRange( fCameraDistance
);
1128 catch( const uno::Exception
& ex
)
1130 ASSERT_EXCEPTION( ex
);
1132 return fCameraDistance
;
1135 void ThreeDHelper::setCameraDistance(
1136 const Reference
< beans::XPropertySet
>& xSceneProperties
, double fCameraDistance
)
1138 if( !xSceneProperties
.is() )
1143 if( fCameraDistance
<= 0 )
1144 fCameraDistance
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
1146 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
1147 xSceneProperties
->getPropertyValue( "D3DCameraGeometry" ) >>= aCG
;
1148 ::basegfx::B3DVector
aVRP( BaseGFXHelper::Position3DToB3DVector( aCG
.vrp
) );
1149 if( ::basegfx::fTools::equalZero( aVRP
.getLength() ) )
1150 aVRP
= ::basegfx::B3DVector(0,0,1);
1151 aVRP
.setLength(fCameraDistance
);
1152 aCG
.vrp
= BaseGFXHelper::B3DVectorToPosition3D( aVRP
);
1154 xSceneProperties
->setPropertyValue( "D3DCameraGeometry", uno::makeAny( aCG
));
1156 catch( const uno::Exception
& ex
)
1158 ASSERT_EXCEPTION( ex
);
1162 double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance
)
1164 double fRet
= fCameraDistance
;
1166 ThreeDHelper::getCameraDistanceRange( fMin
, fMax
);
1167 //fMax <-> 0; fMin <->100
1169 double a
= 100.0*fMax
*fMin
/(fMax
-fMin
);
1172 fRet
= a
/fCameraDistance
+ b
;
1177 double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective
)
1179 double fRet
= fPerspective
;
1181 ThreeDHelper::getCameraDistanceRange( fMin
, fMax
);
1182 //fMax <-> 0; fMin <->100
1184 double a
= 100.0*fMax
*fMin
/(fMax
-fMin
);
1187 fRet
= a
/(fPerspective
- b
);
1192 ThreeDLookScheme
ThreeDHelper::detectScheme( const uno::Reference
< XDiagram
>& xDiagram
)
1194 ThreeDLookScheme aScheme
= ThreeDLookScheme_Unknown
;
1196 sal_Int32 nRoundedEdges
;
1197 sal_Int32 nObjectLines
;
1198 ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram
, nRoundedEdges
, nObjectLines
);
1200 //get shade mode and light settings:
1201 drawing::ShadeMode
aShadeMode( drawing::ShadeMode_SMOOTH
);
1202 uno::Reference
< beans::XPropertySet
> xDiagramProps( xDiagram
, uno::UNO_QUERY
);
1205 if( xDiagramProps
.is() )
1206 xDiagramProps
->getPropertyValue( "D3DSceneShadeMode" )>>= aShadeMode
;
1208 catch( const uno::Exception
& ex
)
1210 ASSERT_EXCEPTION( ex
);
1213 if( lcl_isSimpleScheme( aShadeMode
, nRoundedEdges
, nObjectLines
, xDiagram
) )
1215 if( lcl_isSimpleLightScheme(xDiagramProps
) )
1216 aScheme
= ThreeDLookScheme_Simple
;
1218 else if( lcl_isRealisticScheme( aShadeMode
, nRoundedEdges
, nObjectLines
) )
1220 if( lcl_isRealisticLightScheme(xDiagramProps
) )
1221 aScheme
= ThreeDLookScheme_Realistic
;
1227 void ThreeDHelper::setScheme( const uno::Reference
< XDiagram
>& xDiagram
, ThreeDLookScheme aScheme
)
1229 if( aScheme
== ThreeDLookScheme_Unknown
)
1232 drawing::ShadeMode aShadeMode
;
1233 sal_Int32 nRoundedEdges
;
1234 sal_Int32 nObjectLines
;
1236 if( aScheme
== ThreeDLookScheme_Simple
)
1237 lcl_setSimpleScheme(aShadeMode
,nRoundedEdges
,nObjectLines
,xDiagram
);
1239 lcl_setRealisticScheme(aShadeMode
,nRoundedEdges
,nObjectLines
);
1243 ThreeDHelper::setRoundedEdgesAndObjectLines( xDiagram
, nRoundedEdges
, nObjectLines
);
1245 uno::Reference
< beans::XPropertySet
> xProp( xDiagram
, uno::UNO_QUERY
);
1248 drawing::ShadeMode aOldShadeMode
;
1249 if( ! ( (xProp
->getPropertyValue( "D3DSceneShadeMode" )>>=aOldShadeMode
) &&
1250 aOldShadeMode
== aShadeMode
))
1252 xProp
->setPropertyValue( "D3DSceneShadeMode", uno::makeAny( aShadeMode
));
1256 lcl_setLightsForScheme( xProp
, aScheme
);
1258 catch( const uno::Exception
& ex
)
1260 ASSERT_EXCEPTION( ex
);
1265 void ThreeDHelper::set3DSettingsToDefault( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1267 Reference
< beans::XPropertyState
> xState( xSceneProperties
, uno::UNO_QUERY
);
1270 xState
->setPropertyToDefault( "D3DSceneDistance");
1271 xState
->setPropertyToDefault( "D3DSceneFocalLength");
1273 ThreeDHelper::setDefaultRotation( xSceneProperties
);
1274 ThreeDHelper::setDefaultIllumination( xSceneProperties
);
1277 void ThreeDHelper::setDefaultRotation( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
, bool bPieOrDonut
)
1279 if( !xSceneProperties
.is() )
1282 drawing::CameraGeometry
aCameraGeo( ThreeDHelper::getDefaultCameraGeometry( bPieOrDonut
) );
1283 xSceneProperties
->setPropertyValue( "D3DCameraGeometry", uno::makeAny( aCameraGeo
));
1285 ::basegfx::B3DHomMatrix aSceneRotation
;
1287 aSceneRotation
.rotate( -F_PI
/3.0, 0, 0 );
1288 xSceneProperties
->setPropertyValue( "D3DTransformMatrix",
1289 uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation
)));
1292 void ThreeDHelper::setDefaultRotation( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1294 bool bPieOrDonut( DiagramHelper::isPieOrDonutChart( uno::Reference
< XDiagram
>(xSceneProperties
, uno::UNO_QUERY
) ) );
1295 ThreeDHelper::setDefaultRotation( xSceneProperties
, bPieOrDonut
);
1298 void ThreeDHelper::setDefaultIllumination( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1300 if( !xSceneProperties
.is() )
1303 drawing::ShadeMode
aShadeMode( drawing::ShadeMode_SMOOTH
);
1306 xSceneProperties
->getPropertyValue( "D3DSceneShadeMode" )>>= aShadeMode
;
1307 xSceneProperties
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1
, uno::makeAny( sal_False
) );
1308 xSceneProperties
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3
, uno::makeAny( sal_False
) );
1309 xSceneProperties
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4
, uno::makeAny( sal_False
) );
1310 xSceneProperties
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5
, uno::makeAny( sal_False
) );
1311 xSceneProperties
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6
, uno::makeAny( sal_False
) );
1312 xSceneProperties
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7
, uno::makeAny( sal_False
) );
1313 xSceneProperties
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8
, uno::makeAny( sal_False
) );
1315 catch( const uno::Exception
& ex
)
1317 ASSERT_EXCEPTION( ex
);
1320 ThreeDLookScheme aScheme
= (drawing::ShadeMode_FLAT
==aShadeMode
) ? ThreeDLookScheme_Simple
: ThreeDLookScheme_Realistic
;
1321 lcl_setLightsForScheme( xSceneProperties
, aScheme
);
1324 void ThreeDHelper::getRoundedEdgesAndObjectLines(
1325 const uno::Reference
< XDiagram
> & xDiagram
1326 , sal_Int32
& rnRoundedEdges
, sal_Int32
& rnObjectLines
)
1328 rnRoundedEdges
= -1;
1332 bool bDifferentRoundedEdges
= false;
1333 bool bDifferentObjectLines
= false;
1335 drawing::LineStyle
aLineStyle( drawing::LineStyle_SOLID
);
1337 ::std::vector
< uno::Reference
< XDataSeries
> > aSeriesList(
1338 DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1339 sal_Int32 nSeriesCount
= static_cast<sal_Int32
>( aSeriesList
.size() );
1341 OUString
aPercentDiagonalPropertyName( "PercentDiagonal" );
1342 OUString
aBorderStylePropertyName( "BorderStyle" );
1344 for( sal_Int32 nS
= 0; nS
< nSeriesCount
; ++nS
)
1346 uno::Reference
< XDataSeries
> xSeries( aSeriesList
[nS
] );
1347 uno::Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
1353 sal_Int16 nPercentDiagonal
= 0;
1355 xProp
->getPropertyValue( aPercentDiagonalPropertyName
) >>= nPercentDiagonal
;
1356 rnRoundedEdges
= static_cast< sal_Int32
>( nPercentDiagonal
);
1358 if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1359 , aPercentDiagonalPropertyName
, uno::makeAny(nPercentDiagonal
) ) )
1360 bDifferentRoundedEdges
= true;
1362 catch( const uno::Exception
& e
)
1364 ASSERT_EXCEPTION( e
);
1365 bDifferentRoundedEdges
= true;
1369 xProp
->getPropertyValue( aBorderStylePropertyName
) >>= aLineStyle
;
1371 if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1372 , aBorderStylePropertyName
, uno::makeAny(aLineStyle
) ) )
1373 bDifferentObjectLines
= true;
1375 catch( const uno::Exception
& e
)
1377 ASSERT_EXCEPTION( e
);
1378 bDifferentObjectLines
= true;
1383 if( !bDifferentRoundedEdges
)
1385 sal_Int16 nPercentDiagonal
= 0;
1386 xProp
->getPropertyValue( aPercentDiagonalPropertyName
) >>= nPercentDiagonal
;
1387 sal_Int32 nCurrentRoundedEdges
= static_cast< sal_Int32
>( nPercentDiagonal
);
1388 if(nCurrentRoundedEdges
!=rnRoundedEdges
1389 || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1390 , aPercentDiagonalPropertyName
, uno::makeAny( static_cast< sal_Int16
>(rnRoundedEdges
) ) ) )
1392 bDifferentRoundedEdges
= true;
1393 nCurrentRoundedEdges
= -1;
1397 if( !bDifferentObjectLines
)
1399 drawing::LineStyle aCurrentLineStyle
;
1400 xProp
->getPropertyValue( aBorderStylePropertyName
) >>= aCurrentLineStyle
;
1401 if(aCurrentLineStyle
!=aLineStyle
1402 || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1403 , aBorderStylePropertyName
, uno::makeAny(aLineStyle
) ) )
1404 bDifferentObjectLines
= true;
1407 if( bDifferentRoundedEdges
&& bDifferentObjectLines
)
1413 if( bDifferentObjectLines
)
1415 else if( aLineStyle
== drawing::LineStyle_SOLID
)
1418 catch( const uno::Exception
& e
)
1420 ASSERT_EXCEPTION( e
);
1424 void ThreeDHelper::setRoundedEdgesAndObjectLines(
1425 const uno::Reference
< XDiagram
> & xDiagram
1426 , sal_Int32 nRoundedEdges
, sal_Int32 nObjectLines
)
1428 if( (nRoundedEdges
<0||nRoundedEdges
>100) && nObjectLines
!=0 && nObjectLines
!=1 )
1431 drawing::LineStyle
aLineStyle( drawing::LineStyle_NONE
);
1433 aLineStyle
= drawing::LineStyle_SOLID
;
1435 uno::Any
aALineStyle( uno::makeAny(aLineStyle
));
1436 uno::Any
aARoundedEdges( uno::makeAny( static_cast< sal_Int16
>( nRoundedEdges
)));
1438 ::std::vector
< uno::Reference
< XDataSeries
> > aSeriesList(
1439 DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1440 sal_Int32 nSeriesCount
= static_cast<sal_Int32
>( aSeriesList
.size() );
1441 for( sal_Int32 nS
= 0; nS
< nSeriesCount
; ++nS
)
1443 uno::Reference
< XDataSeries
> xSeries( aSeriesList
[nS
] );
1445 if( nRoundedEdges
>=0 && nRoundedEdges
<=100 )
1446 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries
, "PercentDiagonal", aARoundedEdges
);
1448 if( nObjectLines
==0 || nObjectLines
==1 )
1449 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries
, "BorderStyle", aALineStyle
);
1453 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1455 CuboidPlanePosition
eRet(CuboidPlanePosition_Left
);
1457 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1458 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1459 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1461 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1464 if( sin(fYAngleRad
)>0.0 )
1465 eRet
= CuboidPlanePosition_Right
;
1469 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1471 CuboidPlanePosition
eRet(CuboidPlanePosition_Back
);
1473 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1474 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1475 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1477 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1480 if( cos(fXAngleRad
)*cos(fYAngleRad
)<0.0 )
1481 eRet
= CuboidPlanePosition_Front
;
1485 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1487 CuboidPlanePosition
eRet(CuboidPlanePosition_Bottom
);
1489 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1490 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1491 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1493 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1496 if( sin(fXAngleRad
)*cos(fYAngleRad
)<0.0 )
1497 eRet
= CuboidPlanePosition_Top
;
1501 //.............................................................................
1503 //.............................................................................
1505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */