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