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