1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
31 #include "ThreeDHelper.hxx"
33 #include "DiagramHelper.hxx"
34 #include "ChartTypeHelper.hxx"
35 #include "BaseGFXHelper.hxx"
36 #include "DataSeriesHelper.hxx"
37 #include <editeng/unoprnms.hxx>
38 #include <com/sun/star/beans/XPropertyState.hpp>
39 #include <com/sun/star/chart2/XDiagram.hpp>
40 #include <com/sun/star/drawing/LineStyle.hpp>
42 #include <tools/debug.hxx>
44 //.............................................................................
47 //.............................................................................
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::chart2
;
51 using ::com::sun::star::uno::Reference
;
52 using ::com::sun::star::uno::Sequence
;
53 using ::rtl::OUString
;
54 using ::rtl::math::cos
;
55 using ::rtl::math::sin
;
56 using ::rtl::math::tan
;
58 #define FIXED_SIZE_FOR_3D_CHART_VOLUME (10000.0)
63 bool lcl_isRightAngledAxesSetAndSupported( const Reference
< beans::XPropertySet
>& xSceneProperties
)
65 sal_Bool bRightAngledAxes
= sal_False
;
66 if( xSceneProperties
.is() )
68 xSceneProperties
->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes
;
71 uno::Reference
< chart2::XDiagram
> xDiagram( xSceneProperties
, uno::UNO_QUERY
);
72 if( ChartTypeHelper::isSupportingRightAngledAxes(
73 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
82 void lcl_RotateLightSource( const Reference
< beans::XPropertySet
>& xSceneProperties
83 , const OUString
& rLightSourceDirection
84 , const OUString
& rLightSourceOn
85 , const ::basegfx::B3DHomMatrix
& rRotationMatrix
)
87 if( xSceneProperties
.is() )
89 sal_Bool bLightOn
= sal_False
;
90 if( xSceneProperties
->getPropertyValue( rLightSourceOn
) >>= bLightOn
)
94 drawing::Direction3D aLight
;
95 if( xSceneProperties
->getPropertyValue( rLightSourceDirection
) >>= aLight
)
97 ::basegfx::B3DVector
aLightVector( BaseGFXHelper::Direction3DToB3DVector( aLight
) );
98 aLightVector
= rRotationMatrix
*aLightVector
;
100 xSceneProperties
->setPropertyValue( rLightSourceDirection
101 , uno::makeAny( BaseGFXHelper::B3DVectorToDirection3D( aLightVector
) ) );
108 void lcl_rotateLights( const ::basegfx::B3DHomMatrix
& rLightRottion
, const Reference
< beans::XPropertySet
>& xSceneProperties
)
110 if(!xSceneProperties
.is())
113 ::basegfx::B3DHomMatrix
aLightRottion( rLightRottion
);
114 BaseGFXHelper::ReduceToRotationMatrix( aLightRottion
);
116 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection1"), C2U("D3DSceneLightOn1"), aLightRottion
);
117 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection2"), C2U("D3DSceneLightOn2"), aLightRottion
);
118 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection3"), C2U("D3DSceneLightOn3"), aLightRottion
);
119 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection4"), C2U("D3DSceneLightOn4"), aLightRottion
);
120 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection5"), C2U("D3DSceneLightOn5"), aLightRottion
);
121 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection6"), C2U("D3DSceneLightOn6"), aLightRottion
);
122 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection7"), C2U("D3DSceneLightOn7"), aLightRottion
);
123 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection8"), C2U("D3DSceneLightOn8"), aLightRottion
);
126 ::basegfx::B3DHomMatrix
lcl_getInverseRotationMatrix( const Reference
< beans::XPropertySet
>& xSceneProperties
)
128 ::basegfx::B3DHomMatrix aInverseRotation
;
129 double fXAngleRad
=0.0;
130 double fYAngleRad
=0.0;
131 double fZAngleRad
=0.0;
132 ThreeDHelper::getRotationAngleFromDiagram(
133 xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
134 aInverseRotation
.rotate( 0.0, 0.0, -fZAngleRad
);
135 aInverseRotation
.rotate( 0.0, -fYAngleRad
, 0.0 );
136 aInverseRotation
.rotate( -fXAngleRad
, 0.0, 0.0 );
137 return aInverseRotation
;
140 ::basegfx::B3DHomMatrix
lcl_getCompleteRotationMatrix( const Reference
< beans::XPropertySet
>& xSceneProperties
)
142 ::basegfx::B3DHomMatrix aCompleteRotation
;
143 double fXAngleRad
=0.0;
144 double fYAngleRad
=0.0;
145 double fZAngleRad
=0.0;
146 ThreeDHelper::getRotationAngleFromDiagram(
147 xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
148 aCompleteRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
149 return aCompleteRotation
;
152 bool lcl_isEqual( const drawing::Direction3D
& rA
, const drawing::Direction3D
& rB
)
154 return ::rtl::math::approxEqual(rA
.DirectionX
, rB
.DirectionX
)
155 && ::rtl::math::approxEqual(rA
.DirectionY
, rB
.DirectionY
)
156 && ::rtl::math::approxEqual(rA
.DirectionZ
, rB
.DirectionZ
);
159 bool lcl_isLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
, bool bRealistic
)
161 if(!xDiagramProps
.is())
164 sal_Bool bIsOn
= sal_False
;
165 xDiagramProps
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2
) ) >>= bIsOn
;
169 uno::Reference
< chart2::XDiagram
> xDiagram( xDiagramProps
, uno::UNO_QUERY
);
170 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
172 sal_Int32 nColor
= 0;
173 xDiagramProps
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
) ) >>= nColor
;
174 if( nColor
!= ::chart::ChartTypeHelper::getDefaultDirectLightColor( !bRealistic
, xChartType
) )
177 sal_Int32 nAmbientColor
= 0;
178 xDiagramProps
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR
) ) >>= nAmbientColor
;
179 if( nAmbientColor
!= ::chart::ChartTypeHelper::getDefaultAmbientLightColor( !bRealistic
, xChartType
) )
182 drawing::Direction3D
aDirection(0,0,0);
183 xDiagramProps
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
) ) >>= aDirection
;
185 drawing::Direction3D
aDefaultDirection( bRealistic
186 ? ChartTypeHelper::getDefaultRealisticLightDirection(xChartType
)
187 : ChartTypeHelper::getDefaultSimpleLightDirection(xChartType
) );
189 //rotate default light direction when right angled axes are off but supported
191 sal_Bool bRightAngledAxes
= sal_False
;
192 xDiagramProps
->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes
;
193 if(!bRightAngledAxes
)
195 if( ChartTypeHelper::isSupportingRightAngledAxes(
196 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
198 ::basegfx::B3DHomMatrix
aRotation( lcl_getCompleteRotationMatrix( xDiagramProps
) );
199 BaseGFXHelper::ReduceToRotationMatrix( aRotation
);
200 ::basegfx::B3DVector
aLightVector( BaseGFXHelper::Direction3DToB3DVector( aDefaultDirection
) );
201 aLightVector
= aRotation
*aLightVector
;
202 aDefaultDirection
= BaseGFXHelper::B3DVectorToDirection3D( aLightVector
);
207 return lcl_isEqual( aDirection
, aDefaultDirection
);
210 bool lcl_isRealisticLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
)
212 return lcl_isLightScheme( xDiagramProps
, true /*bRealistic*/ );
214 bool lcl_isSimpleLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
)
216 return lcl_isLightScheme( xDiagramProps
, false /*bRealistic*/ );
218 void lcl_setLightsForScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
, const ThreeDLookScheme
& rScheme
)
220 if(!xDiagramProps
.is())
222 if( rScheme
== ThreeDLookScheme_Unknown
)
225 xDiagramProps
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2
), uno::makeAny( sal_True
) );
227 uno::Reference
< chart2::XDiagram
> xDiagram( xDiagramProps
, uno::UNO_QUERY
);
228 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
229 uno::Any
aADirection( uno::makeAny( rScheme
== ThreeDLookScheme_Simple
230 ? ChartTypeHelper::getDefaultSimpleLightDirection(xChartType
)
231 : ChartTypeHelper::getDefaultRealisticLightDirection(xChartType
) ) );
233 xDiagramProps
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
), aADirection
);
234 //rotate light direction when right angled axes are off but supported
236 sal_Bool bRightAngledAxes
= sal_False
;
237 xDiagramProps
->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes
;
238 if(!bRightAngledAxes
)
240 if( ChartTypeHelper::isSupportingRightAngledAxes( xChartType
) )
242 ::basegfx::B3DHomMatrix
aRotation( lcl_getCompleteRotationMatrix( xDiagramProps
) );
243 BaseGFXHelper::ReduceToRotationMatrix( aRotation
);
244 lcl_RotateLightSource( xDiagramProps
, C2U("D3DSceneLightDirection2"), C2U("D3DSceneLightOn2"), aRotation
);
249 sal_Int32 nColor
= ::chart::ChartTypeHelper::getDefaultDirectLightColor( rScheme
==ThreeDLookScheme_Simple
, xChartType
);
250 xDiagramProps
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
), uno::makeAny( nColor
) );
252 sal_Int32 nAmbientColor
= ::chart::ChartTypeHelper::getDefaultAmbientLightColor( rScheme
==ThreeDLookScheme_Simple
, xChartType
);
253 xDiagramProps
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR
), uno::makeAny( nAmbientColor
) );
256 bool lcl_isRealisticScheme( drawing::ShadeMode aShadeMode
257 , sal_Int32 nRoundedEdges
258 , sal_Int32 nObjectLines
)
260 if(aShadeMode
!=drawing::ShadeMode_SMOOTH
)
269 bool lcl_isSimpleScheme( drawing::ShadeMode aShadeMode
270 , sal_Int32 nRoundedEdges
271 , sal_Int32 nObjectLines
272 , const uno::Reference
< XDiagram
>& xDiagram
)
274 if(aShadeMode
!=drawing::ShadeMode_FLAT
)
280 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
281 return ChartTypeHelper::noBordersForSimpleScheme( xChartType
);
288 void lcl_setRealisticScheme( drawing::ShadeMode
& rShadeMode
289 , sal_Int32
& rnRoundedEdges
290 , sal_Int32
& rnObjectLines
)
292 rShadeMode
= drawing::ShadeMode_SMOOTH
;
297 void lcl_setSimpleScheme( drawing::ShadeMode
& rShadeMode
298 , sal_Int32
& rnRoundedEdges
299 , sal_Int32
& rnObjectLines
300 , const uno::Reference
< XDiagram
>& xDiagram
)
302 rShadeMode
= drawing::ShadeMode_FLAT
;
305 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
306 rnObjectLines
= ChartTypeHelper::noBordersForSimpleScheme( xChartType
) ? 0 : 1;
309 } //end anonymous namespace
312 drawing::CameraGeometry
ThreeDHelper::getDefaultCameraGeometry( bool bPie
)
314 // ViewReferencePoint (Point on the View plane)
315 drawing::Position3D
vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
316 // ViewPlaneNormal (Normal to the View Plane)
317 drawing::Direction3D
vpn(0.416199821709347, 0.173649045905254, 0.892537795986984);
318 // ViewUpVector (determines the v-axis direction on the view plane as
319 // projection of VUP parallel to VPN onto th view pane)
320 drawing::Direction3D
vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
324 vrp
= drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspecitve
325 vpn
= drawing::Direction3D( 0.0, 0.0, 1.0 );
326 vup
= drawing::Direction3D( 0.0, 1.0, 0.0 );
329 return drawing::CameraGeometry( vrp
, vpn
, vup
);
334 ::basegfx::B3DHomMatrix
lcl_getCameraMatrix( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
336 drawing::HomogenMatrix aCameraMatrix
;
338 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
339 if( xSceneProperties
.is() )
340 xSceneProperties
->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG
;
342 ::basegfx::B3DVector
aVPN( BaseGFXHelper::Direction3DToB3DVector( aCG
.vpn
) );
343 ::basegfx::B3DVector
aVUP( BaseGFXHelper::Direction3DToB3DVector( aCG
.vup
) );
349 ::basegfx::B3DVector aCross
= ::basegfx::cross( aVUP
, aVPN
);
351 //first line is VUP x VPN
352 aCameraMatrix
.Line1
.Column1
= aCross
[0];
353 aCameraMatrix
.Line1
.Column2
= aCross
[1];
354 aCameraMatrix
.Line1
.Column3
= aCross
[2];
355 aCameraMatrix
.Line1
.Column4
= 0.0;
358 aCameraMatrix
.Line2
.Column1
= aVUP
[0];
359 aCameraMatrix
.Line2
.Column2
= aVUP
[1];
360 aCameraMatrix
.Line2
.Column3
= aVUP
[2];
361 aCameraMatrix
.Line2
.Column4
= 0.0;
364 aCameraMatrix
.Line3
.Column1
= aVPN
[0];
365 aCameraMatrix
.Line3
.Column2
= aVPN
[1];
366 aCameraMatrix
.Line3
.Column3
= aVPN
[2];
367 aCameraMatrix
.Line3
.Column4
= 0.0;
369 //fourth line is 0 0 0 1
370 aCameraMatrix
.Line4
.Column1
= 0.0;
371 aCameraMatrix
.Line4
.Column2
= 0.0;
372 aCameraMatrix
.Line4
.Column3
= 0.0;
373 aCameraMatrix
.Line4
.Column4
= 1.0;
375 return BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aCameraMatrix
);
378 double lcl_shiftAngleToIntervalMinusPiToPi( double fAngleRad
)
380 //valid range: ]-Pi,Pi]
381 while( fAngleRad
<=-F_PI
)
383 while( fAngleRad
>F_PI
)
388 void lcl_shiftAngleToIntervalMinus180To180( sal_Int32
& rnAngleDegree
)
390 //valid range: ]-180,180]
391 while( rnAngleDegree
<=-180 )
393 while( rnAngleDegree
>180 )
397 void lcl_shiftAngleToIntervalZeroTo360( sal_Int32
& rnAngleDegree
)
399 //valid range: [0,360[
400 while( rnAngleDegree
<0 )
402 while( rnAngleDegree
>=360 )
406 void lcl_ensureIntervalMinus1To1( double& rSinOrCos
)
408 if (rSinOrCos
< -1.0)
410 else if (rSinOrCos
> 1.0)
414 bool lcl_isSinZero( double fAngleRad
)
416 return ::basegfx::fTools::equalZero( sin(fAngleRad
), 0.0000001 );
418 bool lcl_isCosZero( double fAngleRad
)
420 return ::basegfx::fTools::equalZero( cos(fAngleRad
), 0.0000001 );
425 void ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
426 sal_Int32 nElevationDeg
, sal_Int32 nRotationDeg
,
427 double& rfXAngleRad
, double& rfYAngleRad
, double& rfZAngleRad
)
429 // for a description of the algorithm see issue 72994
430 //http://www.openoffice.org/issues/show_bug.cgi?id=72994
431 //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
433 lcl_shiftAngleToIntervalZeroTo360( nElevationDeg
);
434 lcl_shiftAngleToIntervalZeroTo360( nRotationDeg
);
436 double& x
= rfXAngleRad
;
437 double& y
= rfYAngleRad
;
438 double& z
= rfZAngleRad
;
440 double E
= F_PI
*nElevationDeg
/180; //elevation in Rad
441 double R
= F_PI
*nRotationDeg
/180; //rotation in Rad
443 if( (nRotationDeg
== 0 || nRotationDeg
== 180 )
444 && ( nElevationDeg
== 90 || nElevationDeg
== 270 ) )
449 double f23
= cos(R
)*sin(E
);
456 else if( ( nRotationDeg
== 90 || nRotationDeg
== 270 )
457 && ( nElevationDeg
== 90 || nElevationDeg
== 270 ) )
466 if( (sin(R
)*sin(E
))>0 )
471 else if( (nRotationDeg
== 0 || nRotationDeg
== 180 )
472 && ( nElevationDeg
== 0 || nElevationDeg
== 180 ) )
479 else if( ( nRotationDeg
== 90 || nRotationDeg
== 270 )
480 && ( nElevationDeg
== 0 || nElevationDeg
== 180 ) )
485 if( (sin(R
)/cos(E
))>0 )
495 else if ( nElevationDeg
== 0 || nElevationDeg
== 180 )
501 //use element 13 for sign
502 if((cos(x
)*sin(y
)*sin(R
))<0.0)
505 else if ( nElevationDeg
== 90 || nElevationDeg
== 270 )
508 //element 12 + 22 --> y=0 or F_PI and x=+-F_PI/2
510 z
= atan(sin(R
)/(cos(R
)*sin(E
)));
511 //use element 13 for sign for x
512 if( (sin(R
)*sin(z
))>0.0 )
516 //use element 21 for y
517 if( (sin(R
)*sin(E
)*sin(z
))>0.0)
522 else if ( nRotationDeg
== 0 || nRotationDeg
== 180 )
528 double f23
= cos(R
)*sin(E
);
529 if( (f23
* sin(x
)) < 0.0 )
532 else if (nRotationDeg
== 90 || nRotationDeg
== 270)
541 x
*= -1.0; //different signs for x and z
544 double cy
= sR
*sin(E
)/sin(z
);
545 lcl_ensureIntervalMinus1To1(cy
);
548 //use element 22 for sign:
549 if( (sin(x
)*sin(y
)*sin(z
)*cos(E
))<0.0)
554 z
= atan(tan(R
) * sin(E
));
557 DBG_ERROR("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
560 double cy
= cos(R
)/cos(z
);
561 lcl_ensureIntervalMinus1To1(cy
);
565 double fDenominator
= cos(z
)*(1.0-pow(sin(y
),2));
566 if(fDenominator
==0.0)
568 DBG_ERROR("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
571 double sx
= cos(R
)*sin(E
)/fDenominator
;
572 lcl_ensureIntervalMinus1To1(sx
);
575 //use element 13 for sign:
576 double f13a
= cos(x
)*cos(z
)*sin(y
);
577 double f13b
= sin(R
)-sx
*sin(z
);
578 if( (f13b
*f13a
)<0.0 )
581 //use element 22 for further investigations:
584 double f22a
= cos(x
)*cos(z
);
585 double f22b
= cos(E
)-(sx
*sin(y
)*sin(z
));
586 if( (f22a
*f22b
)<0.0 )
594 //change nothing or both
595 //use element 22 for further investigations:
596 double f22a
= cos(x
)*cos(z
);
597 double f22b
= cos(E
)-(sx
*sin(y
)*sin(z
));
598 if( (f22a
*f22b
)<0.0 )
607 void ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
608 sal_Int32
& rnElevationDeg
, sal_Int32
& rnRotationDeg
,
609 double fXRad
, double fYRad
, double fZRad
)
611 // for a description of the algorithm see issue 72994
612 //http://www.openoffice.org/issues/show_bug.cgi?id=72994
613 //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
615 double R
= 0.0; //Rotation in Rad
616 double E
= 0.0; //Elevation in Rad
622 double f11
= cos(y
)*cos(z
);
624 if( lcl_isSinZero(y
) )
628 if( lcl_isCosZero(x
) )
630 //siny == 0 && cosx == 0
632 if( lcl_isSinZero(z
) )
634 //siny == 0 && cosx == 0 && sinz == 0
635 //example: x=+-90 y=0oder180 z=0(oder180)
644 double f23
= cos(z
)*sin(x
) / cos(R
);
650 else if( lcl_isCosZero(z
) )
652 //siny == 0 && cosx == 0 && cosz == 0
653 //example: x=+-90 y=0oder180 z=+-90
655 double f13
= sin(x
)*sin(z
);
663 double f21
= cos(y
)*sin(z
) / sin(R
);
671 //siny == 0 && cosx == 0 && cosz != 0 && sinz != 0
673 double f13
= sin(x
)*sin(z
);
680 double f23
= cos(z
)*sin(x
);
687 else if( lcl_isSinZero(x
) )
696 double f22
= cos(x
)*cos(z
);
702 else if( lcl_isSinZero(z
) )
704 //sinY==0 sinZ==0 sinx!=0 cosx!=0
712 double f22
= cos(x
)*cos(z
);
713 double f23
= cos(z
)*sin(x
);
714 E
= atan( f23
/(f22
*cos(R
)) );
718 else if( lcl_isCosZero(z
) )
720 //sinY == 0 && cosZ == 0 && cosx != 0 && sinx != 0
721 double f13
= sin(x
)*sin(z
);
729 double f21
= cos(y
)*sin(z
);
737 //sinY == 0 && all other !=0
738 double f13
= sin(x
)*sin(z
);
740 if( (f11
*cos(R
))<0.0 )
743 double f22
= cos(x
)*cos(z
);
744 if( !lcl_isCosZero(R
) )
745 E
= atan( cos(z
)*sin(x
) /( f22
*cos(R
) ) );
747 E
= atan( cos(y
)*sin(z
) /( f22
*sin(R
) ) );
752 else if( lcl_isCosZero(y
) )
756 double f13
= sin(x
)*sin(z
)+cos(x
)*cos(z
)*sin(y
);
762 double f22
= cos(x
)*cos(z
)+sin(x
)*sin(y
)*sin(z
);
768 else if( lcl_isSinZero(x
) )
770 //cosY!=0 sinY!=0 sinX=0
771 if( lcl_isSinZero(z
) )
773 //cosY!=0 sinY!=0 sinX=0 sinZ=0
774 double f13
= cos(x
)*cos(z
)*sin(y
);
780 double f22
= cos(x
)*cos(z
);
786 else if( lcl_isCosZero(z
) )
788 //cosY!=0 sinY!=0 sinX=0 cosZ=0
792 double f23
= -1.0*cos(x
)*sin(y
)*sin(z
);
793 if( (f23
*cos(R
)*sin(E
))<0.0 )
801 //cosY!=0 sinY!=0 sinX=0 sinZ!=0 cosZ!=0
802 double f13
= cos(x
)*cos(z
)*sin(y
);
808 double f21
= cos(y
)*sin(z
);
809 double f22
= cos(x
)*cos(z
);
810 E
= atan(f21
/(f22
*sin(R
)) );
812 if( (f22
*cos(E
))<0.0 )
816 else if( lcl_isCosZero(x
) )
818 //cosY!=0 sinY!=0 cosX=0
820 if( lcl_isSinZero(z
) )
822 //cosY!=0 sinY!=0 cosX=0 sinZ=0
823 R
=0;//13 -> R=0 or F_PI
826 E
=F_PI
/2;//22 -> E=+-F_PI/2
827 //use element 11 and 23 for sign
828 double f23
= cos(z
)*sin(x
);
829 if( (f11
*f23
*sin(E
))<0.0 )
832 else if( lcl_isCosZero(z
) )
834 //cosY!=0 sinY!=0 cosX=0 cosZ=0
836 if( (sin(x
)*sin(z
))>0.0 )
841 E
=acos( sin(x
)*sin(y
)*sin(z
));
842 //use element 21 for sign:
843 if( (cos(y
)*sin(z
)*sin(R
)*sin(E
))<0.0 )
848 //cosY!=0 sinY!=0 cosX=0 sinZ!=0 cosZ!=0
850 R
= atan( sin(x
)*sin(z
)/(cos(y
)*cos(z
)) );
852 if( (sin(x
)*sin(z
))<0.0 )
855 E
= acos(sin(x
)*sin(y
)*sin(z
) );
857 if( (cos(y
)*sin(z
)*sin(R
)*sin(E
))<0.0 )
861 else if( lcl_isSinZero(z
) )
863 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ=0
866 //use elenment 13 for sign
867 if( (cos(x
)*cos(z
)*sin(y
)*sin(R
))<0.0 )
870 E
= acos( cos(x
)*cos(z
) );
871 //use element 23 for sign
872 if( (cos(z
)*sin(x
)*cos(R
)*sin(E
))<0.0 )
875 else if( lcl_isCosZero(z
) )
877 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 cosZ=0
879 R
=atan(-cos(y
)/(cos(x
)*sin(y
)));
880 //use element 13 for 'sign'
881 if( (sin(x
)*sin(z
)*sin(R
))<0.0 )
884 E
=atan( cos(y
)*sin(z
)/(sin(R
)*sin(x
)*sin(y
)*sin(z
)) );
885 //use element 23 for 'sign'
886 if( (-cos(x
)*sin(y
)*sin(z
)*cos(R
)*sin(E
))<0.0 )
891 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ!=0 cosZ!=0
893 double f13
= sin(x
)*sin(z
)+cos(x
)*cos(z
)*sin(y
);
894 R
= atan( f13
/ f11
);
897 double f22
= cos(x
)*cos(z
)+sin(x
)*sin(y
)*sin(z
);
898 double f23
= cos(x
)*sin(y
)*sin(z
)-cos(z
)*sin(x
);
900 E
= atan( -1.0*f23
/(f22
*cos(R
)) );
905 rnElevationDeg
= ::basegfx::fround( BaseGFXHelper::Rad2Deg( E
) );
906 rnRotationDeg
= ::basegfx::fround( BaseGFXHelper::Rad2Deg( R
) );
909 double ThreeDHelper::getValueClippedToRange( double fAngle
, const double& fPositivLimit
)
911 if( fAngle
<-1*fPositivLimit
)
912 fAngle
=-1*fPositivLimit
;
913 else if( fAngle
>fPositivLimit
)
914 fAngle
=fPositivLimit
;
918 double ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()
923 double ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()
928 void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad
, double& rfYAngleRad
)
930 rfXAngleRad
= ThreeDHelper::getValueClippedToRange(rfXAngleRad
, BaseGFXHelper::Deg2Rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
931 rfYAngleRad
= ThreeDHelper::getValueClippedToRange(rfYAngleRad
, BaseGFXHelper::Deg2Rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
934 void ThreeDHelper::getRotationAngleFromDiagram(
935 const Reference
< beans::XPropertySet
>& xSceneProperties
, double& rfXAngleRad
, double& rfYAngleRad
, double& rfZAngleRad
)
937 //takes the camera and the transformation matrix into account
939 rfXAngleRad
= rfYAngleRad
= rfZAngleRad
= 0.0;
941 if( !xSceneProperties
.is() )
944 //get camera rotation
945 ::basegfx::B3DHomMatrix
aFixCameraRotationMatrix( lcl_getCameraMatrix( xSceneProperties
) );
946 BaseGFXHelper::ReduceToRotationMatrix( aFixCameraRotationMatrix
);
949 ::basegfx::B3DHomMatrix aSceneRotation
;
951 drawing::HomogenMatrix aHomMatrix
;
952 if( xSceneProperties
->getPropertyValue( C2U("D3DTransformMatrix")) >>= aHomMatrix
)
954 aSceneRotation
= BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aHomMatrix
);
955 BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation
);
959 ::basegfx::B3DHomMatrix aResultRotation
= aFixCameraRotationMatrix
* aSceneRotation
;
960 ::basegfx::B3DTuple
aRotation( BaseGFXHelper::GetRotationFromMatrix( aResultRotation
) );
962 rfXAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getX());
963 rfYAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getY());
964 rfZAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getZ());
966 if(rfZAngleRad
<(-F_PI
/2) || rfZAngleRad
>(F_PI
/2))
970 rfYAngleRad
=(F_PI
-rfYAngleRad
);
972 rfXAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfXAngleRad
);
973 rfYAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfYAngleRad
);
974 rfZAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfZAngleRad
);
978 void ThreeDHelper::switchRightAngledAxes( const Reference
< beans::XPropertySet
>& xSceneProperties
, sal_Bool bRightAngledAxes
, bool bRotateLights
)
982 if( xSceneProperties
.is() )
984 sal_Bool bOldRightAngledAxes
= sal_False
;
985 xSceneProperties
->getPropertyValue( C2U("RightAngledAxes")) >>= bOldRightAngledAxes
;
986 if( bOldRightAngledAxes
!=bRightAngledAxes
)
988 xSceneProperties
->setPropertyValue( C2U("RightAngledAxes"), uno::makeAny( bRightAngledAxes
));
993 ::basegfx::B3DHomMatrix
aInverseRotation( lcl_getInverseRotationMatrix( xSceneProperties
) );
994 lcl_rotateLights( aInverseRotation
, xSceneProperties
);
998 ::basegfx::B3DHomMatrix
aCompleteRotation( lcl_getCompleteRotationMatrix( xSceneProperties
) );
999 lcl_rotateLights( aCompleteRotation
, xSceneProperties
);
1005 catch( const uno::Exception
& ex
)
1007 ASSERT_EXCEPTION( ex
);
1011 void ThreeDHelper::setRotationAngleToDiagram(
1012 const Reference
< beans::XPropertySet
>& xSceneProperties
1013 , double fXAngleRad
, double fYAngleRad
, double fZAngleRad
)
1015 //the rotation of the camera is not touched but taken into account
1016 //the rotation difference is applied to the transformation matrix
1018 //the light sources will be adapted also
1020 if( !xSceneProperties
.is() )
1025 //remind old rotation for adaption of light directions
1026 ::basegfx::B3DHomMatrix
aInverseOldRotation( lcl_getInverseRotationMatrix( xSceneProperties
) );
1028 ::basegfx::B3DHomMatrix aInverseCameraRotation
;
1030 ::basegfx::B3DTuple
aR( BaseGFXHelper::GetRotationFromMatrix(
1031 lcl_getCameraMatrix( xSceneProperties
) ) );
1032 aInverseCameraRotation
.rotate( 0.0, 0.0, -aR
.getZ() );
1033 aInverseCameraRotation
.rotate( 0.0, -aR
.getY(), 0.0 );
1034 aInverseCameraRotation
.rotate( -aR
.getX(), 0.0, 0.0 );
1037 ::basegfx::B3DHomMatrix aCumulatedRotation
;
1038 aCumulatedRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
1040 //calculate new scene matrix
1041 ::basegfx::B3DHomMatrix aSceneRotation
= aInverseCameraRotation
*aCumulatedRotation
;
1042 BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation
);
1044 //set new rotation to transformation matrix
1045 xSceneProperties
->setPropertyValue(
1046 C2U("D3DTransformMatrix"), uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation
)));
1048 //rotate lights if RightAngledAxes are not set or not supported
1049 sal_Bool bRightAngledAxes
= sal_False
;
1050 xSceneProperties
->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes
;
1051 uno::Reference
< chart2::XDiagram
> xDiagram( xSceneProperties
, uno::UNO_QUERY
);
1052 if(!bRightAngledAxes
|| !ChartTypeHelper::isSupportingRightAngledAxes(
1053 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
1055 ::basegfx::B3DHomMatrix aNewRotation
;
1056 aNewRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
1057 lcl_rotateLights( aNewRotation
*aInverseOldRotation
, xSceneProperties
);
1060 catch( const uno::Exception
& ex
)
1062 ASSERT_EXCEPTION( ex
);
1066 void ThreeDHelper::getRotationFromDiagram( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
1067 , sal_Int32
& rnHorizontalAngleDegree
, sal_Int32
& rnVerticalAngleDegree
)
1069 double fXAngle
, fYAngle
, fZAngle
;
1070 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngle
, fYAngle
, fZAngle
);
1072 if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1074 ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
1075 rnHorizontalAngleDegree
, rnVerticalAngleDegree
, fXAngle
, fYAngle
, fZAngle
);
1076 rnVerticalAngleDegree
*=-1;
1080 fXAngle
= BaseGFXHelper::Rad2Deg( fXAngle
);
1081 fYAngle
= BaseGFXHelper::Rad2Deg( fYAngle
);
1082 fZAngle
= BaseGFXHelper::Rad2Deg( fZAngle
);
1084 rnHorizontalAngleDegree
= ::basegfx::fround(fXAngle
);
1085 rnVerticalAngleDegree
= ::basegfx::fround(-1.0*fYAngle
);
1086 //nZRotation = ::basegfx::fround(-1.0*fZAngle);
1089 lcl_shiftAngleToIntervalMinus180To180( rnHorizontalAngleDegree
);
1090 lcl_shiftAngleToIntervalMinus180To180( rnVerticalAngleDegree
);
1093 void ThreeDHelper::setRotationToDiagram( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
1094 , sal_Int32 nHorizontalAngleDegree
, sal_Int32 nVerticalYAngleDegree
)
1096 //todo: x and y is not equal to horz and vert in case of RightAngledAxes==false
1097 double fXAngle
= BaseGFXHelper::Deg2Rad( nHorizontalAngleDegree
);
1098 double fYAngle
= BaseGFXHelper::Deg2Rad( -1*nVerticalYAngleDegree
);
1099 double fZAngle
= 0.0;
1101 if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1102 ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
1103 nHorizontalAngleDegree
, -1*nVerticalYAngleDegree
, fXAngle
, fYAngle
, fZAngle
);
1105 ThreeDHelper::setRotationAngleToDiagram( xSceneProperties
, fXAngle
, fYAngle
, fZAngle
);
1108 void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance
, double& rfMaximumDistance
)
1110 rfMinimumDistance
= 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME
;//empiric value
1111 rfMaximumDistance
= 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME
;//empiric value
1114 void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance
)
1117 getCameraDistanceRange( fMin
, fMax
);
1118 if( rfCameraDistance
< fMin
)
1119 rfCameraDistance
= fMin
;
1120 if( rfCameraDistance
> fMax
)
1121 rfCameraDistance
= fMax
;
1124 double ThreeDHelper::getCameraDistance(
1125 const Reference
< beans::XPropertySet
>& xSceneProperties
)
1127 double fCameraDistance
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
1129 if( !xSceneProperties
.is() )
1130 return fCameraDistance
;
1134 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
1135 xSceneProperties
->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG
;
1136 ::basegfx::B3DVector
aVRP( BaseGFXHelper::Position3DToB3DVector( aCG
.vrp
) );
1137 fCameraDistance
= aVRP
.getLength();
1139 ensureCameraDistanceRange( fCameraDistance
);
1141 catch( const uno::Exception
& ex
)
1143 ASSERT_EXCEPTION( ex
);
1145 return fCameraDistance
;
1148 void ThreeDHelper::setCameraDistance(
1149 const Reference
< beans::XPropertySet
>& xSceneProperties
, double fCameraDistance
)
1151 if( !xSceneProperties
.is() )
1156 if( fCameraDistance
<= 0 )
1157 fCameraDistance
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
1159 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
1160 xSceneProperties
->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG
;
1161 ::basegfx::B3DVector
aVRP( BaseGFXHelper::Position3DToB3DVector( aCG
.vrp
) );
1162 if( ::basegfx::fTools::equalZero( aVRP
.getLength() ) )
1163 aVRP
= ::basegfx::B3DVector(0,0,1);
1164 aVRP
.setLength(fCameraDistance
);
1165 aCG
.vrp
= BaseGFXHelper::B3DVectorToPosition3D( aVRP
);
1167 xSceneProperties
->setPropertyValue( C2U("D3DCameraGeometry"), uno::makeAny( aCG
));
1169 catch( const uno::Exception
& ex
)
1171 ASSERT_EXCEPTION( ex
);
1176 double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance
)
1178 double fRet
= fCameraDistance
;
1180 ThreeDHelper::getCameraDistanceRange( fMin
, fMax
);
1181 //fMax <-> 0; fMin <->100
1183 double a
= 100.0*fMax
*fMin
/(fMax
-fMin
);
1186 fRet
= a
/fCameraDistance
+ b
;
1192 double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective
)
1194 double fRet
= fPerspective
;
1196 ThreeDHelper::getCameraDistanceRange( fMin
, fMax
);
1197 //fMax <-> 0; fMin <->100
1199 double a
= 100.0*fMax
*fMin
/(fMax
-fMin
);
1202 fRet
= a
/(fPerspective
- b
);
1208 ThreeDLookScheme
ThreeDHelper::detectScheme( const uno::Reference
< XDiagram
>& xDiagram
)
1210 ThreeDLookScheme aScheme
= ThreeDLookScheme_Unknown
;
1212 sal_Int32 nRoundedEdges
;
1213 sal_Int32 nObjectLines
;
1214 ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram
, nRoundedEdges
, nObjectLines
);
1216 //get shade mode and light settings:
1217 drawing::ShadeMode
aShadeMode( drawing::ShadeMode_SMOOTH
);
1218 uno::Reference
< beans::XPropertySet
> xDiagramProps( xDiagram
, uno::UNO_QUERY
);
1221 if( xDiagramProps
.is() )
1222 xDiagramProps
->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>= aShadeMode
;
1224 catch( uno::Exception
& ex
)
1226 ASSERT_EXCEPTION( ex
);
1229 if( lcl_isSimpleScheme( aShadeMode
, nRoundedEdges
, nObjectLines
, xDiagram
) )
1231 if( lcl_isSimpleLightScheme(xDiagramProps
) )
1232 aScheme
= ThreeDLookScheme_Simple
;
1234 else if( lcl_isRealisticScheme( aShadeMode
, nRoundedEdges
, nObjectLines
) )
1236 if( lcl_isRealisticLightScheme(xDiagramProps
) )
1237 aScheme
= ThreeDLookScheme_Realistic
;
1243 void ThreeDHelper::setScheme( const uno::Reference
< XDiagram
>& xDiagram
, ThreeDLookScheme aScheme
)
1245 if( aScheme
== ThreeDLookScheme_Unknown
)
1248 drawing::ShadeMode aShadeMode
;
1249 sal_Int32 nRoundedEdges
;
1250 sal_Int32 nObjectLines
;
1252 if( aScheme
== ThreeDLookScheme_Simple
)
1253 lcl_setSimpleScheme(aShadeMode
,nRoundedEdges
,nObjectLines
,xDiagram
);
1255 lcl_setRealisticScheme(aShadeMode
,nRoundedEdges
,nObjectLines
);
1259 ThreeDHelper::setRoundedEdgesAndObjectLines( xDiagram
, nRoundedEdges
, nObjectLines
);
1261 uno::Reference
< beans::XPropertySet
> xProp( xDiagram
, uno::UNO_QUERY
);
1264 drawing::ShadeMode aOldShadeMode
;
1265 if( ! ( (xProp
->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>=aOldShadeMode
) &&
1266 aOldShadeMode
== aShadeMode
))
1268 xProp
->setPropertyValue( C2U( "D3DSceneShadeMode" ), uno::makeAny( aShadeMode
));
1272 lcl_setLightsForScheme( xProp
, aScheme
);
1274 catch( uno::Exception
& ex
)
1276 ASSERT_EXCEPTION( ex
);
1282 void ThreeDHelper::set3DSettingsToDefault( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1284 Reference
< beans::XPropertyState
> xState( xSceneProperties
, uno::UNO_QUERY
);
1287 xState
->setPropertyToDefault( C2U("D3DSceneDistance"));
1288 xState
->setPropertyToDefault( C2U("D3DSceneFocalLength"));
1290 ThreeDHelper::setDefaultRotation( xSceneProperties
);
1291 ThreeDHelper::setDefaultIllumination( xSceneProperties
);
1295 void ThreeDHelper::setDefaultRotation( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
, bool bPieOrDonut
)
1297 if( !xSceneProperties
.is() )
1300 drawing::CameraGeometry
aCameraGeo( ThreeDHelper::getDefaultCameraGeometry( bPieOrDonut
) );
1301 xSceneProperties
->setPropertyValue( C2U("D3DCameraGeometry"), uno::makeAny( aCameraGeo
));
1303 ::basegfx::B3DHomMatrix aSceneRotation
;
1305 aSceneRotation
.rotate( -F_PI
/3.0, 0, 0 );
1306 xSceneProperties
->setPropertyValue( C2U("D3DTransformMatrix"),
1307 uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation
)));
1311 void ThreeDHelper::setDefaultRotation( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1313 bool bPieOrDonut( DiagramHelper::isPieOrDonutChart( uno::Reference
< XDiagram
>(xSceneProperties
, uno::UNO_QUERY
) ) );
1314 ThreeDHelper::setDefaultRotation( xSceneProperties
, bPieOrDonut
);
1318 void ThreeDHelper::setDefaultIllumination( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1320 if( !xSceneProperties
.is() )
1323 drawing::ShadeMode
aShadeMode( drawing::ShadeMode_SMOOTH
);
1326 xSceneProperties
->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>= aShadeMode
;
1327 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_1
), uno::makeAny( sal_False
) );
1328 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_3
), uno::makeAny( sal_False
) );
1329 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_4
), uno::makeAny( sal_False
) );
1330 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_5
), uno::makeAny( sal_False
) );
1331 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_6
), uno::makeAny( sal_False
) );
1332 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_7
), uno::makeAny( sal_False
) );
1333 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_8
), uno::makeAny( sal_False
) );
1335 catch( uno::Exception
& ex
)
1337 ASSERT_EXCEPTION( ex
);
1340 ThreeDLookScheme aScheme
= (drawing::ShadeMode_FLAT
==aShadeMode
) ? ThreeDLookScheme_Simple
: ThreeDLookScheme_Realistic
;
1341 lcl_setLightsForScheme( xSceneProperties
, aScheme
);
1345 void ThreeDHelper::getRoundedEdgesAndObjectLines(
1346 const uno::Reference
< XDiagram
> & xDiagram
1347 , sal_Int32
& rnRoundedEdges
, sal_Int32
& rnObjectLines
)
1349 rnRoundedEdges
= -1;
1353 bool bDifferentRoundedEdges
= false;
1354 bool bDifferentObjectLines
= false;
1356 drawing::LineStyle
aLineStyle( drawing::LineStyle_SOLID
);
1358 ::std::vector
< uno::Reference
< XDataSeries
> > aSeriesList(
1359 DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1360 sal_Int32 nSeriesCount
= static_cast<sal_Int32
>( aSeriesList
.size() );
1362 rtl::OUString
aPercentDiagonalPropertyName( C2U( "PercentDiagonal" ) );
1363 rtl::OUString
aBorderStylePropertyName( C2U( "BorderStyle" ) );
1365 for( sal_Int32 nS
= 0; nS
< nSeriesCount
; ++nS
)
1367 uno::Reference
< XDataSeries
> xSeries( aSeriesList
[nS
] );
1368 uno::Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
1374 sal_Int16 nPercentDiagonal
= 0;
1376 xProp
->getPropertyValue( aPercentDiagonalPropertyName
) >>= nPercentDiagonal
;
1377 rnRoundedEdges
= static_cast< sal_Int32
>( nPercentDiagonal
);
1379 if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1380 , aPercentDiagonalPropertyName
, uno::makeAny(nPercentDiagonal
) ) )
1381 bDifferentRoundedEdges
= true;
1383 catch( uno::Exception
& e
)
1385 ASSERT_EXCEPTION( e
);
1386 bDifferentRoundedEdges
= true;
1390 xProp
->getPropertyValue( aBorderStylePropertyName
) >>= aLineStyle
;
1392 if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1393 , aBorderStylePropertyName
, uno::makeAny(aLineStyle
) ) )
1394 bDifferentObjectLines
= true;
1396 catch( uno::Exception
& e
)
1398 ASSERT_EXCEPTION( e
);
1399 bDifferentObjectLines
= true;
1404 if( !bDifferentRoundedEdges
)
1406 sal_Int16 nPercentDiagonal
= 0;
1407 xProp
->getPropertyValue( aPercentDiagonalPropertyName
) >>= nPercentDiagonal
;
1408 sal_Int32 nCurrentRoundedEdges
= static_cast< sal_Int32
>( nPercentDiagonal
);
1409 if(nCurrentRoundedEdges
!=rnRoundedEdges
1410 || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1411 , aPercentDiagonalPropertyName
, uno::makeAny( static_cast< sal_Int16
>(rnRoundedEdges
) ) ) )
1413 bDifferentRoundedEdges
= true;
1414 nCurrentRoundedEdges
= -1;
1418 if( !bDifferentObjectLines
)
1420 drawing::LineStyle aCurrentLineStyle
;
1421 xProp
->getPropertyValue( aBorderStylePropertyName
) >>= aCurrentLineStyle
;
1422 if(aCurrentLineStyle
!=aLineStyle
1423 || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1424 , aBorderStylePropertyName
, uno::makeAny(aLineStyle
) ) )
1425 bDifferentObjectLines
= true;
1428 if( bDifferentRoundedEdges
&& bDifferentObjectLines
)
1434 if( bDifferentObjectLines
)
1436 else if( aLineStyle
== drawing::LineStyle_SOLID
)
1439 catch( uno::Exception
& e
)
1441 ASSERT_EXCEPTION( e
);
1445 void ThreeDHelper::setRoundedEdgesAndObjectLines(
1446 const uno::Reference
< XDiagram
> & xDiagram
1447 , sal_Int32 nRoundedEdges
, sal_Int32 nObjectLines
)
1449 if( (nRoundedEdges
<0||nRoundedEdges
>100) && nObjectLines
!=0 && nObjectLines
!=1 )
1452 drawing::LineStyle
aLineStyle( drawing::LineStyle_NONE
);
1454 aLineStyle
= drawing::LineStyle_SOLID
;
1456 uno::Any
aALineStyle( uno::makeAny(aLineStyle
));
1457 uno::Any
aARoundedEdges( uno::makeAny( static_cast< sal_Int16
>( nRoundedEdges
)));
1459 ::std::vector
< uno::Reference
< XDataSeries
> > aSeriesList(
1460 DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1461 sal_Int32 nSeriesCount
= static_cast<sal_Int32
>( aSeriesList
.size() );
1462 for( sal_Int32 nS
= 0; nS
< nSeriesCount
; ++nS
)
1464 uno::Reference
< XDataSeries
> xSeries( aSeriesList
[nS
] );
1466 if( nRoundedEdges
>=0 && nRoundedEdges
<=100 )
1467 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries
, C2U( "PercentDiagonal" ), aARoundedEdges
);
1469 if( nObjectLines
==0 || nObjectLines
==1 )
1470 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries
, C2U( "BorderStyle" ), aALineStyle
);
1475 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1477 CuboidPlanePosition
eRet(CuboidPlanePosition_Left
);
1479 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1480 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1481 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1483 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1486 if( sin(fYAngleRad
)>0.0 )
1487 eRet
= CuboidPlanePosition_Right
;
1492 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1494 CuboidPlanePosition
eRet(CuboidPlanePosition_Back
);
1496 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1497 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1498 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1500 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1503 if( cos(fXAngleRad
)*cos(fYAngleRad
)<0.0 )
1504 eRet
= CuboidPlanePosition_Front
;
1509 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1511 CuboidPlanePosition
eRet(CuboidPlanePosition_Bottom
);
1513 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1514 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1515 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1517 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1520 if( sin(fXAngleRad
)*cos(fYAngleRad
)<0.0 )
1521 eRet
= CuboidPlanePosition_Top
;
1525 //.............................................................................
1527 //.............................................................................