1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ThreeDHelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "ThreeDHelper.hxx"
36 #include "DiagramHelper.hxx"
37 #include "ChartTypeHelper.hxx"
38 #include "BaseGFXHelper.hxx"
39 #include "DataSeriesHelper.hxx"
40 #include <svx/unoprnms.hxx>
41 #include <com/sun/star/beans/XPropertyState.hpp>
42 #include <com/sun/star/chart2/XDiagram.hpp>
43 #include <com/sun/star/drawing/LineStyle.hpp>
45 #include <tools/debug.hxx>
47 //.............................................................................
50 //.............................................................................
51 using namespace ::com::sun::star
;
52 using namespace ::com::sun::star::chart2
;
54 using ::com::sun::star::uno::Reference
;
55 using ::com::sun::star::uno::Sequence
;
56 using ::rtl::OUString
;
57 using ::rtl::math::cos
;
58 using ::rtl::math::sin
;
59 using ::rtl::math::tan
;
61 #define FIXED_SIZE_FOR_3D_CHART_VOLUME (10000.0)
66 bool lcl_isRightAngledAxesSetAndSupported( const Reference
< beans::XPropertySet
>& xSceneProperties
)
68 sal_Bool bRightAngledAxes
= sal_False
;
69 if( xSceneProperties
.is() )
71 xSceneProperties
->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes
;
74 uno::Reference
< chart2::XDiagram
> xDiagram( xSceneProperties
, uno::UNO_QUERY
);
75 if( ChartTypeHelper::isSupportingRightAngledAxes(
76 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
85 void lcl_RotateLightSource( const Reference
< beans::XPropertySet
>& xSceneProperties
86 , const OUString
& rLightSourceDirection
87 , const OUString
& rLightSourceOn
88 , const ::basegfx::B3DHomMatrix
& rRotationMatrix
)
90 if( xSceneProperties
.is() )
92 sal_Bool bLightOn
= sal_False
;
93 if( xSceneProperties
->getPropertyValue( rLightSourceOn
) >>= bLightOn
)
97 drawing::Direction3D aLight
;
98 if( xSceneProperties
->getPropertyValue( rLightSourceDirection
) >>= aLight
)
100 ::basegfx::B3DVector
aLightVector( BaseGFXHelper::Direction3DToB3DVector( aLight
) );
101 aLightVector
= rRotationMatrix
*aLightVector
;
103 xSceneProperties
->setPropertyValue( rLightSourceDirection
104 , uno::makeAny( BaseGFXHelper::B3DVectorToDirection3D( aLightVector
) ) );
111 void lcl_rotateLights( const ::basegfx::B3DHomMatrix
& rLightRottion
, const Reference
< beans::XPropertySet
>& xSceneProperties
)
113 if(!xSceneProperties
.is())
116 ::basegfx::B3DHomMatrix
aLightRottion( rLightRottion
);
117 BaseGFXHelper::ReduceToRotationMatrix( aLightRottion
);
119 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection1"), C2U("D3DSceneLightOn1"), aLightRottion
);
120 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection2"), C2U("D3DSceneLightOn2"), aLightRottion
);
121 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection3"), C2U("D3DSceneLightOn3"), aLightRottion
);
122 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection4"), C2U("D3DSceneLightOn4"), aLightRottion
);
123 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection5"), C2U("D3DSceneLightOn5"), aLightRottion
);
124 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection6"), C2U("D3DSceneLightOn6"), aLightRottion
);
125 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection7"), C2U("D3DSceneLightOn7"), aLightRottion
);
126 lcl_RotateLightSource( xSceneProperties
, C2U("D3DSceneLightDirection8"), C2U("D3DSceneLightOn8"), aLightRottion
);
129 ::basegfx::B3DHomMatrix
lcl_getInverseRotationMatrix( const Reference
< beans::XPropertySet
>& xSceneProperties
)
131 ::basegfx::B3DHomMatrix aInverseRotation
;
132 double fXAngleRad
=0.0;
133 double fYAngleRad
=0.0;
134 double fZAngleRad
=0.0;
135 ThreeDHelper::getRotationAngleFromDiagram(
136 xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
137 aInverseRotation
.rotate( 0.0, 0.0, -fZAngleRad
);
138 aInverseRotation
.rotate( 0.0, -fYAngleRad
, 0.0 );
139 aInverseRotation
.rotate( -fXAngleRad
, 0.0, 0.0 );
140 return aInverseRotation
;
143 ::basegfx::B3DHomMatrix
lcl_getCompleteRotationMatrix( const Reference
< beans::XPropertySet
>& xSceneProperties
)
145 ::basegfx::B3DHomMatrix aCompleteRotation
;
146 double fXAngleRad
=0.0;
147 double fYAngleRad
=0.0;
148 double fZAngleRad
=0.0;
149 ThreeDHelper::getRotationAngleFromDiagram(
150 xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
151 aCompleteRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
152 return aCompleteRotation
;
155 bool lcl_isEqual( const drawing::Direction3D
& rA
, const drawing::Direction3D
& rB
)
157 return ::rtl::math::approxEqual(rA
.DirectionX
, rB
.DirectionX
)
158 && ::rtl::math::approxEqual(rA
.DirectionY
, rB
.DirectionY
)
159 && ::rtl::math::approxEqual(rA
.DirectionZ
, rB
.DirectionZ
);
162 bool lcl_isLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
, bool bRealistic
)
164 if(!xDiagramProps
.is())
167 sal_Bool bIsOn
= sal_False
;
168 xDiagramProps
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2
) ) >>= bIsOn
;
172 uno::Reference
< chart2::XDiagram
> xDiagram( xDiagramProps
, uno::UNO_QUERY
);
173 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
175 sal_Int32 nColor
= 0;
176 xDiagramProps
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
) ) >>= nColor
;
177 if( nColor
!= ::chart::ChartTypeHelper::getDefaultDirectLightColor( !bRealistic
, xChartType
) )
180 sal_Int32 nAmbientColor
= 0;
181 xDiagramProps
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR
) ) >>= nAmbientColor
;
182 if( nAmbientColor
!= ::chart::ChartTypeHelper::getDefaultAmbientLightColor( !bRealistic
, xChartType
) )
185 drawing::Direction3D
aDirection(0,0,0);
186 xDiagramProps
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
) ) >>= aDirection
;
188 drawing::Direction3D
aDefaultDirection( bRealistic
189 ? ChartTypeHelper::getDefaultRealisticLightDirection(xChartType
)
190 : ChartTypeHelper::getDefaultSimpleLightDirection(xChartType
) );
192 //rotate default light direction when right angled axes are off but supported
194 sal_Bool bRightAngledAxes
= sal_False
;
195 xDiagramProps
->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes
;
196 if(!bRightAngledAxes
)
198 if( ChartTypeHelper::isSupportingRightAngledAxes(
199 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
201 ::basegfx::B3DHomMatrix
aRotation( lcl_getCompleteRotationMatrix( xDiagramProps
) );
202 BaseGFXHelper::ReduceToRotationMatrix( aRotation
);
203 ::basegfx::B3DVector
aLightVector( BaseGFXHelper::Direction3DToB3DVector( aDefaultDirection
) );
204 aLightVector
= aRotation
*aLightVector
;
205 aDefaultDirection
= BaseGFXHelper::B3DVectorToDirection3D( aLightVector
);
210 return lcl_isEqual( aDirection
, aDefaultDirection
);
213 bool lcl_isRealisticLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
)
215 return lcl_isLightScheme( xDiagramProps
, true /*bRealistic*/ );
217 bool lcl_isSimpleLightScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
)
219 return lcl_isLightScheme( xDiagramProps
, false /*bRealistic*/ );
221 void lcl_setLightsForScheme( const uno::Reference
< beans::XPropertySet
>& xDiagramProps
, const ThreeDLookScheme
& rScheme
)
223 if(!xDiagramProps
.is())
225 if( rScheme
== ThreeDLookScheme_Unknown
)
228 xDiagramProps
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2
), uno::makeAny( sal_True
) );
230 uno::Reference
< chart2::XDiagram
> xDiagram( xDiagramProps
, uno::UNO_QUERY
);
231 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
232 uno::Any
aADirection( uno::makeAny( rScheme
== ThreeDLookScheme_Simple
233 ? ChartTypeHelper::getDefaultSimpleLightDirection(xChartType
)
234 : ChartTypeHelper::getDefaultRealisticLightDirection(xChartType
) ) );
236 xDiagramProps
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
), aADirection
);
237 //rotate light direction when right angled axes are off but supported
239 sal_Bool bRightAngledAxes
= sal_False
;
240 xDiagramProps
->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes
;
241 if(!bRightAngledAxes
)
243 if( ChartTypeHelper::isSupportingRightAngledAxes( xChartType
) )
245 ::basegfx::B3DHomMatrix
aRotation( lcl_getCompleteRotationMatrix( xDiagramProps
) );
246 BaseGFXHelper::ReduceToRotationMatrix( aRotation
);
247 lcl_RotateLightSource( xDiagramProps
, C2U("D3DSceneLightDirection2"), C2U("D3DSceneLightOn2"), aRotation
);
252 sal_Int32 nColor
= ::chart::ChartTypeHelper::getDefaultDirectLightColor( rScheme
==ThreeDLookScheme_Simple
, xChartType
);
253 xDiagramProps
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
), uno::makeAny( nColor
) );
255 sal_Int32 nAmbientColor
= ::chart::ChartTypeHelper::getDefaultAmbientLightColor( rScheme
==ThreeDLookScheme_Simple
, xChartType
);
256 xDiagramProps
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR
), uno::makeAny( nAmbientColor
) );
259 bool lcl_isRealisticScheme( drawing::ShadeMode aShadeMode
260 , sal_Int32 nRoundedEdges
261 , sal_Int32 nObjectLines
)
263 if(aShadeMode
!=drawing::ShadeMode_SMOOTH
)
272 bool lcl_isSimpleScheme( drawing::ShadeMode aShadeMode
273 , sal_Int32 nRoundedEdges
274 , sal_Int32 nObjectLines
275 , const uno::Reference
< XDiagram
>& xDiagram
)
277 if(aShadeMode
!=drawing::ShadeMode_FLAT
)
283 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
284 return ChartTypeHelper::noBordersForSimpleScheme( xChartType
);
291 void lcl_setRealisticScheme( drawing::ShadeMode
& rShadeMode
292 , sal_Int32
& rnRoundedEdges
293 , sal_Int32
& rnObjectLines
)
295 rShadeMode
= drawing::ShadeMode_SMOOTH
;
300 void lcl_setSimpleScheme( drawing::ShadeMode
& rShadeMode
301 , sal_Int32
& rnRoundedEdges
302 , sal_Int32
& rnObjectLines
303 , const uno::Reference
< XDiagram
>& xDiagram
)
305 rShadeMode
= drawing::ShadeMode_FLAT
;
308 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
309 rnObjectLines
= ChartTypeHelper::noBordersForSimpleScheme( xChartType
) ? 0 : 1;
312 } //end anonymous namespace
315 drawing::CameraGeometry
ThreeDHelper::getDefaultCameraGeometry( bool bPie
)
317 // ViewReferencePoint (Point on the View plane)
318 drawing::Position3D
vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
319 // ViewPlaneNormal (Normal to the View Plane)
320 drawing::Direction3D
vpn(0.416199821709347, 0.173649045905254, 0.892537795986984);
321 // ViewUpVector (determines the v-axis direction on the view plane as
322 // projection of VUP parallel to VPN onto th view pane)
323 drawing::Direction3D
vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
327 vrp
= drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspecitve
328 vpn
= drawing::Direction3D( 0.0, 0.0, 1.0 );
329 vup
= drawing::Direction3D( 0.0, 1.0, 0.0 );
332 return drawing::CameraGeometry( vrp
, vpn
, vup
);
337 ::basegfx::B3DHomMatrix
lcl_getCameraMatrix( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
339 drawing::HomogenMatrix aCameraMatrix
;
341 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
342 if( xSceneProperties
.is() )
343 xSceneProperties
->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG
;
345 ::basegfx::B3DVector
aVPN( BaseGFXHelper::Direction3DToB3DVector( aCG
.vpn
) );
346 ::basegfx::B3DVector
aVUP( BaseGFXHelper::Direction3DToB3DVector( aCG
.vup
) );
352 ::basegfx::B3DVector aCross
= ::basegfx::cross( aVUP
, aVPN
);
354 //first line is VUP x VPN
355 aCameraMatrix
.Line1
.Column1
= aCross
[0];
356 aCameraMatrix
.Line1
.Column2
= aCross
[1];
357 aCameraMatrix
.Line1
.Column3
= aCross
[2];
358 aCameraMatrix
.Line1
.Column4
= 0.0;
361 aCameraMatrix
.Line2
.Column1
= aVUP
[0];
362 aCameraMatrix
.Line2
.Column2
= aVUP
[1];
363 aCameraMatrix
.Line2
.Column3
= aVUP
[2];
364 aCameraMatrix
.Line2
.Column4
= 0.0;
367 aCameraMatrix
.Line3
.Column1
= aVPN
[0];
368 aCameraMatrix
.Line3
.Column2
= aVPN
[1];
369 aCameraMatrix
.Line3
.Column3
= aVPN
[2];
370 aCameraMatrix
.Line3
.Column4
= 0.0;
372 //fourth line is 0 0 0 1
373 aCameraMatrix
.Line4
.Column1
= 0.0;
374 aCameraMatrix
.Line4
.Column2
= 0.0;
375 aCameraMatrix
.Line4
.Column3
= 0.0;
376 aCameraMatrix
.Line4
.Column4
= 1.0;
378 return BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aCameraMatrix
);
381 double lcl_shiftAngleToIntervalMinusPiToPi( double fAngleRad
)
383 //valid range: ]-Pi,Pi]
384 while( fAngleRad
<=-F_PI
)
386 while( fAngleRad
>F_PI
)
391 void lcl_shiftAngleToIntervalMinus180To180( sal_Int32
& rnAngleDegree
)
393 //valid range: ]-180,180]
394 while( rnAngleDegree
<=-180 )
396 while( rnAngleDegree
>180 )
400 void lcl_shiftAngleToIntervalZeroTo360( sal_Int32
& rnAngleDegree
)
402 //valid range: [0,360[
403 while( rnAngleDegree
<0 )
405 while( rnAngleDegree
>=360 )
409 void lcl_ensureIntervalMinus1To1( double& rSinOrCos
)
411 if (rSinOrCos
< -1.0)
413 else if (rSinOrCos
> 1.0)
417 bool lcl_isSinZero( double fAngleRad
)
419 return ::basegfx::fTools::equalZero( sin(fAngleRad
), 0.0000001 );
421 bool lcl_isCosZero( double fAngleRad
)
423 return ::basegfx::fTools::equalZero( cos(fAngleRad
), 0.0000001 );
428 void ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
429 sal_Int32 nElevationDeg
, sal_Int32 nRotationDeg
,
430 double& rfXAngleRad
, double& rfYAngleRad
, double& rfZAngleRad
)
432 // for a description of the algorithm see issue 72994
433 //http://www.openoffice.org/issues/show_bug.cgi?id=72994
434 //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
436 lcl_shiftAngleToIntervalZeroTo360( nElevationDeg
);
437 lcl_shiftAngleToIntervalZeroTo360( nRotationDeg
);
439 double& x
= rfXAngleRad
;
440 double& y
= rfYAngleRad
;
441 double& z
= rfZAngleRad
;
443 double E
= F_PI
*nElevationDeg
/180; //elevation in Rad
444 double R
= F_PI
*nRotationDeg
/180; //rotation in Rad
446 if( (nRotationDeg
== 0 || nRotationDeg
== 180 )
447 && ( nElevationDeg
== 90 || nElevationDeg
== 270 ) )
452 double f23
= cos(R
)*sin(E
);
459 else if( ( nRotationDeg
== 90 || nRotationDeg
== 270 )
460 && ( nElevationDeg
== 90 || nElevationDeg
== 270 ) )
469 if( (sin(R
)*sin(E
))>0 )
474 else if( (nRotationDeg
== 0 || nRotationDeg
== 180 )
475 && ( nElevationDeg
== 0 || nElevationDeg
== 180 ) )
482 else if( ( nRotationDeg
== 90 || nRotationDeg
== 270 )
483 && ( nElevationDeg
== 0 || nElevationDeg
== 180 ) )
488 if( (sin(R
)/cos(E
))>0 )
498 else if ( nElevationDeg
== 0 || nElevationDeg
== 180 )
504 //use element 13 for sign
505 if((cos(x
)*sin(y
)*sin(R
))<0.0)
508 else if ( nElevationDeg
== 90 || nElevationDeg
== 270 )
511 //element 12 + 22 --> y=0 or F_PI and x=+-F_PI/2
513 z
= atan(sin(R
)/(cos(R
)*sin(E
)));
514 //use element 13 for sign for x
515 if( (sin(R
)*sin(z
))>0.0 )
519 //use element 21 for y
520 if( (sin(R
)*sin(E
)*sin(z
))>0.0)
525 else if ( nRotationDeg
== 0 || nRotationDeg
== 180 )
531 double f23
= cos(R
)*sin(E
);
532 if( (f23
* sin(x
)) < 0.0 )
535 else if (nRotationDeg
== 90 || nRotationDeg
== 270)
544 x
*= -1.0; //different signs for x and z
547 double cy
= sR
*sin(E
)/sin(z
);
548 lcl_ensureIntervalMinus1To1(cy
);
551 //use element 22 for sign:
552 if( (sin(x
)*sin(y
)*sin(z
)*cos(E
))<0.0)
557 z
= atan(tan(R
) * sin(E
));
560 DBG_ERROR("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
563 double cy
= cos(R
)/cos(z
);
564 lcl_ensureIntervalMinus1To1(cy
);
568 double fDenominator
= cos(z
)*(1.0-pow(sin(y
),2));
569 if(fDenominator
==0.0)
571 DBG_ERROR("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
574 double sx
= cos(R
)*sin(E
)/fDenominator
;
575 lcl_ensureIntervalMinus1To1(sx
);
578 //use element 13 for sign:
579 double f13a
= cos(x
)*cos(z
)*sin(y
);
580 double f13b
= sin(R
)-sx
*sin(z
);
581 if( (f13b
*f13a
)<0.0 )
584 //use element 22 for further investigations:
587 double f22a
= cos(x
)*cos(z
);
588 double f22b
= cos(E
)-(sx
*sin(y
)*sin(z
));
589 if( (f22a
*f22b
)<0.0 )
597 //change nothing or both
598 //use element 22 for further investigations:
599 double f22a
= cos(x
)*cos(z
);
600 double f22b
= cos(E
)-(sx
*sin(y
)*sin(z
));
601 if( (f22a
*f22b
)<0.0 )
610 void ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
611 sal_Int32
& rnElevationDeg
, sal_Int32
& rnRotationDeg
,
612 double fXRad
, double fYRad
, double fZRad
)
614 // for a description of the algorithm see issue 72994
615 //http://www.openoffice.org/issues/show_bug.cgi?id=72994
616 //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
618 double R
= 0.0; //Rotation in Rad
619 double E
= 0.0; //Elevation in Rad
625 double f11
= cos(y
)*cos(z
);
627 if( lcl_isSinZero(y
) )
631 if( lcl_isCosZero(x
) )
633 //siny == 0 && cosx == 0
635 if( lcl_isSinZero(z
) )
637 //siny == 0 && cosx == 0 && sinz == 0
638 //example: x=+-90 y=0oder180 z=0(oder180)
647 double f23
= cos(z
)*sin(x
) / cos(R
);
653 else if( lcl_isCosZero(z
) )
655 //siny == 0 && cosx == 0 && cosz == 0
656 //example: x=+-90 y=0oder180 z=+-90
658 double f13
= sin(x
)*sin(z
);
666 double f21
= cos(y
)*sin(z
) / sin(R
);
674 //siny == 0 && cosx == 0 && cosz != 0 && sinz != 0
676 double f13
= sin(x
)*sin(z
);
683 double f23
= cos(z
)*sin(x
);
690 else if( lcl_isSinZero(x
) )
699 double f22
= cos(x
)*cos(z
);
705 else if( lcl_isSinZero(z
) )
707 //sinY==0 sinZ==0 sinx!=0 cosx!=0
715 double f22
= cos(x
)*cos(z
);
716 double f23
= cos(z
)*sin(x
);
717 E
= atan( f23
/(f22
*cos(R
)) );
721 else if( lcl_isCosZero(z
) )
723 //sinY == 0 && cosZ == 0 && cosx != 0 && sinx != 0
724 double f13
= sin(x
)*sin(z
);
732 double f21
= cos(y
)*sin(z
);
740 //sinY == 0 && all other !=0
741 double f13
= sin(x
)*sin(z
);
743 if( (f11
*cos(R
))<0.0 )
746 double f22
= cos(x
)*cos(z
);
747 if( !lcl_isCosZero(R
) )
748 E
= atan( cos(z
)*sin(x
) /( f22
*cos(R
) ) );
750 E
= atan( cos(y
)*sin(z
) /( f22
*sin(R
) ) );
755 else if( lcl_isCosZero(y
) )
759 double f13
= sin(x
)*sin(z
)+cos(x
)*cos(z
)*sin(y
);
765 double f22
= cos(x
)*cos(z
)+sin(x
)*sin(y
)*sin(z
);
771 else if( lcl_isSinZero(x
) )
773 //cosY!=0 sinY!=0 sinX=0
774 if( lcl_isSinZero(z
) )
776 //cosY!=0 sinY!=0 sinX=0 sinZ=0
777 double f13
= cos(x
)*cos(z
)*sin(y
);
783 double f22
= cos(x
)*cos(z
);
789 else if( lcl_isCosZero(z
) )
791 //cosY!=0 sinY!=0 sinX=0 cosZ=0
795 double f23
= -1.0*cos(x
)*sin(y
)*sin(z
);
796 if( (f23
*cos(R
)*sin(E
))<0.0 )
804 //cosY!=0 sinY!=0 sinX=0 sinZ!=0 cosZ!=0
805 double f13
= cos(x
)*cos(z
)*sin(y
);
811 double f21
= cos(y
)*sin(z
);
812 double f22
= cos(x
)*cos(z
);
813 E
= atan(f21
/(f22
*sin(R
)) );
815 if( (f22
*cos(E
))<0.0 )
819 else if( lcl_isCosZero(x
) )
821 //cosY!=0 sinY!=0 cosX=0
823 if( lcl_isSinZero(z
) )
825 //cosY!=0 sinY!=0 cosX=0 sinZ=0
826 R
=0;//13 -> R=0 or F_PI
829 E
=F_PI
/2;//22 -> E=+-F_PI/2
830 //use element 11 and 23 for sign
831 double f23
= cos(z
)*sin(x
);
832 if( (f11
*f23
*sin(E
))<0.0 )
835 else if( lcl_isCosZero(z
) )
837 //cosY!=0 sinY!=0 cosX=0 cosZ=0
839 if( (sin(x
)*sin(z
))>0.0 )
844 E
=acos( sin(x
)*sin(y
)*sin(z
));
845 //use element 21 for sign:
846 if( (cos(y
)*sin(z
)*sin(R
)*sin(E
))<0.0 )
851 //cosY!=0 sinY!=0 cosX=0 sinZ!=0 cosZ!=0
853 R
= atan( sin(x
)*sin(z
)/(cos(y
)*cos(z
)) );
855 if( (sin(x
)*sin(z
))<0.0 )
858 E
= acos(sin(x
)*sin(y
)*sin(z
) );
860 if( (cos(y
)*sin(z
)*sin(R
)*sin(E
))<0.0 )
864 else if( lcl_isSinZero(z
) )
866 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ=0
869 //use elenment 13 for sign
870 if( (cos(x
)*cos(z
)*sin(y
)*sin(R
))<0.0 )
873 E
= acos( cos(x
)*cos(z
) );
874 //use element 23 for sign
875 if( (cos(z
)*sin(x
)*cos(R
)*sin(E
))<0.0 )
878 else if( lcl_isCosZero(z
) )
880 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 cosZ=0
882 R
=atan(-cos(y
)/(cos(x
)*sin(y
)));
883 //use element 13 for 'sign'
884 if( (sin(x
)*sin(z
)*sin(R
))<0.0 )
887 E
=atan( cos(y
)*sin(z
)/(sin(R
)*sin(x
)*sin(y
)*sin(z
)) );
888 //use element 23 for 'sign'
889 if( (-cos(x
)*sin(y
)*sin(z
)*cos(R
)*sin(E
))<0.0 )
894 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ!=0 cosZ!=0
896 double f13
= sin(x
)*sin(z
)+cos(x
)*cos(z
)*sin(y
);
897 R
= atan( f13
/ f11
);
900 double f22
= cos(x
)*cos(z
)+sin(x
)*sin(y
)*sin(z
);
901 double f23
= cos(x
)*sin(y
)*sin(z
)-cos(z
)*sin(x
);
903 E
= atan( -1.0*f23
/(f22
*cos(R
)) );
908 rnElevationDeg
= ::basegfx::fround( BaseGFXHelper::Rad2Deg( E
) );
909 rnRotationDeg
= ::basegfx::fround( BaseGFXHelper::Rad2Deg( R
) );
912 double ThreeDHelper::getValueClippedToRange( double fAngle
, const double& fPositivLimit
)
914 if( fAngle
<-1*fPositivLimit
)
915 fAngle
=-1*fPositivLimit
;
916 else if( fAngle
>fPositivLimit
)
917 fAngle
=fPositivLimit
;
921 double ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()
926 double ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()
931 void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad
, double& rfYAngleRad
)
933 rfXAngleRad
= ThreeDHelper::getValueClippedToRange(rfXAngleRad
, BaseGFXHelper::Deg2Rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
934 rfYAngleRad
= ThreeDHelper::getValueClippedToRange(rfYAngleRad
, BaseGFXHelper::Deg2Rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
937 void ThreeDHelper::getRotationAngleFromDiagram(
938 const Reference
< beans::XPropertySet
>& xSceneProperties
, double& rfXAngleRad
, double& rfYAngleRad
, double& rfZAngleRad
)
940 //takes the camera and the transformation matrix into account
942 rfXAngleRad
= rfYAngleRad
= rfZAngleRad
= 0.0;
944 if( !xSceneProperties
.is() )
947 //get camera rotation
948 ::basegfx::B3DHomMatrix
aFixCameraRotationMatrix( lcl_getCameraMatrix( xSceneProperties
) );
949 BaseGFXHelper::ReduceToRotationMatrix( aFixCameraRotationMatrix
);
952 ::basegfx::B3DHomMatrix aSceneRotation
;
954 drawing::HomogenMatrix aHomMatrix
;
955 if( xSceneProperties
->getPropertyValue( C2U("D3DTransformMatrix")) >>= aHomMatrix
)
957 aSceneRotation
= BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aHomMatrix
);
958 BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation
);
962 ::basegfx::B3DHomMatrix aResultRotation
= aFixCameraRotationMatrix
* aSceneRotation
;
963 ::basegfx::B3DTuple
aRotation( BaseGFXHelper::GetRotationFromMatrix( aResultRotation
) );
965 rfXAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getX());
966 rfYAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getY());
967 rfZAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(aRotation
.getZ());
969 if(rfZAngleRad
<(-F_PI
/2) || rfZAngleRad
>(F_PI
/2))
973 rfYAngleRad
=(F_PI
-rfYAngleRad
);
975 rfXAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfXAngleRad
);
976 rfYAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfYAngleRad
);
977 rfZAngleRad
= lcl_shiftAngleToIntervalMinusPiToPi(rfZAngleRad
);
981 void ThreeDHelper::switchRightAngledAxes( const Reference
< beans::XPropertySet
>& xSceneProperties
, sal_Bool bRightAngledAxes
, bool bRotateLights
)
985 if( xSceneProperties
.is() )
987 sal_Bool bOldRightAngledAxes
= sal_False
;
988 xSceneProperties
->getPropertyValue( C2U("RightAngledAxes")) >>= bOldRightAngledAxes
;
989 if( bOldRightAngledAxes
!=bRightAngledAxes
)
991 xSceneProperties
->setPropertyValue( C2U("RightAngledAxes"), uno::makeAny( bRightAngledAxes
));
996 ::basegfx::B3DHomMatrix
aInverseRotation( lcl_getInverseRotationMatrix( xSceneProperties
) );
997 lcl_rotateLights( aInverseRotation
, xSceneProperties
);
1001 ::basegfx::B3DHomMatrix
aCompleteRotation( lcl_getCompleteRotationMatrix( xSceneProperties
) );
1002 lcl_rotateLights( aCompleteRotation
, xSceneProperties
);
1008 catch( const uno::Exception
& ex
)
1010 ASSERT_EXCEPTION( ex
);
1014 void ThreeDHelper::setRotationAngleToDiagram(
1015 const Reference
< beans::XPropertySet
>& xSceneProperties
1016 , double fXAngleRad
, double fYAngleRad
, double fZAngleRad
)
1018 //the rotation of the camera is not touched but taken into account
1019 //the rotation difference is applied to the transformation matrix
1021 //the light sources will be adapted also
1023 if( !xSceneProperties
.is() )
1028 //remind old rotation for adaption of light directions
1029 ::basegfx::B3DHomMatrix
aInverseOldRotation( lcl_getInverseRotationMatrix( xSceneProperties
) );
1031 ::basegfx::B3DHomMatrix aInverseCameraRotation
;
1033 ::basegfx::B3DTuple
aR( BaseGFXHelper::GetRotationFromMatrix(
1034 lcl_getCameraMatrix( xSceneProperties
) ) );
1035 aInverseCameraRotation
.rotate( 0.0, 0.0, -aR
.getZ() );
1036 aInverseCameraRotation
.rotate( 0.0, -aR
.getY(), 0.0 );
1037 aInverseCameraRotation
.rotate( -aR
.getX(), 0.0, 0.0 );
1040 ::basegfx::B3DHomMatrix aCumulatedRotation
;
1041 aCumulatedRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
1043 //calculate new scene matrix
1044 ::basegfx::B3DHomMatrix aSceneRotation
= aInverseCameraRotation
*aCumulatedRotation
;
1045 BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation
);
1047 //set new rotation to transformation matrix
1048 xSceneProperties
->setPropertyValue(
1049 C2U("D3DTransformMatrix"), uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation
)));
1051 //rotate lights if RightAngledAxes are not set or not supported
1052 sal_Bool bRightAngledAxes
= sal_False
;
1053 xSceneProperties
->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes
;
1054 uno::Reference
< chart2::XDiagram
> xDiagram( xSceneProperties
, uno::UNO_QUERY
);
1055 if(!bRightAngledAxes
|| !ChartTypeHelper::isSupportingRightAngledAxes(
1056 DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) ) )
1058 ::basegfx::B3DHomMatrix aNewRotation
;
1059 aNewRotation
.rotate( fXAngleRad
, fYAngleRad
, fZAngleRad
);
1060 lcl_rotateLights( aNewRotation
*aInverseOldRotation
, xSceneProperties
);
1063 catch( const uno::Exception
& ex
)
1065 ASSERT_EXCEPTION( ex
);
1069 void ThreeDHelper::getRotationFromDiagram( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
1070 , sal_Int32
& rnHorizontalAngleDegree
, sal_Int32
& rnVerticalAngleDegree
)
1072 double fXAngle
, fYAngle
, fZAngle
;
1073 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngle
, fYAngle
, fZAngle
);
1075 if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1077 ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
1078 rnHorizontalAngleDegree
, rnVerticalAngleDegree
, fXAngle
, fYAngle
, fZAngle
);
1079 rnVerticalAngleDegree
*=-1;
1083 fXAngle
= BaseGFXHelper::Rad2Deg( fXAngle
);
1084 fYAngle
= BaseGFXHelper::Rad2Deg( fYAngle
);
1085 fZAngle
= BaseGFXHelper::Rad2Deg( fZAngle
);
1087 rnHorizontalAngleDegree
= ::basegfx::fround(fXAngle
);
1088 rnVerticalAngleDegree
= ::basegfx::fround(-1.0*fYAngle
);
1089 //nZRotation = ::basegfx::fround(-1.0*fZAngle);
1092 lcl_shiftAngleToIntervalMinus180To180( rnHorizontalAngleDegree
);
1093 lcl_shiftAngleToIntervalMinus180To180( rnVerticalAngleDegree
);
1096 void ThreeDHelper::setRotationToDiagram( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
1097 , sal_Int32 nHorizontalAngleDegree
, sal_Int32 nVerticalYAngleDegree
)
1099 //todo: x and y is not equal to horz and vert in case of RightAngledAxes==false
1100 double fXAngle
= BaseGFXHelper::Deg2Rad( nHorizontalAngleDegree
);
1101 double fYAngle
= BaseGFXHelper::Deg2Rad( -1*nVerticalYAngleDegree
);
1102 double fZAngle
= 0.0;
1104 if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1105 ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
1106 nHorizontalAngleDegree
, -1*nVerticalYAngleDegree
, fXAngle
, fYAngle
, fZAngle
);
1108 ThreeDHelper::setRotationAngleToDiagram( xSceneProperties
, fXAngle
, fYAngle
, fZAngle
);
1111 void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance
, double& rfMaximumDistance
)
1113 rfMinimumDistance
= 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME
;//empiric value
1114 rfMaximumDistance
= 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME
;//empiric value
1117 void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance
)
1120 getCameraDistanceRange( fMin
, fMax
);
1121 if( rfCameraDistance
< fMin
)
1122 rfCameraDistance
= fMin
;
1123 if( rfCameraDistance
> fMax
)
1124 rfCameraDistance
= fMax
;
1127 double ThreeDHelper::getCameraDistance(
1128 const Reference
< beans::XPropertySet
>& xSceneProperties
)
1130 double fCameraDistance
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
1132 if( !xSceneProperties
.is() )
1133 return fCameraDistance
;
1137 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
1138 xSceneProperties
->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG
;
1139 ::basegfx::B3DVector
aVRP( BaseGFXHelper::Position3DToB3DVector( aCG
.vrp
) );
1140 fCameraDistance
= aVRP
.getLength();
1142 ensureCameraDistanceRange( fCameraDistance
);
1144 catch( const uno::Exception
& ex
)
1146 ASSERT_EXCEPTION( ex
);
1148 return fCameraDistance
;
1151 void ThreeDHelper::setCameraDistance(
1152 const Reference
< beans::XPropertySet
>& xSceneProperties
, double fCameraDistance
)
1154 if( !xSceneProperties
.is() )
1159 if( fCameraDistance
<= 0 )
1160 fCameraDistance
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
1162 drawing::CameraGeometry
aCG( ThreeDHelper::getDefaultCameraGeometry() );
1163 xSceneProperties
->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG
;
1164 ::basegfx::B3DVector
aVRP( BaseGFXHelper::Position3DToB3DVector( aCG
.vrp
) );
1165 if( ::basegfx::fTools::equalZero( aVRP
.getLength() ) )
1166 aVRP
= ::basegfx::B3DVector(0,0,1);
1167 aVRP
.setLength(fCameraDistance
);
1168 aCG
.vrp
= BaseGFXHelper::B3DVectorToPosition3D( aVRP
);
1170 xSceneProperties
->setPropertyValue( C2U("D3DCameraGeometry"), uno::makeAny( aCG
));
1172 catch( const uno::Exception
& ex
)
1174 ASSERT_EXCEPTION( ex
);
1179 double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance
)
1181 double fRet
= fCameraDistance
;
1183 ThreeDHelper::getCameraDistanceRange( fMin
, fMax
);
1184 //fMax <-> 0; fMin <->100
1186 double a
= 100.0*fMax
*fMin
/(fMax
-fMin
);
1189 fRet
= a
/fCameraDistance
+ b
;
1195 double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective
)
1197 double fRet
= fPerspective
;
1199 ThreeDHelper::getCameraDistanceRange( fMin
, fMax
);
1200 //fMax <-> 0; fMin <->100
1202 double a
= 100.0*fMax
*fMin
/(fMax
-fMin
);
1205 fRet
= a
/(fPerspective
- b
);
1211 ThreeDLookScheme
ThreeDHelper::detectScheme( const uno::Reference
< XDiagram
>& xDiagram
)
1213 ThreeDLookScheme aScheme
= ThreeDLookScheme_Unknown
;
1215 sal_Int32 nRoundedEdges
;
1216 sal_Int32 nObjectLines
;
1217 ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram
, nRoundedEdges
, nObjectLines
);
1219 //get shade mode and light settings:
1220 drawing::ShadeMode
aShadeMode( drawing::ShadeMode_SMOOTH
);
1221 uno::Reference
< beans::XPropertySet
> xDiagramProps( xDiagram
, uno::UNO_QUERY
);
1224 if( xDiagramProps
.is() )
1225 xDiagramProps
->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>= aShadeMode
;
1227 catch( uno::Exception
& ex
)
1229 ASSERT_EXCEPTION( ex
);
1232 if( lcl_isSimpleScheme( aShadeMode
, nRoundedEdges
, nObjectLines
, xDiagram
) )
1234 if( lcl_isSimpleLightScheme(xDiagramProps
) )
1235 aScheme
= ThreeDLookScheme_Simple
;
1237 else if( lcl_isRealisticScheme( aShadeMode
, nRoundedEdges
, nObjectLines
) )
1239 if( lcl_isRealisticLightScheme(xDiagramProps
) )
1240 aScheme
= ThreeDLookScheme_Realistic
;
1246 void ThreeDHelper::setScheme( const uno::Reference
< XDiagram
>& xDiagram
, ThreeDLookScheme aScheme
)
1248 if( aScheme
== ThreeDLookScheme_Unknown
)
1251 drawing::ShadeMode aShadeMode
;
1252 sal_Int32 nRoundedEdges
;
1253 sal_Int32 nObjectLines
;
1255 if( aScheme
== ThreeDLookScheme_Simple
)
1256 lcl_setSimpleScheme(aShadeMode
,nRoundedEdges
,nObjectLines
,xDiagram
);
1258 lcl_setRealisticScheme(aShadeMode
,nRoundedEdges
,nObjectLines
);
1262 ThreeDHelper::setRoundedEdgesAndObjectLines( xDiagram
, nRoundedEdges
, nObjectLines
);
1264 uno::Reference
< beans::XPropertySet
> xProp( xDiagram
, uno::UNO_QUERY
);
1267 drawing::ShadeMode aOldShadeMode
;
1268 if( ! ( (xProp
->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>=aOldShadeMode
) &&
1269 aOldShadeMode
== aShadeMode
))
1271 xProp
->setPropertyValue( C2U( "D3DSceneShadeMode" ), uno::makeAny( aShadeMode
));
1275 lcl_setLightsForScheme( xProp
, aScheme
);
1277 catch( uno::Exception
& ex
)
1279 ASSERT_EXCEPTION( ex
);
1285 void ThreeDHelper::set3DSettingsToDefault( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1287 Reference
< beans::XPropertyState
> xState( xSceneProperties
, uno::UNO_QUERY
);
1290 xState
->setPropertyToDefault( C2U("D3DSceneDistance"));
1291 xState
->setPropertyToDefault( C2U("D3DSceneFocalLength"));
1293 ThreeDHelper::setDefaultRotation( xSceneProperties
);
1294 ThreeDHelper::setDefaultIllumination( xSceneProperties
);
1298 void ThreeDHelper::setDefaultRotation( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
, bool bPieOrDonut
)
1300 if( !xSceneProperties
.is() )
1303 drawing::CameraGeometry
aCameraGeo( ThreeDHelper::getDefaultCameraGeometry( bPieOrDonut
) );
1304 xSceneProperties
->setPropertyValue( C2U("D3DCameraGeometry"), uno::makeAny( aCameraGeo
));
1306 ::basegfx::B3DHomMatrix aSceneRotation
;
1308 aSceneRotation
.rotate( -F_PI
/3.0, 0, 0 );
1309 xSceneProperties
->setPropertyValue( C2U("D3DTransformMatrix"),
1310 uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation
)));
1314 void ThreeDHelper::setDefaultRotation( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1316 bool bPieOrDonut( DiagramHelper::isPieOrDonutChart( uno::Reference
< XDiagram
>(xSceneProperties
, uno::UNO_QUERY
) ) );
1317 ThreeDHelper::setDefaultRotation( xSceneProperties
, bPieOrDonut
);
1321 void ThreeDHelper::setDefaultIllumination( const uno::Reference
< beans::XPropertySet
>& xSceneProperties
)
1323 if( !xSceneProperties
.is() )
1326 drawing::ShadeMode
aShadeMode( drawing::ShadeMode_SMOOTH
);
1329 xSceneProperties
->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>= aShadeMode
;
1330 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_1
), uno::makeAny( sal_False
) );
1331 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_3
), uno::makeAny( sal_False
) );
1332 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_4
), uno::makeAny( sal_False
) );
1333 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_5
), uno::makeAny( sal_False
) );
1334 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_6
), uno::makeAny( sal_False
) );
1335 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_7
), uno::makeAny( sal_False
) );
1336 xSceneProperties
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_8
), uno::makeAny( sal_False
) );
1338 catch( uno::Exception
& ex
)
1340 ASSERT_EXCEPTION( ex
);
1343 ThreeDLookScheme aScheme
= (drawing::ShadeMode_FLAT
==aShadeMode
) ? ThreeDLookScheme_Simple
: ThreeDLookScheme_Realistic
;
1344 lcl_setLightsForScheme( xSceneProperties
, aScheme
);
1348 void ThreeDHelper::getRoundedEdgesAndObjectLines(
1349 const uno::Reference
< XDiagram
> & xDiagram
1350 , sal_Int32
& rnRoundedEdges
, sal_Int32
& rnObjectLines
)
1352 rnRoundedEdges
= -1;
1356 bool bDifferentRoundedEdges
= false;
1357 bool bDifferentObjectLines
= false;
1359 drawing::LineStyle
aLineStyle( drawing::LineStyle_SOLID
);
1361 ::std::vector
< uno::Reference
< XDataSeries
> > aSeriesList(
1362 DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1363 sal_Int32 nSeriesCount
= static_cast<sal_Int32
>( aSeriesList
.size() );
1365 rtl::OUString
aPercentDiagonalPropertyName( C2U( "PercentDiagonal" ) );
1366 rtl::OUString
aBorderStylePropertyName( C2U( "BorderStyle" ) );
1368 for( sal_Int32 nS
= 0; nS
< nSeriesCount
; ++nS
)
1370 uno::Reference
< XDataSeries
> xSeries( aSeriesList
[nS
] );
1371 uno::Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
1377 sal_Int16 nPercentDiagonal
= 0;
1379 xProp
->getPropertyValue( aPercentDiagonalPropertyName
) >>= nPercentDiagonal
;
1380 rnRoundedEdges
= static_cast< sal_Int32
>( nPercentDiagonal
);
1382 if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1383 , aPercentDiagonalPropertyName
, uno::makeAny(nPercentDiagonal
) ) )
1384 bDifferentRoundedEdges
= true;
1386 catch( uno::Exception
& e
)
1388 ASSERT_EXCEPTION( e
);
1389 bDifferentRoundedEdges
= true;
1393 xProp
->getPropertyValue( aBorderStylePropertyName
) >>= aLineStyle
;
1395 if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1396 , aBorderStylePropertyName
, uno::makeAny(aLineStyle
) ) )
1397 bDifferentObjectLines
= true;
1399 catch( uno::Exception
& e
)
1401 ASSERT_EXCEPTION( e
);
1402 bDifferentObjectLines
= true;
1407 if( !bDifferentRoundedEdges
)
1409 sal_Int16 nPercentDiagonal
= 0;
1410 xProp
->getPropertyValue( aPercentDiagonalPropertyName
) >>= nPercentDiagonal
;
1411 sal_Int32 nCurrentRoundedEdges
= static_cast< sal_Int32
>( nPercentDiagonal
);
1412 if(nCurrentRoundedEdges
!=rnRoundedEdges
1413 || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1414 , aPercentDiagonalPropertyName
, uno::makeAny( static_cast< sal_Int16
>(rnRoundedEdges
) ) ) )
1416 bDifferentRoundedEdges
= true;
1417 nCurrentRoundedEdges
= -1;
1421 if( !bDifferentObjectLines
)
1423 drawing::LineStyle aCurrentLineStyle
;
1424 xProp
->getPropertyValue( aBorderStylePropertyName
) >>= aCurrentLineStyle
;
1425 if(aCurrentLineStyle
!=aLineStyle
1426 || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
1427 , aBorderStylePropertyName
, uno::makeAny(aLineStyle
) ) )
1428 bDifferentObjectLines
= true;
1431 if( bDifferentRoundedEdges
&& bDifferentObjectLines
)
1437 if( bDifferentObjectLines
)
1439 else if( aLineStyle
== drawing::LineStyle_SOLID
)
1442 catch( uno::Exception
& e
)
1444 ASSERT_EXCEPTION( e
);
1448 void ThreeDHelper::setRoundedEdgesAndObjectLines(
1449 const uno::Reference
< XDiagram
> & xDiagram
1450 , sal_Int32 nRoundedEdges
, sal_Int32 nObjectLines
)
1452 if( (nRoundedEdges
<0||nRoundedEdges
>100) && nObjectLines
!=0 && nObjectLines
!=1 )
1455 drawing::LineStyle
aLineStyle( drawing::LineStyle_NONE
);
1457 aLineStyle
= drawing::LineStyle_SOLID
;
1459 uno::Any
aALineStyle( uno::makeAny(aLineStyle
));
1460 uno::Any
aARoundedEdges( uno::makeAny( static_cast< sal_Int16
>( nRoundedEdges
)));
1462 ::std::vector
< uno::Reference
< XDataSeries
> > aSeriesList(
1463 DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1464 sal_Int32 nSeriesCount
= static_cast<sal_Int32
>( aSeriesList
.size() );
1465 for( sal_Int32 nS
= 0; nS
< nSeriesCount
; ++nS
)
1467 uno::Reference
< XDataSeries
> xSeries( aSeriesList
[nS
] );
1469 if( nRoundedEdges
>=0 && nRoundedEdges
<=100 )
1470 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries
, C2U( "PercentDiagonal" ), aARoundedEdges
);
1472 if( nObjectLines
==0 || nObjectLines
==1 )
1473 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries
, C2U( "BorderStyle" ), aALineStyle
);
1478 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1480 CuboidPlanePosition
eRet(CuboidPlanePosition_Left
);
1482 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1483 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1484 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1486 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1489 if( sin(fYAngleRad
)>0.0 )
1490 eRet
= CuboidPlanePosition_Right
;
1495 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1497 CuboidPlanePosition
eRet(CuboidPlanePosition_Back
);
1499 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1500 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1501 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1503 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1506 if( cos(fXAngleRad
)*cos(fYAngleRad
)<0.0 )
1507 eRet
= CuboidPlanePosition_Front
;
1512 CuboidPlanePosition
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const Reference
< beans::XPropertySet
>& xSceneProperties
)
1514 CuboidPlanePosition
eRet(CuboidPlanePosition_Bottom
);
1516 double fXAngleRad
=0.0; double fYAngleRad
=0.0; double fZAngleRad
=0.0;
1517 ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties
, fXAngleRad
, fYAngleRad
, fZAngleRad
);
1518 if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties
) )
1520 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad
, fYAngleRad
);
1523 if( sin(fXAngleRad
)*cos(fYAngleRad
)<0.0 )
1524 eRet
= CuboidPlanePosition_Top
;
1528 //.............................................................................
1530 //.............................................................................