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