1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
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>
45 using namespace ::com::sun::star
;
46 using namespace ::com::sun::star::chart2
;
49 const uno::Reference
<XDiagram
> & xDiagram
, const drawing::Direction3D
& rPreferredAspectRatio
,
50 sal_Int32 nDimension
)
52 , m_xShapeFactory(NULL
)
53 , m_pShapeFactory(NULL
)
54 , m_xOuterGroupShape(NULL
)
55 , m_xCoordinateRegionShape(NULL
)
57 , m_nDimensionCount(nDimension
)
58 , m_xDiagram(xDiagram
)
59 , m_aPreferredAspectRatio(rPreferredAspectRatio
)
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 ) ) )
74 xSourceProp
->getPropertyValue("RightAngledAxes") >>= m_bRightAngledAxes
;
75 if( m_bRightAngledAxes
)
77 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi
, m_fYAnglePi
);
89 const uno::Reference
< drawing::XShapes
>& xTarget
, const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
91 OSL_PRECOND(xFactory
.is(), "no proper initialization parameters");
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 )
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
) );
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
) );
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())
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
);
171 AbstractShapeFactory
* pShapeFactory
= AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory
);
172 m_xWall2D
= pShapeFactory
->createRectangle(
175 uno::Reference
< beans::XPropertySet
> xProp( m_xWall2D
, uno::UNO_QUERY
);
180 OSL_ENSURE( m_xDiagram
.is(), "Invalid Diagram model" );
181 if( m_xDiagram
.is() )
183 uno::Reference
< beans::XPropertySet
> xWallProp( m_xDiagram
->getWall());
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
);
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
)
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() ));
222 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
223 if( pObj
&& pObj
->ISA(E3dScene
) )
224 pRet
= static_cast<E3dScene
*>(pObj
);
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
));
289 void lcl_ensureScaleValue( double& rfScale
)
291 OSL_ENSURE(rfScale
>0, "calculation error for automatic 3D height in chart");
294 else if( rfScale
<0.2 )
296 else if( 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
);
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
)
335 //fH*zoomfactor == sx*fScaleZ + fScaleY;
336 //fW*zoomfactor == sy*fScaleZ + fScaleX;
338 if( fScaleX
>0 && fScaleZ
>0 )
341 if( !::basegfx::fTools::equalZero(fW
) )
343 fScaleY
= (fH
/fW
)*(sy
*fScaleZ
+fScaleX
)-(sx
*fScaleZ
);
344 lcl_ensureScaleValue( fScaleY
);
347 fScaleY
= 1.0;//looking from top or bottom the height is irrelevant
349 else if( fScaleY
>0 && fScaleZ
>0 )
352 if( !::basegfx::fTools::equalZero(fH
) )
354 fScaleX
= (fW
/fH
)*(sx
*fScaleZ
+fScaleY
)-(sy
*fScaleZ
);
355 lcl_ensureScaleValue(fScaleX
);
358 fScaleX
= 1.0;//looking from top or bottom height is irrelevant
363 OSL_FAIL("not implemented yet");
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 )
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
);
389 fScaleY
= 1.0;//looking from top or bottom the height is irrelevant
392 else if( fScaleY
>0 && fScaleZ
>0 )
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
);
402 fScaleX
= 1.0;//looking from top or bottom height is irrelevant
407 OSL_FAIL("not implemented yet");
419 //normalize scale factors
421 double fMax
= std::max( std::max( fScaleX
, fScaleY
) , fScaleZ
);
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())
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;
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
)
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
) ) );
508 short nRotatedTexture
= ( CuboidPlanePosition_Front
==eBackWallPos
) ? 3 : 1;
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
);
536 short nRotatedTexture
= 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) );
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
);
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
));
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
);
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
);
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
);
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
);
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");
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();
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
;
730 aNewPos
.X
+= abs(nDeltaWidth
);
733 sal_Int32 nDiffUp
= rConsumedOuterRect
.getMinY() - aAvailableOuterRect
.getMinY();
734 sal_Int32 nDiffDown
= aAvailableOuterRect
.getMaxY() - rConsumedOuterRect
.getMaxY();
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
;
744 aNewPos
.Y
+= abs(nDeltaHeight
);
747 return adjustPosAndSize( aNewPos
, aNewSize
);
752 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */