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 // 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 //.............................................................................
48 //.............................................................................
49 using namespace ::com::sun::star
;
50 using namespace ::com::sun::star::chart2
;
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
)
63 , m_nDimensionCount(nDimension
)
65 , m_xDiagram(xDiagram
)
66 , m_aPreferredAspectRatio(rPreferredAspectRatio
)
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 ) ) )
81 xSourceProp
->getPropertyValue("RightAngledAxes") >>= m_bRightAngledAxes
;
82 if( m_bRightAngledAxes
)
84 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi
, m_fYAnglePi
);
93 delete m_pShapeFactory
;
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 )
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
) );
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
) );
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()))
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
);
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
);
193 OSL_ENSURE( m_xDiagram
.is(), "Invalid Diagram model" );
194 if( m_xDiagram
.is() )
196 uno::Reference
< beans::XPropertySet
> xWallProp( m_xDiagram
->getWall());
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
);
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
)
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() ));
236 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
237 if( pObj
&& pObj
->ISA(E3dScene
) )
238 pRet
= (E3dScene
*)pObj
;
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
));
303 void lcl_ensureScaleValue( double& rfScale
)
305 OSL_ENSURE(rfScale
>0, "calculation error for automatic 3D height in chart");
308 else if( rfScale
<0.2 )
310 else if( 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
);
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
)
349 //fH*zoomfactor == sx*fScaleZ + fScaleY;
350 //fW*zoomfactor == sy*fScaleZ + fScaleX;
352 if( fScaleX
>0 && fScaleZ
>0 )
355 if( !::basegfx::fTools::equalZero(fW
) )
357 fScaleY
= (fH
/fW
)*(sy
*fScaleZ
+fScaleX
)-(sx
*fScaleZ
);
358 lcl_ensureScaleValue( fScaleY
);
361 fScaleY
= 1.0;//looking from top or bottom the height is irrelevant
363 else if( fScaleY
>0 && fScaleZ
>0 )
366 if( !::basegfx::fTools::equalZero(fH
) )
368 fScaleX
= (fW
/fH
)*(sx
*fScaleZ
+fScaleY
)-(sy
*fScaleZ
);
369 lcl_ensureScaleValue(fScaleX
);
372 fScaleX
= 1.0;//looking from top or bottom hieght is irrelevant
377 OSL_FAIL("not implemented yet");
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 )
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
);
403 fScaleY
= 1.0;//looking from top or bottom the height is irrelevant
406 else if( fScaleY
>0 && fScaleZ
>0 )
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
);
416 fScaleX
= 1.0;//looking from top or bottom hieght is irrelevant
421 OSL_FAIL("not implemented yet");
433 //normalize scale factors
435 double fMax
= std::max( std::max( fScaleX
, fScaleY
) , fScaleZ
);
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()))
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;
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
) ) );
529 short nRotatedTexture
= ( CuboidPlanePosition_Front
==eBackWallPos
) ? 3 : 1;
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
);
557 short nRotatedTexture
= 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) );
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
);
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
));
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
);
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
);
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
);
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
);
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");
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();
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
;
757 aNewPos
.X
+= abs(nDeltaWidth
);
760 sal_Int32 nDiffUp
= rConsumedOuterRect
.getMinY() - rAvailableOuterRect
.getMinY();
761 sal_Int32 nDiffDown
= rAvailableOuterRect
.getMaxY() - rConsumedOuterRect
.getMaxY();
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
;
771 aNewPos
.Y
+= abs(nDeltaHeight
);
774 return adjustPosAndSize( aNewPos
, aNewSize
);
777 //.............................................................................
779 //.............................................................................
781 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */