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