fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / chart2 / source / view / diagram / VDiagram.cxx
blob9f5db992645697c918576c4821108f7db19e3e9a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "VDiagram.hxx"
21 #include "PropertyMapper.hxx"
22 #include "ViewDefines.hxx"
23 #include "Stripe.hxx"
24 #include "macros.hxx"
25 #include "ObjectIdentifier.hxx"
26 #include "DiagramHelper.hxx"
27 #include "BaseGFXHelper.hxx"
28 #include "CommonConverters.hxx"
29 #include "ChartTypeHelper.hxx"
30 #include "ThreeDHelper.hxx"
31 #include "defines.hxx"
32 #include <editeng/unoprnms.hxx>
33 #include <com/sun/star/drawing/FillStyle.hpp>
34 #include <com/sun/star/drawing/LineStyle.hpp>
35 #include <com/sun/star/drawing/ProjectionMode.hpp>
36 #include <com/sun/star/drawing/ShadeMode.hpp>
37 #include <com/sun/star/lang/XUnoTunnel.hpp>
38 #include <com/sun/star/lang/XTypeProvider.hpp>
39 #include <svx/unoshape.hxx>
40 #include <svx/scene3d.hxx>
41 #include <svx/e3dsceneupdater.hxx>
43 namespace chart
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::chart2;
48 VDiagram::VDiagram(
49 const uno::Reference<XDiagram> & xDiagram, const drawing::Direction3D& rPreferredAspectRatio,
50 sal_Int32 nDimension )
51 : m_xTarget(NULL)
52 , m_xShapeFactory(NULL)
53 , m_pShapeFactory(NULL)
54 , m_xOuterGroupShape(NULL)
55 , m_xCoordinateRegionShape(NULL)
56 , m_xWall2D(NULL)
57 , m_nDimensionCount(nDimension)
58 , m_xDiagram(xDiagram)
59 , m_aPreferredAspectRatio(rPreferredAspectRatio)
60 , m_xAspectRatio3D()
61 , m_fXAnglePi(0)
62 , m_fYAnglePi(0)
63 , m_fZAnglePi(0)
64 , m_bRightAngledAxes(false)
66 if( m_nDimensionCount == 3)
68 uno::Reference< beans::XPropertySet > xSourceProp( m_xDiagram, uno::UNO_QUERY );
69 ThreeDHelper::getRotationAngleFromDiagram( xSourceProp, m_fXAnglePi, m_fYAnglePi, m_fZAnglePi );
70 if( ChartTypeHelper::isSupportingRightAngledAxes(
71 DiagramHelper::getChartTypeByIndex( m_xDiagram, 0 ) ) )
73 if(xSourceProp.is())
74 xSourceProp->getPropertyValue("RightAngledAxes") >>= m_bRightAngledAxes;
75 if( m_bRightAngledAxes )
77 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi, m_fYAnglePi );
78 m_fZAnglePi=0.0;
84 VDiagram::~VDiagram()
88 void VDiagram::init(
89 const uno::Reference< drawing::XShapes >& xTarget, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
91 OSL_PRECOND(xFactory.is(), "no proper initialization parameters");
93 m_xTarget = xTarget;
94 m_xShapeFactory = xFactory;
95 m_pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(xFactory);
98 void VDiagram::createShapes( const awt::Point& rPos, const awt::Size& rSize )
100 m_aAvailablePosIncludingAxes = rPos;
101 m_aAvailableSizeIncludingAxes = rSize;
103 if( m_nDimensionCount == 3 )
104 createShapes_3d();
105 else
106 createShapes_2d();
109 ::basegfx::B2IRectangle VDiagram::adjustPosAndSize( const awt::Point& rPos, const awt::Size& rSize )
111 ::basegfx::B2IRectangle aAllowedRect( BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes,m_aAvailableSizeIncludingAxes) );
112 ::basegfx::B2IRectangle aNewInnerRect( BaseGFXHelper::makeRectangle(rPos,rSize) );
113 aNewInnerRect.intersect( aAllowedRect );
115 if( m_nDimensionCount == 3 )
116 aNewInnerRect = adjustPosAndSize_3d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
117 else
118 aNewInnerRect = adjustPosAndSize_2d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
120 return aNewInnerRect;
123 ::basegfx::B2IRectangle VDiagram::adjustPosAndSize_2d( const awt::Point& rPos, const awt::Size& rAvailableSize )
125 m_aCurrentPosWithoutAxes = rPos;
126 m_aCurrentSizeWithoutAxes = rAvailableSize;
127 if( m_aPreferredAspectRatio.DirectionX > 0 && m_aPreferredAspectRatio.DirectionY > 0)
129 //do not change aspect ratio
130 awt::Size aAspectRatio( static_cast<sal_Int32>(m_aPreferredAspectRatio.DirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME),
131 static_cast<sal_Int32>(m_aPreferredAspectRatio.DirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME ));
132 m_aCurrentSizeWithoutAxes = awt::Size( AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
133 rAvailableSize, aAspectRatio ) );
134 //center diagram position
135 m_aCurrentPosWithoutAxes = awt::Point( AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
136 rPos, rAvailableSize, m_aCurrentSizeWithoutAxes ) );
140 if( m_xWall2D.is() )
142 m_xWall2D->setSize( m_aCurrentSizeWithoutAxes);
143 m_xWall2D->setPosition(m_aCurrentPosWithoutAxes);
146 return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes) );
149 void VDiagram::createShapes_2d()
151 OSL_PRECOND(m_pShapeFactory && m_xTarget.is() && m_xShapeFactory.is(), "is not proper initialized");
152 if (!m_pShapeFactory || !m_xTarget.is() || !m_xShapeFactory.is())
153 return;
155 //create group shape
156 uno::Reference< drawing::XShapes > xOuterGroup_Shapes = m_pShapeFactory->createGroup2D(m_xTarget);
157 m_xOuterGroupShape = uno::Reference<drawing::XShape>( xOuterGroup_Shapes, uno::UNO_QUERY );
159 uno::Reference< drawing::XShapes > xGroupForWall( m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,"PlotAreaExcludingAxes") );
161 //create independent group shape as container for datapoints and such things
163 uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID");
164 m_xCoordinateRegionShape = uno::Reference<drawing::XShape>( xShapes, uno::UNO_QUERY );
167 bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram );
169 //add back wall
171 AbstractShapeFactory* pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory);
172 m_xWall2D = pShapeFactory->createRectangle(
173 xGroupForWall );
175 uno::Reference< beans::XPropertySet > xProp( m_xWall2D, uno::UNO_QUERY );
176 if( xProp.is())
180 OSL_ENSURE( m_xDiagram.is(), "Invalid Diagram model" );
181 if( m_xDiagram.is() )
183 uno::Reference< beans::XPropertySet > xWallProp( m_xDiagram->getWall());
184 if( xWallProp.is())
185 PropertyMapper::setMappedProperties( xProp, xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
187 if( !bAddFloorAndWall )
189 //we always need this object as dummy object for correct scene dimensions
190 //but it should not be visible in this case:
191 AbstractShapeFactory::makeShapeInvisible( m_xWall2D );
193 else
195 //CID for selection handling
196 OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
197 xProp->setPropertyValue( UNO_NAME_MISC_OBJ_NAME, uno::makeAny( aWallCID ) );
200 catch( const uno::Exception& e )
202 ASSERT_EXCEPTION( e );
208 //position and size for diagram
209 adjustPosAndSize_2d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
212 E3dScene* lcl_getE3dScene( const uno::Reference< drawing::XShape >& xShape )
214 E3dScene* pRet=NULL;
215 uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY );
216 uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY );
217 if(xUnoTunnel.is()&&xTypeProvider.is())
219 SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() ));
220 if(pSvxShape)
222 SdrObject* pObj = pSvxShape->GetSdrObject();
223 if( pObj && pObj->ISA(E3dScene) )
224 pRet = static_cast<E3dScene*>(pObj);
227 return pRet;
230 void lcl_setLightSources(
231 const uno::Reference< beans::XPropertySet > & xSource,
232 const uno::Reference< beans::XPropertySet > & xDest )
234 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1,
235 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1));
236 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2,
237 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2));
238 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3,
239 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3));
240 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4,
241 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4));
242 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5,
243 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5));
244 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6,
245 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6));
246 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7,
247 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7));
248 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8,
249 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8));
251 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1,
252 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1));
253 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2,
254 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2));
255 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3,
256 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3));
257 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4,
258 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4));
259 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5,
260 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5));
261 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6,
262 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6));
263 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7,
264 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7));
265 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8,
266 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8));
268 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1,
269 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1));
270 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2,
271 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2));
272 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3,
273 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3));
274 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4,
275 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4));
276 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5,
277 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5));
278 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6,
279 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6));
280 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7,
281 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7));
282 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8,
283 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8));
286 namespace
289 void lcl_ensureScaleValue( double& rfScale )
291 OSL_ENSURE(rfScale>0, "calculation error for automatic 3D height in chart");
292 if( rfScale<0 )
293 rfScale = 1.0;
294 else if( rfScale<0.2 )
295 rfScale = 0.2;
296 else if( rfScale>5.0 )
297 rfScale = 5.0;
302 void VDiagram::adjustAspectRatio3d( const awt::Size& rAvailableSize )
304 OSL_PRECOND(m_xAspectRatio3D.is(), "created shape offers no XPropertySet");
305 if( m_xAspectRatio3D.is())
309 double fScaleX = m_aPreferredAspectRatio.DirectionX;
310 double fScaleY = m_aPreferredAspectRatio.DirectionY;
311 double fScaleZ = m_aPreferredAspectRatio.DirectionZ;
313 //normalize scale factors
315 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
316 fScaleX/=fMax;
317 fScaleY/=fMax;
318 fScaleZ/=fMax;
321 if( fScaleX<0 || fScaleY<0 || fScaleZ<0 )
323 //calculate automatic 3D aspect ratio that fits good into the given 2D area
324 double fW = rAvailableSize.Width;
325 double fH = rAvailableSize.Height;
327 double sx = fabs(sin(m_fXAnglePi));
328 double sy = fabs(sin(m_fYAnglePi));
329 double cz = fabs(cos(m_fZAnglePi));
330 double sz = fabs(sin(m_fZAnglePi));
332 if(m_bRightAngledAxes)
334 //base equations:
335 //fH*zoomfactor == sx*fScaleZ + fScaleY;
336 //fW*zoomfactor == sy*fScaleZ + fScaleX;
338 if( fScaleX>0 && fScaleZ>0 )
340 //calculate fScaleY:
341 if( !::basegfx::fTools::equalZero(fW) )
343 fScaleY = (fH/fW)*(sy*fScaleZ+fScaleX)-(sx*fScaleZ);
344 lcl_ensureScaleValue( fScaleY );
346 else
347 fScaleY = 1.0;//looking from top or bottom the height is irrelevant
349 else if( fScaleY>0 && fScaleZ>0 )
351 //calculate fScaleX:
352 if( !::basegfx::fTools::equalZero(fH) )
354 fScaleX = (fW/fH)*(sx*fScaleZ+fScaleY)-(sy*fScaleZ);
355 lcl_ensureScaleValue(fScaleX);
357 else
358 fScaleX = 1.0;//looking from top or bottom height is irrelevant
360 else
362 //todo
363 OSL_FAIL("not implemented yet");
365 if( fScaleX<0 )
366 fScaleX = 1.0;
367 if( fScaleY<0 )
368 fScaleY = 1.0;
369 if( fScaleZ<0 )
370 fScaleZ = 1.0;
373 else
375 //base equations:
376 //fH*zoomfactor == cz*fScaleY + sz*fScaleX;
377 //fW*zoomfactor == cz*fScaleX + sz*fScaleY;
378 //==> fScaleY*(fH*sz-fW*cz) == fScaleX*(fW*sz-fH*cz);
379 if( fScaleX>0 && fScaleZ>0 )
381 //calculate fScaleY:
382 double fDivide = fH*sz-fW*cz;
383 if( !::basegfx::fTools::equalZero(fDivide) )
385 fScaleY = fScaleX*(fW*sz-fH*cz) / fDivide;
386 lcl_ensureScaleValue(fScaleY);
388 else
389 fScaleY = 1.0;//looking from top or bottom the height is irrelevant
392 else if( fScaleY>0 && fScaleZ>0 )
394 //calculate fScaleX:
395 double fDivide = fW*sz-fH*cz;
396 if( !::basegfx::fTools::equalZero(fDivide) )
398 fScaleX = fScaleY*(fH*sz-fW*cz) / fDivide;
399 lcl_ensureScaleValue(fScaleX);
401 else
402 fScaleX = 1.0;//looking from top or bottom height is irrelevant
404 else
406 //todo
407 OSL_FAIL("not implemented yet");
409 if( fScaleX<0 )
410 fScaleX = 1.0;
411 if( fScaleY<0 )
412 fScaleY = 1.0;
413 if( fScaleZ<0 )
414 fScaleZ = 1.0;
419 //normalize scale factors
421 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
422 fScaleX/=fMax;
423 fScaleY/=fMax;
424 fScaleZ/=fMax;
427 // identity matrix
428 ::basegfx::B3DHomMatrix aResult;
429 aResult.translate( -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
430 -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
431 -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
432 aResult.scale( fScaleX, fScaleY, fScaleZ );
433 aResult.translate( FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
434 FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
435 FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
437 // To get the 3D aspect ratio's effect on the 2D scene size, the scene's 2D size needs to be adapted to
438 // 3D content changes here. The tooling class remembers the current 3D transformation stack
439 // and in its destructor, calculates a new 2D SnapRect for the scene and it's modified 3D geometry.
440 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
442 m_xAspectRatio3D->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
443 , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aResult )) );
445 catch( const uno::Exception& e )
447 ASSERT_EXCEPTION( e );
452 ::basegfx::B2IRectangle VDiagram::adjustPosAndSize_3d( const awt::Point& rPos, const awt::Size& rAvailableSize )
454 adjustAspectRatio3d( rAvailableSize );
456 //do not change aspect ratio of 3D scene with 2D bound rect
457 m_aCurrentSizeWithoutAxes = AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
458 rAvailableSize, m_xOuterGroupShape->getSize() );
459 m_xOuterGroupShape->setSize( m_aCurrentSizeWithoutAxes );
461 //center diagram position
462 m_aCurrentPosWithoutAxes= AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
463 rPos, rAvailableSize, m_aCurrentSizeWithoutAxes );
464 m_xOuterGroupShape->setPosition(m_aCurrentPosWithoutAxes);
466 return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes) );
469 void VDiagram::createShapes_3d()
471 OSL_PRECOND(m_pShapeFactory && m_xTarget.is() && m_xShapeFactory.is(), "is not proper initialized");
472 if (!m_pShapeFactory || !m_xTarget.is() || !m_xShapeFactory.is())
473 return;
475 //create shape
476 m_xOuterGroupShape = uno::Reference< drawing::XShape >(
477 m_pShapeFactory->createGroup3D( m_xTarget, "PlotAreaExcludingAxes" ), uno::UNO_QUERY);
479 uno::Reference< drawing::XShapes > xOuterGroup_Shapes =
480 uno::Reference<drawing::XShapes>( m_xOuterGroupShape, uno::UNO_QUERY );
482 //create additional group to manipulate the aspect ratio of the whole diagram:
483 xOuterGroup_Shapes = m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, OUString() );
485 m_xAspectRatio3D = uno::Reference< beans::XPropertySet >( xOuterGroup_Shapes, uno::UNO_QUERY );
487 bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram );
489 const bool bDoubleSided = false;
490 const bool bFlatNormals = true;
492 //add walls
494 uno::Reference< beans::XPropertySet > xWallProp( NULL );
495 if( m_xDiagram.is() )
496 xWallProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getWall());
498 OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
499 if( !bAddFloorAndWall )
500 aWallCID.clear();
501 uno::Reference< drawing::XShapes > xWallGroup_Shapes( m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, aWallCID ) );
503 CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
504 CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
506 //add left wall
508 short nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 3 : 1;
509 double xPos = 0.0;
510 if( CuboidPlanePosition_Right==eLeftWallPos )
511 xPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
512 Stripe aStripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
513 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
514 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
515 if( CuboidPlanePosition_Right==eLeftWallPos )
517 nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 2 : 0;
518 aStripe = Stripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
519 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
520 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) );
522 aStripe.InvertNormal(true);
524 uno::Reference< drawing::XShape > xShape =
525 m_pShapeFactory->createStripe( xWallGroup_Shapes, aStripe
526 , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals );
527 if( !bAddFloorAndWall )
529 //we always need this object as dummy object for correct scene dimensions
530 //but it should not be visible in this case:
531 AbstractShapeFactory::makeShapeInvisible( xShape );
534 //add back wall
536 short nRotatedTexture = 0;
537 double zPos = 0.0;
538 if( CuboidPlanePosition_Front==eBackWallPos )
539 zPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
540 Stripe aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
541 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
542 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
543 if( CuboidPlanePosition_Front==eBackWallPos )
545 aStripe = Stripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
546 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0)
547 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
548 nRotatedTexture = 3;
550 aStripe.InvertNormal(true);
552 uno::Reference< drawing::XShape > xShape =
553 m_pShapeFactory->createStripe(xWallGroup_Shapes, aStripe
554 , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals );
555 if( !bAddFloorAndWall )
557 //we always need this object as dummy object for correct scene dimensions
558 //but it should not be visible in this case:
559 AbstractShapeFactory::makeShapeInvisible( xShape );
566 uno::Reference< beans::XPropertySet > xSourceProp( m_xDiagram, uno::UNO_QUERY_THROW );
567 uno::Reference< beans::XPropertySet > xDestProp( m_xOuterGroupShape, uno::UNO_QUERY_THROW );
569 //perspective
571 //ignore distance and focal length from file format and model completely
572 //use vrp only to indicate the distance of the camera and thus influence the perspective
573 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_DISTANCE, uno::makeAny(
574 static_cast<sal_Int32>(ThreeDHelper::getCameraDistance( xSourceProp ))));
575 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE,
576 xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE));
579 //light
581 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE,
582 xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE));
583 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR,
584 xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR));
585 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING,
586 xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING));
587 lcl_setLightSources( xSourceProp, xDestProp );
590 //rotation
592 //set diagrams rotation is set exclusively via the transformation matrix
593 //don't set a camera at all!
594 //the camera's rotation is incorporated into this matrix
596 ::basegfx::B3DHomMatrix aEffectiveTranformation;
597 aEffectiveTranformation.translate(-FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0, -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0, -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0);
599 if(!m_bRightAngledAxes)
600 aEffectiveTranformation.rotate(m_fXAnglePi,m_fYAnglePi,m_fZAnglePi);
601 else
602 aEffectiveTranformation.shearXY(m_fYAnglePi,-m_fXAnglePi);
604 //#i98497# 3D charts are rendered with wrong size
605 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
606 xDestProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX,
607 uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aEffectiveTranformation ) ) );
610 catch( const uno::Exception & ex )
612 ASSERT_EXCEPTION( ex );
615 //add floor plate
617 uno::Reference< beans::XPropertySet > xFloorProp( NULL );
618 if( m_xDiagram.is() )
619 xFloorProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getFloor());
621 Stripe aStripe( drawing::Position3D(0,0,0)
622 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
623 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
624 aStripe.InvertNormal(true);
626 uno::Reference< drawing::XShape > xShape =
627 m_pShapeFactory->createStripe(xOuterGroup_Shapes, aStripe
628 , xFloorProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, 0, bFlatNormals );
630 CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
631 if( !bAddFloorAndWall || (CuboidPlanePosition_Bottom!=eBottomPos) )
633 //we always need this object as dummy object for correct scene dimensions
634 //but it should not be visible in this case:
635 AbstractShapeFactory::makeShapeInvisible( xShape );
637 else
639 OUString aFloorCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, OUString() ) );//@todo read CID from model
640 AbstractShapeFactory::setShapeName( xShape, aFloorCID );
644 //create an additional scene for the smaller inner coordinate region:
646 uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup3D( xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID" );
647 m_xCoordinateRegionShape = uno::Reference< drawing::XShape >( xShapes, uno::UNO_QUERY );
649 uno::Reference< beans::XPropertySet > xShapeProp( m_xCoordinateRegionShape, uno::UNO_QUERY );
650 OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
651 if( xShapeProp.is())
655 double fXScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
656 double fYScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
657 double fZScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
659 ::basegfx::B3DHomMatrix aM;
660 aM.translate(GRID_TO_WALL_DISTANCE/fXScale, GRID_TO_WALL_DISTANCE/fYScale, GRID_TO_WALL_DISTANCE/fZScale);
661 aM.scale( fXScale, fYScale, fZScale );
662 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
663 xShapeProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
664 , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix(aM)) );
666 catch( const uno::Exception& e )
668 ASSERT_EXCEPTION( e );
673 m_aCurrentPosWithoutAxes = m_aAvailablePosIncludingAxes;
674 m_aCurrentSizeWithoutAxes = m_aAvailableSizeIncludingAxes;
675 adjustPosAndSize_3d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
678 basegfx::B2IRectangle VDiagram::getCurrentRectangle() const
680 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes);
683 void VDiagram::reduceToMimimumSize()
685 if( m_xOuterGroupShape.is() )
687 awt::Size aMaxSize( m_aAvailableSizeIncludingAxes );
688 awt::Point aMaxPos( m_aAvailablePosIncludingAxes );
690 sal_Int32 nNewWidth = aMaxSize.Width/3;
691 sal_Int32 nNewHeight = aMaxSize.Height/3;
692 awt::Size aNewSize( nNewWidth, nNewHeight );
693 awt::Point aNewPos( aMaxPos );
694 aNewPos.X += nNewWidth;
695 aNewPos.Y += nNewHeight;
697 adjustPosAndSize( aNewPos, aNewSize );
701 ::basegfx::B2IRectangle VDiagram::adjustInnerSize( const ::basegfx::B2IRectangle& rConsumedOuterRect )
703 awt::Point aNewPos = m_aCurrentPosWithoutAxes;
704 awt::Size aNewSize = m_aCurrentSizeWithoutAxes;
706 basegfx::B2IRectangle aAvailableOuterRect =
707 BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes);
709 sal_Int32 nDeltaWidth = aAvailableOuterRect.getWidth() - rConsumedOuterRect.getWidth();
710 sal_Int32 nDeltaHeight = aAvailableOuterRect.getHeight() - rConsumedOuterRect.getHeight();
711 if( (aNewSize.Width + nDeltaWidth) < aAvailableOuterRect.getWidth()/3 )
712 nDeltaWidth = aAvailableOuterRect.getWidth()/3 - aNewSize.Width;
713 aNewSize.Width += nDeltaWidth;
715 if( (aNewSize.Height + nDeltaHeight) < aAvailableOuterRect.getHeight()/3 )
716 nDeltaHeight = aAvailableOuterRect.getHeight()/3 - aNewSize.Height;
717 aNewSize.Height += nDeltaHeight;
719 sal_Int32 nDiffLeft = rConsumedOuterRect.getMinX() - aAvailableOuterRect.getMinX();
720 sal_Int32 nDiffRight = aAvailableOuterRect.getMaxX() - rConsumedOuterRect.getMaxX();
721 if( nDiffLeft >= 0 )
722 aNewPos.X -= nDiffLeft;
723 else if( nDiffRight >= 0 )
725 if( nDiffRight > -nDiffLeft )
726 aNewPos.X += abs(nDiffLeft);
727 else if( nDiffRight > abs(nDeltaWidth) )
728 aNewPos.X += nDiffRight;
729 else
730 aNewPos.X += abs(nDeltaWidth);
733 sal_Int32 nDiffUp = rConsumedOuterRect.getMinY() - aAvailableOuterRect.getMinY();
734 sal_Int32 nDiffDown = aAvailableOuterRect.getMaxY() - rConsumedOuterRect.getMaxY();
735 if( nDiffUp >= 0 )
736 aNewPos.Y -= nDiffUp;
737 else if( nDiffDown >= 0 )
739 if( nDiffDown > -nDiffUp )
740 aNewPos.Y += abs(nDiffUp);
741 else if( nDiffDown > abs(nDeltaHeight) )
742 aNewPos.Y += nDiffDown;
743 else
744 aNewPos.Y += abs(nDeltaHeight);
747 return adjustPosAndSize( aNewPos, aNewSize );
750 } //namespace chart
752 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */