update credits
[LibreOffice.git] / chart2 / source / view / diagram / VDiagram.cxx
blob5b018c5235c8d06dad7cc29c43b27b4af2b36b27
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 // header for class SvxShape
40 #include <svx/unoshape.hxx>
41 // header for class E3dScene
42 #include <svx/scene3d.hxx>
43 #include <svx/e3dsceneupdater.hxx>
45 //.............................................................................
46 namespace chart
48 //.............................................................................
49 using namespace ::com::sun::star;
50 using namespace ::com::sun::star::chart2;
52 VDiagram::VDiagram(
53 const uno::Reference< XDiagram > & xDiagram
54 , const drawing::Direction3D& rPreferredAspectRatio
55 , sal_Int32 nDimension, sal_Bool bPolar )
56 : m_xLogicTarget(NULL)
57 , m_xFinalTarget(NULL)
58 , m_xShapeFactory(NULL)
59 , m_pShapeFactory(NULL)
60 , m_xOuterGroupShape(NULL)
61 , m_xCoordinateRegionShape(NULL)
62 , m_xWall2D(NULL)
63 , m_nDimensionCount(nDimension)
64 , m_bPolar(bPolar)
65 , m_xDiagram(xDiagram)
66 , m_aPreferredAspectRatio(rPreferredAspectRatio)
67 , m_xAspectRatio3D()
68 , m_fXAnglePi(0)
69 , m_fYAnglePi(0)
70 , m_fZAnglePi(0)
71 , m_bRightAngledAxes(sal_False)
73 if( m_nDimensionCount == 3)
75 uno::Reference< beans::XPropertySet > xSourceProp( m_xDiagram, uno::UNO_QUERY );
76 ThreeDHelper::getRotationAngleFromDiagram( xSourceProp, m_fXAnglePi, m_fYAnglePi, m_fZAnglePi );
77 if( ChartTypeHelper::isSupportingRightAngledAxes(
78 DiagramHelper::getChartTypeByIndex( m_xDiagram, 0 ) ) )
80 if(xSourceProp.is())
81 xSourceProp->getPropertyValue("RightAngledAxes") >>= m_bRightAngledAxes;
82 if( m_bRightAngledAxes )
84 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi, m_fYAnglePi );
85 m_fZAnglePi=0.0;
91 VDiagram::~VDiagram()
93 delete m_pShapeFactory;
96 void VDiagram::init(
97 const uno::Reference< drawing::XShapes >& xLogicTarget
98 , const uno::Reference< drawing::XShapes >& xFinalTarget
99 , const uno::Reference< lang::XMultiServiceFactory >& xFactory )
101 OSL_PRECOND(xLogicTarget.is()&&xFinalTarget.is()&&xFactory.is(),"no proper initialization parameters");
103 m_xLogicTarget = xLogicTarget;
104 m_xFinalTarget = xFinalTarget;
105 m_xShapeFactory = xFactory;
106 m_pShapeFactory = new ShapeFactory(xFactory);
109 void VDiagram::createShapes( const awt::Point& rPos, const awt::Size& rSize )
111 m_aAvailablePosIncludingAxes = rPos;
112 m_aAvailableSizeIncludingAxes = rSize;
114 if( m_nDimensionCount == 3 )
115 createShapes_3d();
116 else
117 createShapes_2d();
120 ::basegfx::B2IRectangle VDiagram::adjustPosAndSize( const awt::Point& rPos, const awt::Size& rSize )
122 ::basegfx::B2IRectangle aAllowedRect( BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes,m_aAvailableSizeIncludingAxes) );
123 ::basegfx::B2IRectangle aNewInnerRect( BaseGFXHelper::makeRectangle(rPos,rSize) );
124 aNewInnerRect.intersect( aAllowedRect );
126 if( m_nDimensionCount == 3 )
127 aNewInnerRect = adjustPosAndSize_3d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
128 else
129 aNewInnerRect = adjustPosAndSize_2d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
131 return aNewInnerRect;
134 ::basegfx::B2IRectangle VDiagram::adjustPosAndSize_2d( const awt::Point& rPos, const awt::Size& rAvailableSize )
136 m_aCurrentPosWithoutAxes = rPos;
137 m_aCurrentSizeWithoutAxes = rAvailableSize;
138 if( m_aPreferredAspectRatio.DirectionX > 0 && m_aPreferredAspectRatio.DirectionY > 0)
140 //do not change aspect ratio
141 awt::Size aAspectRatio( static_cast<sal_Int32>(m_aPreferredAspectRatio.DirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME),
142 static_cast<sal_Int32>(m_aPreferredAspectRatio.DirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME ));
143 m_aCurrentSizeWithoutAxes = awt::Size( ShapeFactory::calculateNewSizeRespectingAspectRatio(
144 rAvailableSize, aAspectRatio ) );
145 //center diagram position
146 m_aCurrentPosWithoutAxes = awt::Point( ShapeFactory::calculateTopLeftPositionToCenterObject(
147 rPos, rAvailableSize, m_aCurrentSizeWithoutAxes ) );
151 if( m_xWall2D.is() )
153 m_xWall2D->setSize( m_aCurrentSizeWithoutAxes);
154 m_xWall2D->setPosition(m_aCurrentPosWithoutAxes);
157 return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes) );
160 void VDiagram::createShapes_2d()
162 OSL_PRECOND(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()&&m_xShapeFactory.is(),"is not proper initialized");
163 if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()&&m_xShapeFactory.is()))
164 return;
166 //create group shape
167 uno::Reference< drawing::XShapes > xOuterGroup_Shapes = m_pShapeFactory->createGroup2D(m_xLogicTarget);
168 m_xOuterGroupShape = uno::Reference<drawing::XShape>( xOuterGroup_Shapes, uno::UNO_QUERY );
170 uno::Reference< drawing::XShapes > xGroupForWall( m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,"PlotAreaExcludingAxes") );
172 //create independent group shape as container for datapoints and such things
174 uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID");
175 m_xCoordinateRegionShape = uno::Reference<drawing::XShape>( xShapes, uno::UNO_QUERY );
178 //---------------------------
179 bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram );
181 //add back wall
183 m_xWall2D = uno::Reference< drawing::XShape >(
184 m_xShapeFactory->createInstance(
185 "com.sun.star.drawing.RectangleShape" ), uno::UNO_QUERY );
187 xGroupForWall->add(m_xWall2D);
188 uno::Reference< beans::XPropertySet > xProp( m_xWall2D, uno::UNO_QUERY );
189 if( xProp.is())
193 OSL_ENSURE( m_xDiagram.is(), "Invalid Diagram model" );
194 if( m_xDiagram.is() )
196 uno::Reference< beans::XPropertySet > xWallProp( m_xDiagram->getWall());
197 if( xWallProp.is())
198 PropertyMapper::setMappedProperties( xProp, xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
200 if( !bAddFloorAndWall )
202 //we always need this object as dummy object for correct scene dimensions
203 //but it should not be visible in this case:
204 ShapeFactory::makeShapeInvisible( m_xWall2D );
206 else
208 //CID for selection handling
209 OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
210 xProp->setPropertyValue( UNO_NAME_MISC_OBJ_NAME, uno::makeAny( aWallCID ) );
213 catch( const uno::Exception& e )
215 ASSERT_EXCEPTION( e );
221 //---------------------------
222 //position and size for diagram
223 adjustPosAndSize_2d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
226 E3dScene* lcl_getE3dScene( const uno::Reference< drawing::XShape >& xShape )
228 E3dScene* pRet=NULL;
229 uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY );
230 uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY );
231 if(xUnoTunnel.is()&&xTypeProvider.is())
233 SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() ));
234 if(pSvxShape)
236 SdrObject* pObj = pSvxShape->GetSdrObject();
237 if( pObj && pObj->ISA(E3dScene) )
238 pRet = (E3dScene*)pObj;
241 return pRet;
244 void lcl_setLightSources(
245 const uno::Reference< beans::XPropertySet > & xSource,
246 const uno::Reference< beans::XPropertySet > & xDest )
248 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1,
249 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1));
250 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2,
251 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2));
252 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3,
253 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3));
254 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4,
255 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4));
256 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5,
257 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5));
258 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6,
259 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6));
260 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7,
261 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7));
262 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8,
263 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8));
265 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1,
266 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1));
267 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2,
268 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2));
269 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3,
270 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3));
271 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4,
272 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4));
273 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5,
274 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5));
275 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6,
276 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6));
277 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7,
278 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7));
279 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8,
280 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8));
282 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1,
283 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1));
284 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2,
285 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2));
286 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3,
287 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3));
288 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4,
289 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4));
290 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5,
291 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5));
292 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6,
293 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6));
294 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7,
295 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7));
296 xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8,
297 xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8));
300 namespace
303 void lcl_ensureScaleValue( double& rfScale )
305 OSL_ENSURE(rfScale>0, "calculation error for automatic 3D height in chart");
306 if( rfScale<0 )
307 rfScale = 1.0;
308 else if( rfScale<0.2 )
309 rfScale = 0.2;
310 else if( rfScale>5.0 )
311 rfScale = 5.0;
316 void VDiagram::adjustAspectRatio3d( const awt::Size& rAvailableSize )
318 OSL_PRECOND(m_xAspectRatio3D.is(), "created shape offers no XPropertySet");
319 if( m_xAspectRatio3D.is())
323 double fScaleX = m_aPreferredAspectRatio.DirectionX;
324 double fScaleY = m_aPreferredAspectRatio.DirectionY;
325 double fScaleZ = m_aPreferredAspectRatio.DirectionZ;
327 //normalize scale factors
329 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
330 fScaleX/=fMax;
331 fScaleY/=fMax;
332 fScaleZ/=fMax;
335 if( fScaleX<0 || fScaleY<0 || fScaleZ<0 )
337 //calculate automatic 3D aspect ratio that fits good into the given 2D area
338 double fW = rAvailableSize.Width;
339 double fH = rAvailableSize.Height;
341 double sx = fabs(sin(m_fXAnglePi));
342 double sy = fabs(sin(m_fYAnglePi));
343 double cz = fabs(cos(m_fZAnglePi));
344 double sz = fabs(sin(m_fZAnglePi));
346 if(m_bRightAngledAxes)
348 //base equations:
349 //fH*zoomfactor == sx*fScaleZ + fScaleY;
350 //fW*zoomfactor == sy*fScaleZ + fScaleX;
352 if( fScaleX>0 && fScaleZ>0 )
354 //calculate fScaleY:
355 if( !::basegfx::fTools::equalZero(fW) )
357 fScaleY = (fH/fW)*(sy*fScaleZ+fScaleX)-(sx*fScaleZ);
358 lcl_ensureScaleValue( fScaleY );
360 else
361 fScaleY = 1.0;//looking from top or bottom the height is irrelevant
363 else if( fScaleY>0 && fScaleZ>0 )
365 //calculate fScaleX:
366 if( !::basegfx::fTools::equalZero(fH) )
368 fScaleX = (fW/fH)*(sx*fScaleZ+fScaleY)-(sy*fScaleZ);
369 lcl_ensureScaleValue(fScaleX);
371 else
372 fScaleX = 1.0;//looking from top or bottom hieght is irrelevant
374 else
376 //todo
377 OSL_FAIL("not implemented yet");
379 if( fScaleX<0 )
380 fScaleX = 1.0;
381 if( fScaleY<0 )
382 fScaleY = 1.0;
383 if( fScaleZ<0 )
384 fScaleZ = 1.0;
387 else
389 //base equations:
390 //fH*zoomfactor == cz*fScaleY + sz*fScaleX;
391 //fW*zoomfactor == cz*fScaleX + sz*fScaleY;
392 //==> fScaleY*(fH*sz-fW*cz) == fScaleX*(fW*sz-fH*cz);
393 if( fScaleX>0 && fScaleZ>0 )
395 //calculate fScaleY:
396 double fDivide = fH*sz-fW*cz;
397 if( !::basegfx::fTools::equalZero(fDivide) )
399 fScaleY = fScaleX*(fW*sz-fH*cz) / fDivide;
400 lcl_ensureScaleValue(fScaleY);
402 else
403 fScaleY = 1.0;//looking from top or bottom the height is irrelevant
406 else if( fScaleY>0 && fScaleZ>0 )
408 //calculate fScaleX:
409 double fDivide = fW*sz-fH*cz;
410 if( !::basegfx::fTools::equalZero(fDivide) )
412 fScaleX = fScaleY*(fH*sz-fW*cz) / fDivide;
413 lcl_ensureScaleValue(fScaleX);
415 else
416 fScaleX = 1.0;//looking from top or bottom hieght is irrelevant
418 else
420 //todo
421 OSL_FAIL("not implemented yet");
423 if( fScaleX<0 )
424 fScaleX = 1.0;
425 if( fScaleY<0 )
426 fScaleY = 1.0;
427 if( fScaleZ<0 )
428 fScaleZ = 1.0;
433 //normalize scale factors
435 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
436 fScaleX/=fMax;
437 fScaleY/=fMax;
438 fScaleZ/=fMax;
441 // identity matrix
442 ::basegfx::B3DHomMatrix aResult;
443 aResult.translate( -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
444 -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
445 -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
446 aResult.scale( fScaleX, fScaleY, fScaleZ );
447 aResult.translate( FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
448 FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
449 FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
451 // To get the 3D aspect ratio's effect on the 2D scene size, the scene's 2D size needs to be adapted to
452 // 3D content changes here. The tooling class remembers the current 3D transformation stack
453 // and in it's destructor, calculates a new 2D SnapRect for the scene and it's modified 3D geometry.
454 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
456 m_xAspectRatio3D->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
457 , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aResult )) );
459 catch( const uno::Exception& e )
461 ASSERT_EXCEPTION( e );
466 ::basegfx::B2IRectangle VDiagram::adjustPosAndSize_3d( const awt::Point& rPos, const awt::Size& rAvailableSize )
468 adjustAspectRatio3d( rAvailableSize );
470 //do not change aspect ratio of 3D scene with 2D bound rect
471 m_aCurrentSizeWithoutAxes = ShapeFactory::calculateNewSizeRespectingAspectRatio(
472 rAvailableSize, m_xOuterGroupShape->getSize() );
473 m_xOuterGroupShape->setSize( m_aCurrentSizeWithoutAxes );
475 //center diagram position
476 m_aCurrentPosWithoutAxes= ShapeFactory::calculateTopLeftPositionToCenterObject(
477 rPos, rAvailableSize, m_aCurrentSizeWithoutAxes );
478 m_xOuterGroupShape->setPosition(m_aCurrentPosWithoutAxes);
480 return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes) );
483 void VDiagram::createShapes_3d()
485 OSL_PRECOND(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()&&m_xShapeFactory.is(),"is not proper initialized");
486 if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()&&m_xShapeFactory.is()))
487 return;
489 //create shape
490 m_xOuterGroupShape = uno::Reference< drawing::XShape >(
491 m_xShapeFactory->createInstance(
492 "com.sun.star.drawing.Shape3DSceneObject" ), uno::UNO_QUERY );
493 ShapeFactory::setShapeName( m_xOuterGroupShape, "PlotAreaExcludingAxes" );
494 m_xLogicTarget->add(m_xOuterGroupShape);
496 uno::Reference< drawing::XShapes > xOuterGroup_Shapes =
497 uno::Reference<drawing::XShapes>( m_xOuterGroupShape, uno::UNO_QUERY );
500 //-------------------------------------------------------------------------
501 //create additional group to manipulate the aspect ratio of the whole diagram:
502 xOuterGroup_Shapes = m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, OUString() );
504 m_xAspectRatio3D = uno::Reference< beans::XPropertySet >( xOuterGroup_Shapes, uno::UNO_QUERY );
506 //---------------------------
508 bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram );
510 const bool bDoubleSided = false;
511 const bool bFlatNormals = true;
513 //add walls
515 uno::Reference< beans::XPropertySet > xWallProp( NULL );
516 if( m_xDiagram.is() )
517 xWallProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getWall());
519 OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
520 if( !bAddFloorAndWall )
521 aWallCID = OUString();
522 uno::Reference< drawing::XShapes > xWallGroup_Shapes( m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, aWallCID ) );
524 CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
525 CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
527 //add left wall
529 short nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 3 : 1;
530 double xPos = 0.0;
531 if( CuboidPlanePosition_Right==eLeftWallPos )
532 xPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
533 Stripe aStripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
534 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
535 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
536 if( CuboidPlanePosition_Right==eLeftWallPos )
538 nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 2 : 0;
539 aStripe = Stripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
540 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
541 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) );
543 aStripe.InvertNormal(true);
545 uno::Reference< drawing::XShape > xShape =
546 m_pShapeFactory->createStripe( xWallGroup_Shapes, aStripe
547 , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals );
548 if( !bAddFloorAndWall )
550 //we always need this object as dummy object for correct scene dimensions
551 //but it should not be visible in this case:
552 ShapeFactory::makeShapeInvisible( xShape );
555 //add back wall
557 short nRotatedTexture = 0;
558 double zPos = 0.0;
559 if( CuboidPlanePosition_Front==eBackWallPos )
560 zPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
561 Stripe aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
562 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
563 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
564 if( CuboidPlanePosition_Front==eBackWallPos )
566 aStripe = Stripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
567 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0)
568 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
569 nRotatedTexture = 3;
571 aStripe.InvertNormal(true);
573 uno::Reference< drawing::XShape > xShape =
574 m_pShapeFactory->createStripe(xWallGroup_Shapes, aStripe
575 , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals );
576 if( !bAddFloorAndWall )
578 //we always need this object as dummy object for correct scene dimensions
579 //but it should not be visible in this case:
580 ShapeFactory::makeShapeInvisible( xShape );
587 uno::Reference< beans::XPropertySet > xSourceProp( m_xDiagram, uno::UNO_QUERY_THROW );
588 uno::Reference< beans::XPropertySet > xDestProp( m_xOuterGroupShape, uno::UNO_QUERY_THROW );
590 //perspective
592 //ignore distance and focal length from file format and model comcpletely
593 //use vrp only to indicate the distance of the camera and thus influence the perspecitve
594 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_DISTANCE, uno::makeAny(
595 static_cast<sal_Int32>(ThreeDHelper::getCameraDistance( xSourceProp ))));
596 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE,
597 xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE));
600 //light
602 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE,
603 xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE));
604 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR,
605 xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR));
606 xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING,
607 xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING));
608 lcl_setLightSources( xSourceProp, xDestProp );
611 //rotation
613 //set diagrams rotation is set exclusively vie the transformation matrix
614 //don't set a camera at all!
615 //the cameras rotation is incorporated into this matrix
617 ::basegfx::B3DHomMatrix aEffectiveTranformation;
618 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);
620 if(!m_bRightAngledAxes)
621 aEffectiveTranformation.rotate(m_fXAnglePi,m_fYAnglePi,m_fZAnglePi);
622 else
623 aEffectiveTranformation.shearXY(m_fYAnglePi,-m_fXAnglePi);
625 //#i98497# 3D charts are rendered with wrong size
626 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
627 xDestProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX,
628 uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aEffectiveTranformation ) ) );
631 catch( const uno::Exception & ex )
633 ASSERT_EXCEPTION( ex );
636 //add floor plate
638 uno::Reference< beans::XPropertySet > xFloorProp( NULL );
639 if( m_xDiagram.is() )
640 xFloorProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getFloor());
642 Stripe aStripe( drawing::Position3D(0,0,0)
643 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
644 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
645 aStripe.InvertNormal(true);
647 uno::Reference< drawing::XShape > xShape =
648 m_pShapeFactory->createStripe(xOuterGroup_Shapes, aStripe
649 , xFloorProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, 0, bFlatNormals );
651 CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
652 if( !bAddFloorAndWall || (CuboidPlanePosition_Bottom!=eBottomPos) )
654 //we always need this object as dummy object for correct scene dimensions
655 //but it should not be visible in this case:
656 ShapeFactory::makeShapeInvisible( xShape );
658 else
660 OUString aFloorCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, OUString() ) );//@todo read CID from model
661 ShapeFactory::setShapeName( xShape, aFloorCID );
664 //---------------------------
666 //create an additional scene for the smaller inner coordinate region:
668 uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup3D( xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID" );
669 m_xCoordinateRegionShape = uno::Reference< drawing::XShape >( xShapes, uno::UNO_QUERY );
671 uno::Reference< beans::XPropertySet > xShapeProp( m_xCoordinateRegionShape, uno::UNO_QUERY );
672 OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
673 if( xShapeProp.is())
677 double fXScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
678 double fYScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
679 double fZScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
681 ::basegfx::B3DHomMatrix aM;
682 aM.translate(GRID_TO_WALL_DISTANCE/fXScale, GRID_TO_WALL_DISTANCE/fYScale, GRID_TO_WALL_DISTANCE/fZScale);
683 aM.scale( fXScale, fYScale, fZScale );
684 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
685 xShapeProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
686 , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix(aM)) );
688 catch( const uno::Exception& e )
690 ASSERT_EXCEPTION( e );
695 m_aCurrentPosWithoutAxes = m_aAvailablePosIncludingAxes;
696 m_aCurrentSizeWithoutAxes = m_aAvailableSizeIncludingAxes;
697 adjustPosAndSize_3d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
700 uno::Reference< drawing::XShapes > VDiagram::getCoordinateRegion()
702 return uno::Reference<drawing::XShapes>( m_xCoordinateRegionShape, uno::UNO_QUERY );
705 ::basegfx::B2IRectangle VDiagram::getCurrentRectangle()
707 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes);
710 void VDiagram::reduceToMimimumSize()
712 if( m_xOuterGroupShape.is() )
714 awt::Size aMaxSize( m_aAvailableSizeIncludingAxes );
715 awt::Point aMaxPos( m_aAvailablePosIncludingAxes );
717 sal_Int32 nNewWidth = aMaxSize.Width/3;
718 sal_Int32 nNewHeight = aMaxSize.Height/3;
719 awt::Size aNewSize( nNewWidth, nNewHeight );
720 awt::Point aNewPos( aMaxPos );
721 aNewPos.X += nNewWidth;
722 aNewPos.Y += nNewHeight;
724 adjustPosAndSize( aNewPos, aNewSize );
728 ::basegfx::B2IRectangle VDiagram::adjustInnerSize( const ::basegfx::B2IRectangle& rConsumedOuterRect )
730 awt::Point aNewPos( m_aCurrentPosWithoutAxes );
731 awt::Size aNewSize( m_aCurrentSizeWithoutAxes );
733 ::basegfx::B2IRectangle rAvailableOuterRect(
734 BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes,m_aAvailableSizeIncludingAxes) );
736 sal_Int32 nDeltaWidth = static_cast<sal_Int32>(rAvailableOuterRect.getWidth() - rConsumedOuterRect.getWidth());
737 sal_Int32 nDeltaHeight = static_cast<sal_Int32>(rAvailableOuterRect.getHeight() - rConsumedOuterRect.getHeight());
738 if( (aNewSize.Width + nDeltaWidth) < rAvailableOuterRect.getWidth()/3 )
739 nDeltaWidth = static_cast<sal_Int32>(rAvailableOuterRect.getWidth()/3 - aNewSize.Width);
740 aNewSize.Width += nDeltaWidth;
742 if( (aNewSize.Height + nDeltaHeight) < rAvailableOuterRect.getHeight()/3 )
743 nDeltaHeight = static_cast<sal_Int32>(rAvailableOuterRect.getHeight()/3 - aNewSize.Height);
744 aNewSize.Height += nDeltaHeight;
746 sal_Int32 nDiffLeft = rConsumedOuterRect.getMinX() - rAvailableOuterRect.getMinX();
747 sal_Int32 nDiffRight = rAvailableOuterRect.getMaxX() - rConsumedOuterRect.getMaxX();
748 if( nDiffLeft >= 0 )
749 aNewPos.X -= nDiffLeft;
750 else if( nDiffRight >= 0 )
752 if( nDiffRight > -nDiffLeft )
753 aNewPos.X += abs(nDiffLeft);
754 else if( nDiffRight > abs(nDeltaWidth) )
755 aNewPos.X += nDiffRight;
756 else
757 aNewPos.X += abs(nDeltaWidth);
760 sal_Int32 nDiffUp = rConsumedOuterRect.getMinY() - rAvailableOuterRect.getMinY();
761 sal_Int32 nDiffDown = rAvailableOuterRect.getMaxY() - rConsumedOuterRect.getMaxY();
762 if( nDiffUp >= 0 )
763 aNewPos.Y -= nDiffUp;
764 else if( nDiffDown >= 0 )
766 if( nDiffDown > -nDiffUp )
767 aNewPos.Y += abs(nDiffUp);
768 else if( nDiffDown > abs(nDeltaHeight) )
769 aNewPos.Y += nDiffDown;
770 else
771 aNewPos.Y += abs(nDeltaHeight);
774 return adjustPosAndSize( aNewPos, aNewSize );
777 //.............................................................................
778 } //namespace chart
779 //.............................................................................
781 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */