1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: VDiagram.cxx,v $
10 * $Revision: 1.18.60.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "VDiagram.hxx"
34 #include "PropertyMapper.hxx"
35 #include "ViewDefines.hxx"
38 #include "ObjectIdentifier.hxx"
39 #include "DiagramHelper.hxx"
40 #include "BaseGFXHelper.hxx"
41 #include "CommonConverters.hxx"
42 #include "ChartTypeHelper.hxx"
43 #include "ThreeDHelper.hxx"
44 #include <svx/unoprnms.hxx>
45 #include <tools/color.hxx>
46 #include <tools/debug.hxx>
47 #include <com/sun/star/drawing/FillStyle.hpp>
48 #include <com/sun/star/drawing/LineStyle.hpp>
49 #include <com/sun/star/drawing/ProjectionMode.hpp>
50 #include <com/sun/star/drawing/ShadeMode.hpp>
51 #include <com/sun/star/lang/XUnoTunnel.hpp>
52 #include <com/sun/star/lang/XTypeProvider.hpp>
53 // header for class SvxShape
54 #include <svx/unoshape.hxx>
55 // header for class E3dScene
56 #include <svx/scene3d.hxx>
57 #include <rtl/math.hxx>
58 #include <svx/e3dsceneupdater.hxx>
60 //.............................................................................
63 //.............................................................................
64 using namespace ::com::sun::star
;
65 using namespace ::com::sun::star::chart2
;
68 const uno::Reference
< XDiagram
> & xDiagram
69 , const drawing::Direction3D
& rPreferredAspectRatio
70 , sal_Int32 nDimension
, sal_Bool bPolar
)
71 : m_xLogicTarget(NULL
)
72 , m_xFinalTarget(NULL
)
73 , m_xShapeFactory(NULL
)
74 , m_pShapeFactory(NULL
)
75 , m_xOuterGroupShape(NULL
)
76 , m_xCoordinateRegionShape(NULL
)
78 , m_nDimensionCount(nDimension
)
80 , m_xDiagram(xDiagram
)
81 , m_aPreferredAspectRatio(rPreferredAspectRatio
)
86 , m_bRightAngledAxes(sal_False
)
88 if( m_nDimensionCount
== 3)
90 uno::Reference
< beans::XPropertySet
> xSourceProp( m_xDiagram
, uno::UNO_QUERY
);
91 ThreeDHelper::getRotationAngleFromDiagram( xSourceProp
, m_fXAnglePi
, m_fYAnglePi
, m_fZAnglePi
);
92 if( ChartTypeHelper::isSupportingRightAngledAxes(
93 DiagramHelper::getChartTypeByIndex( m_xDiagram
, 0 ) ) )
96 xSourceProp
->getPropertyValue(C2U( "RightAngledAxes" )) >>= m_bRightAngledAxes
;
97 if( m_bRightAngledAxes
)
99 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi
, m_fYAnglePi
);
106 VDiagram::~VDiagram()
108 delete m_pShapeFactory
;
111 void SAL_CALL
VDiagram::init(
112 const uno::Reference
< drawing::XShapes
>& xLogicTarget
113 , const uno::Reference
< drawing::XShapes
>& xFinalTarget
114 , const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
116 DBG_ASSERT(xLogicTarget
.is()&&xFinalTarget
.is()&&xFactory
.is(),"no proper initialization parameters");
118 m_xLogicTarget
= xLogicTarget
;
119 m_xFinalTarget
= xFinalTarget
;
120 m_xShapeFactory
= xFactory
;
121 m_pShapeFactory
= new ShapeFactory(xFactory
);
124 void VDiagram::createShapes( const awt::Point
& rPos
, const awt::Size
& rSize
)
126 m_aAvailablePosIncludingAxes
= rPos
;
127 m_aAvailableSizeIncludingAxes
= rSize
;
129 if( m_nDimensionCount
== 3 )
135 ::basegfx::B2IRectangle
VDiagram::adjustPosAndSize( const awt::Point
& rPos
, const awt::Size
& rSize
)
137 ::basegfx::B2IRectangle
aAllowedRect( BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes
,m_aAvailableSizeIncludingAxes
) );
138 ::basegfx::B2IRectangle
aNewInnerRect( BaseGFXHelper::makeRectangle(rPos
,rSize
) );
139 aNewInnerRect
.intersect( aAllowedRect
);
141 if( m_nDimensionCount
== 3 )
142 aNewInnerRect
= adjustPosAndSize_3d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect
), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect
) );
144 aNewInnerRect
= adjustPosAndSize_2d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect
), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect
) );
146 return aNewInnerRect
;
149 ::basegfx::B2IRectangle
VDiagram::adjustPosAndSize_2d( const awt::Point
& rPos
, const awt::Size
& rAvailableSize
)
151 m_aCurrentPosWithoutAxes
= rPos
;
152 m_aCurrentSizeWithoutAxes
= rAvailableSize
;
153 if( m_aPreferredAspectRatio
.DirectionX
> 0 && m_aPreferredAspectRatio
.DirectionY
> 0)
155 //do not change aspect ratio
156 awt::Size
aAspectRatio( static_cast<sal_Int32
>(m_aPreferredAspectRatio
.DirectionX
*FIXED_SIZE_FOR_3D_CHART_VOLUME
),
157 static_cast<sal_Int32
>(m_aPreferredAspectRatio
.DirectionY
*FIXED_SIZE_FOR_3D_CHART_VOLUME
));
158 m_aCurrentSizeWithoutAxes
= awt::Size( ShapeFactory::calculateNewSizeRespectingAspectRatio(
159 rAvailableSize
, aAspectRatio
) );
160 //center diagram position
161 m_aCurrentPosWithoutAxes
= awt::Point( ShapeFactory::calculateTopLeftPositionToCenterObject(
162 rPos
, rAvailableSize
, m_aCurrentSizeWithoutAxes
) );
168 m_xWall2D
->setSize( m_aCurrentSizeWithoutAxes
);
169 m_xWall2D
->setPosition(m_aCurrentPosWithoutAxes
);
172 return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes
,m_aCurrentSizeWithoutAxes
) );
175 void VDiagram::createShapes_2d()
177 DBG_ASSERT(m_pShapeFactory
&&m_xLogicTarget
.is()&&m_xFinalTarget
.is()&&m_xShapeFactory
.is(),"is not proper initialized");
178 if(!(m_pShapeFactory
&&m_xLogicTarget
.is()&&m_xFinalTarget
.is()&&m_xShapeFactory
.is()))
182 uno::Reference
< drawing::XShapes
> xOuterGroup_Shapes
= m_pShapeFactory
->createGroup2D(m_xLogicTarget
);
183 m_xOuterGroupShape
= uno::Reference
<drawing::XShape
>( xOuterGroup_Shapes
, uno::UNO_QUERY
);
185 //create independent group shape as container for datapoints and such things
187 uno::Reference
< drawing::XShapes
> xShapes
= m_pShapeFactory
->createGroup2D(xOuterGroup_Shapes
,C2U("testonly;CooContainer=XXX_CID"));
188 m_xCoordinateRegionShape
= uno::Reference
<drawing::XShape
>( xShapes
, uno::UNO_QUERY
);
191 //---------------------------
192 bool bAddFloorAndWall
= DiagramHelper::isSupportingFloorAndWall( m_xDiagram
);
196 m_xWall2D
= uno::Reference
< drawing::XShape
>(
197 m_xShapeFactory
->createInstance( C2U(
198 "com.sun.star.drawing.RectangleShape" ) ), uno::UNO_QUERY
);
199 //m_xWall2D->setPosition(m_aAvailablePosIncludingAxes);
200 //m_xWall2D->setSize(m_aAvailableSizeIncludingAxes);
201 uno::Reference
< drawing::XShapes
> xShapes( m_xCoordinateRegionShape
, uno::UNO_QUERY
);
202 xShapes
->add(m_xWall2D
);
203 uno::Reference
< beans::XPropertySet
> xProp( m_xWall2D
, uno::UNO_QUERY
);
208 DBG_ASSERT( m_xDiagram
.is(), "Invalid Diagram model" );
209 if( m_xDiagram
.is() )
211 uno::Reference
< beans::XPropertySet
> xWallProp( m_xDiagram
->getWall());
213 PropertyMapper::setMappedProperties( xProp
, xWallProp
, PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
215 if( !bAddFloorAndWall
)
217 //we always need this object as dummy object for correct scene dimensions
218 //but it should not be visible in this case:
219 ShapeFactory::makeShapeInvisible( m_xWall2D
);
223 //CID for selection handling
224 rtl::OUString
aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL
, rtl::OUString() ) );//@todo read CID from model
225 xProp
->setPropertyValue( C2U( UNO_NAME_MISC_OBJ_NAME
), uno::makeAny( aWallCID
) );
228 catch( uno::Exception
& e
)
230 ASSERT_EXCEPTION( e
);
236 //---------------------------
237 //position and size for diagram
238 adjustPosAndSize_2d( m_aAvailablePosIncludingAxes
, m_aAvailableSizeIncludingAxes
);
241 E3dScene
* lcl_getE3dScene( const uno::Reference
< drawing::XShape
>& xShape
)
244 uno::Reference
< lang::XUnoTunnel
> xUnoTunnel( xShape
, uno::UNO_QUERY
);
245 uno::Reference
< lang::XTypeProvider
> xTypeProvider( xShape
, uno::UNO_QUERY
);
246 if(xUnoTunnel
.is()&&xTypeProvider
.is())
248 SvxShape
* pSvxShape
= reinterpret_cast<SvxShape
*>(xUnoTunnel
->getSomething( SvxShape::getUnoTunnelId() ));
251 SdrObject
* pObj
= pSvxShape
->GetSdrObject();
252 if( pObj
&& pObj
->ISA(E3dScene
) )
253 pRet
= (E3dScene
*)pObj
;
259 void lcl_setLightSources(
260 const uno::Reference
< beans::XPropertySet
> & xSource
,
261 const uno::Reference
< beans::XPropertySet
> & xDest
)
263 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_1
),
264 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_1
)));
265 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2
),
266 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2
)));
267 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_3
),
268 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_3
)));
269 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_4
),
270 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_4
)));
271 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_5
),
272 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_5
)));
273 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_6
),
274 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_6
)));
275 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_7
),
276 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_7
)));
277 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_8
),
278 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_8
)));
280 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1
),
281 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1
)));
282 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
),
283 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
)));
284 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3
),
285 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3
)));
286 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4
),
287 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4
)));
288 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5
),
289 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5
)));
290 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6
),
291 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6
)));
292 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7
),
293 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7
)));
294 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8
),
295 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8
)));
297 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_1
),
298 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_1
)));
299 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
),
300 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
)));
301 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_3
),
302 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_3
)));
303 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_4
),
304 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_4
)));
305 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_5
),
306 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_5
)));
307 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_6
),
308 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_6
)));
309 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_7
),
310 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_7
)));
311 xDest
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_8
),
312 xSource
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_8
)));
318 void lcl_ensureScaleValue( double& rfScale
)
320 DBG_ASSERT(rfScale
>0, "calculation error for automatic 3D height in chart");
323 else if( rfScale
<0.2 )
325 else if( rfScale
>5.0 )
331 void VDiagram::adjustAspectRatio3d( const awt::Size
& rAvailableSize
)
333 DBG_ASSERT(m_xAspectRatio3D
.is(), "created shape offers no XPropertySet");
334 if( m_xAspectRatio3D
.is())
338 double fScaleX
= m_aPreferredAspectRatio
.DirectionX
;
339 double fScaleY
= m_aPreferredAspectRatio
.DirectionY
;
340 double fScaleZ
= m_aPreferredAspectRatio
.DirectionZ
;
342 //normalize scale factors
344 double fMax
= std::max( std::max( fScaleX
, fScaleY
) , fScaleZ
);
350 if( fScaleX
<0 || fScaleY
<0 || fScaleZ
<0 )
352 //calculate automatic 3D aspect ratio that fits good into the given 2D area
353 double fW
= rAvailableSize
.Width
;
354 double fH
= rAvailableSize
.Height
;
356 // double cx = fabs(cos(m_fXAnglePi));
357 double sx
= fabs(sin(m_fXAnglePi
));
358 // double cy = fabs(cos(m_fYAnglePi));
359 double sy
= fabs(sin(m_fYAnglePi
));
360 double cz
= fabs(cos(m_fZAnglePi
));
361 double sz
= fabs(sin(m_fZAnglePi
));
363 if(m_bRightAngledAxes
)
366 //fH*zoomfactor == sx*fScaleZ + fScaleY;
367 //fW*zoomfactor == sy*fScaleZ + fScaleX;
369 if( fScaleX
>0 && fScaleZ
>0 )
372 if( !::basegfx::fTools::equalZero(fW
) )
374 fScaleY
= (fH
/fW
)*(sy
*fScaleZ
+fScaleX
)-(sx
*fScaleZ
);
375 lcl_ensureScaleValue( fScaleY
);
378 fScaleY
= 1.0;//looking from top or bottom the height is irrelevant
380 else if( fScaleY
>0 && fScaleZ
>0 )
383 if( !::basegfx::fTools::equalZero(fH
) )
385 fScaleX
= (fW
/fH
)*(sx
*fScaleZ
+fScaleY
)-(sy
*fScaleZ
);
386 lcl_ensureScaleValue(fScaleX
);
389 fScaleX
= 1.0;//looking from top or bottom hieght is irrelevant
394 DBG_ASSERT(false, "not implemented yet");
407 //fH*zoomfactor == cz*fScaleY + sz*fScaleX;
408 //fW*zoomfactor == cz*fScaleX + sz*fScaleY;
409 //==> fScaleY*(fH*sz-fW*cz) == fScaleX*(fW*sz-fH*cz);
410 if( fScaleX
>0 && fScaleZ
>0 )
413 double fDivide
= fH
*sz
-fW
*cz
;
414 if( !::basegfx::fTools::equalZero(fDivide
) )
416 fScaleY
= fScaleX
*(fW
*sz
-fH
*cz
) / fDivide
;
417 lcl_ensureScaleValue(fScaleY
);
420 fScaleY
= 1.0;//looking from top or bottom the height is irrelevant
423 //fW*zoomfactor == fScaleX*cy*cz + fScaleY*sz*cy + fScaleZ*sy*cx;
424 //fH*zoomfactor == fScaleY*cx*cz + fScaleX*sz*cy + fScaleZ*sx*cz;
425 //==> fScaleY*(sz*cy*fH -cx*cz*fW) = fScaleX*(sz*cy*fW - cy*cz*fH) + fScaleZ*(sx*cz*fW - sy*cx*fH);
426 double fDivide = sz*cy*fH -cx*cz*fW;
427 if( !::basegfx::fTools::equalZero(fDivide) )
429 fScaleY = ( fScaleX*(sz*cy*fW - cy*cz*fH)
430 + fScaleZ*(sx*cz*fW - sy*cx*fH) ) / fDivide;
431 lcl_ensureScaleValue(fScaleY);
434 fScaleY = 1.0;//looking from top or bottom hieght is irrelevant
437 else if( fScaleY
>0 && fScaleZ
>0 )
440 double fDivide
= fW
*sz
-fH
*cz
;
441 if( !::basegfx::fTools::equalZero(fDivide
) )
443 fScaleX
= fScaleY
*(fH
*sz
-fW
*cz
) / fDivide
;
444 lcl_ensureScaleValue(fScaleX
);
447 fScaleX
= 1.0;//looking from top or bottom hieght is irrelevant
452 DBG_ASSERT(false, "not implemented yet");
464 //normalize scale factors
466 double fMax
= std::max( std::max( fScaleX
, fScaleY
) , fScaleZ
);
473 ::basegfx::B3DHomMatrix aResult
;
474 aResult
.translate( -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
475 -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
476 -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0 );
477 aResult
.scale( fScaleX
, fScaleY
, fScaleZ
);
478 aResult
.translate( FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
479 FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
480 FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0 );
482 // To get the 3D aspect ratio's effect on the 2D scene size, the scene's 2D size needs to be adapted to
483 // 3D content changes here. The tooling class remembers the current 3D transformation stack
484 // and in it's destructor, calculates a new 2D SnapRect for the scene and it's modified 3D geometry.
485 E3DModifySceneSnapRectUpdater
aUpdater(lcl_getE3dScene( m_xOuterGroupShape
));
487 m_xAspectRatio3D
->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX
)
488 , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aResult
)) );
490 catch( uno::Exception
& e
)
492 ASSERT_EXCEPTION( e
);
497 ::basegfx::B2IRectangle
VDiagram::adjustPosAndSize_3d( const awt::Point
& rPos
, const awt::Size
& rAvailableSize
)
499 adjustAspectRatio3d( rAvailableSize
);
501 //do not change aspect ratio of 3D scene with 2D bound rect
502 m_aCurrentSizeWithoutAxes
= ShapeFactory::calculateNewSizeRespectingAspectRatio(
503 rAvailableSize
, m_xOuterGroupShape
->getSize() );
504 m_xOuterGroupShape
->setSize( m_aCurrentSizeWithoutAxes
);
506 //center diagram position
507 m_aCurrentPosWithoutAxes
= ShapeFactory::calculateTopLeftPositionToCenterObject(
508 rPos
, rAvailableSize
, m_aCurrentSizeWithoutAxes
);
509 m_xOuterGroupShape
->setPosition(m_aCurrentPosWithoutAxes
);
511 return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes
,m_aCurrentSizeWithoutAxes
) );
514 void VDiagram::createShapes_3d()
516 DBG_ASSERT(m_pShapeFactory
&&m_xLogicTarget
.is()&&m_xFinalTarget
.is()&&m_xShapeFactory
.is(),"is not proper initialized");
517 if(!(m_pShapeFactory
&&m_xLogicTarget
.is()&&m_xFinalTarget
.is()&&m_xShapeFactory
.is()))
521 m_xOuterGroupShape
= uno::Reference
< drawing::XShape
>(
522 m_xShapeFactory
->createInstance( C2U(
523 "com.sun.star.drawing.Shape3DSceneObject" ) ), uno::UNO_QUERY
);
524 m_xLogicTarget
->add(m_xOuterGroupShape
);
526 uno::Reference
< drawing::XShapes
> xOuterGroup_Shapes
=
527 uno::Reference
<drawing::XShapes
>( m_xOuterGroupShape
, uno::UNO_QUERY
);
530 //-------------------------------------------------------------------------
531 //create additional group to manipulate the aspect ratio of the whole diagram:
532 xOuterGroup_Shapes
= m_pShapeFactory
->createGroup3D( xOuterGroup_Shapes
, rtl::OUString() );
534 m_xAspectRatio3D
= uno::Reference
< beans::XPropertySet
>( xOuterGroup_Shapes
, uno::UNO_QUERY
);
536 //---------------------------
538 bool bAddFloorAndWall
= DiagramHelper::isSupportingFloorAndWall( m_xDiagram
);
542 uno::Reference
< beans::XPropertySet
> xWallProp( NULL
);
543 if( m_xDiagram
.is() )
544 xWallProp
=uno::Reference
< beans::XPropertySet
>( m_xDiagram
->getWall());
546 rtl::OUString
aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL
, rtl::OUString() ) );//@todo read CID from model
547 if( !bAddFloorAndWall
)
548 aWallCID
= rtl::OUString();
549 uno::Reference
< drawing::XShapes
> xWallGroup_Shapes( m_pShapeFactory
->createGroup3D( xOuterGroup_Shapes
, aWallCID
) );
553 CuboidPlanePosition
eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference
< beans::XPropertySet
>( m_xDiagram
, uno::UNO_QUERY
) ) );
554 if( CuboidPlanePosition_Right
==eLeftWallPos
)
555 xPos
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
556 Stripe
aStripe( drawing::Position3D(xPos
,FIXED_SIZE_FOR_3D_CHART_VOLUME
,0)
557 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME
,0)
558 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME
) );
560 uno::Reference
< drawing::XShape
> xShape
=
561 m_pShapeFactory
->createStripe( xWallGroup_Shapes
, aStripe
562 , xWallProp
, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), true, true );
563 if( !bAddFloorAndWall
)
565 //we always need this object as dummy object for correct scene dimensions
566 //but it should not be visible in this case:
567 ShapeFactory::makeShapeInvisible( xShape
);
573 CuboidPlanePosition
eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference
< beans::XPropertySet
>( m_xDiagram
, uno::UNO_QUERY
) ) );
574 if( CuboidPlanePosition_Front
==eBackWallPos
)
575 zPos
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
576 Stripe
aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME
,zPos
)
577 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME
,0,0)
578 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME
,0) );
580 uno::Reference
< drawing::XShape
> xShape
=
581 m_pShapeFactory
->createStripe(xWallGroup_Shapes
, aStripe
582 , xWallProp
, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), true );
583 if( !bAddFloorAndWall
)
585 //we always need this object as dummy object for correct scene dimensions
586 //but it should not be visible in this case:
587 ShapeFactory::makeShapeInvisible( xShape
);
594 uno::Reference
< beans::XPropertySet
> xSourceProp( m_xDiagram
, uno::UNO_QUERY_THROW
);
595 uno::Reference
< beans::XPropertySet
> xDestProp( m_xOuterGroupShape
, uno::UNO_QUERY_THROW
);
599 //ignore distance and focal length from file format and model comcpletely
600 //use vrp only to indicate the distance of the camera and thus influence the perspecitve
601 xDestProp
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_DISTANCE
), uno::makeAny(
602 static_cast<sal_Int32
>(ThreeDHelper::getCameraDistance( xSourceProp
))));
603 xDestProp
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_PERSPECTIVE
),
604 xSourceProp
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_PERSPECTIVE
)));
609 xDestProp
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_SHADE_MODE
),
610 xSourceProp
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_SHADE_MODE
)));
611 xDestProp
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR
),
612 xSourceProp
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR
)));
613 xDestProp
->setPropertyValue( C2U( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING
),
614 xSourceProp
->getPropertyValue( C2U( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING
)));
615 lcl_setLightSources( xSourceProp
, xDestProp
);
620 //set diagrams rotation is set exclusively vie the transformation matrix
621 //don't set a camera at all!
622 //the cameras rotation is incorporated into this matrix
624 ::basegfx::B3DHomMatrix aEffectiveTranformation
;
625 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);
627 if(!m_bRightAngledAxes
)
628 aEffectiveTranformation
.rotate(m_fXAnglePi
,m_fYAnglePi
,m_fZAnglePi
);
630 aEffectiveTranformation
.shearXY(m_fYAnglePi
,-m_fXAnglePi
);
632 //#i98497# 3D charts are rendered with wrong size
633 E3DModifySceneSnapRectUpdater
aUpdater(lcl_getE3dScene( m_xOuterGroupShape
));
634 xDestProp
->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX
),
635 uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aEffectiveTranformation
) ) );
638 catch( const uno::Exception
& ex
)
640 ASSERT_EXCEPTION( ex
);
645 uno::Reference
< beans::XPropertySet
> xFloorProp( NULL
);
646 if( m_xDiagram
.is() )
647 xFloorProp
=uno::Reference
< beans::XPropertySet
>( m_xDiagram
->getFloor());
649 uno::Reference
< drawing::XShape
> xShape(
650 m_xShapeFactory
->createInstance( C2U(
651 "com.sun.star.drawing.Shape3DExtrudeObject") ), uno::UNO_QUERY
);
652 xOuterGroup_Shapes
->add(xShape
);
653 uno::Reference
< beans::XPropertySet
> xShapeProp( xShape
, uno::UNO_QUERY
);
657 xShapeProp
->setPropertyValue( C2U( UNO_NAME_3D_EXTRUDE_DEPTH
)
658 , uno::makeAny((sal_Int32
)FLOOR_THICKNESS
) );
660 xShapeProp
->setPropertyValue( C2U( UNO_NAME_3D_PERCENT_DIAGONAL
)
661 , uno::makeAny( sal_Int32(0) ) );
663 drawing::Direction3D
aSize(FIXED_SIZE_FOR_3D_CHART_VOLUME
,FIXED_SIZE_FOR_3D_CHART_VOLUME
,FLOOR_THICKNESS
);
666 drawing::PolyPolygonShape3D aPoly
;
667 AddPointToPoly( aPoly
, drawing::Position3D(0,0,0) );
668 AddPointToPoly( aPoly
, drawing::Position3D(FIXED_SIZE_FOR_3D_CHART_VOLUME
,0,0) );
669 AddPointToPoly( aPoly
, drawing::Position3D(FIXED_SIZE_FOR_3D_CHART_VOLUME
,FIXED_SIZE_FOR_3D_CHART_VOLUME
,0) );
670 AddPointToPoly( aPoly
, drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME
,0) );
671 AddPointToPoly( aPoly
, drawing::Position3D(0,0,0) );
672 xShapeProp
->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D
), uno::makeAny( aPoly
) );
674 //Matrix for position
676 ::basegfx::B3DHomMatrix aM
;
677 aM
.rotate(F_PI
/2.0,0.0,0.0);
678 aM
.translate(0.0,FLOOR_THICKNESS
, 0.0);
679 drawing::HomogenMatrix aHM
= B3DHomMatrixToHomogenMatrix(aM
);
680 E3DModifySceneSnapRectUpdater
aUpdater(lcl_getE3dScene( m_xOuterGroupShape
));
681 xShapeProp
->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX
)
682 , uno::makeAny(aHM
) );
685 PropertyMapper::setMappedProperties( xShapeProp
, xFloorProp
, PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
688 CuboidPlanePosition
eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( uno::Reference
< beans::XPropertySet
>( m_xDiagram
, uno::UNO_QUERY
) ) );
689 if( !bAddFloorAndWall
|| (CuboidPlanePosition_Bottom
!=eBottomPos
) )
691 //we always need this object as dummy object for correct scene dimensions
692 //but it should not be visible in this case:
693 ShapeFactory::makeShapeInvisible( xShape
);
697 rtl::OUString
aFloorCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR
, rtl::OUString() ) );//@todo read CID from model
698 ShapeFactory::setShapeName( xShape
, aFloorCID
);
701 //---------------------------
703 //create an additional scene for the smaller inner coordinate region:
705 uno::Reference
< drawing::XShapes
> xShapes
= m_pShapeFactory
->createGroup3D( xOuterGroup_Shapes
,C2U("testonly;CooContainer=XXX_CID") );
706 m_xCoordinateRegionShape
= uno::Reference
< drawing::XShape
>( xShapes
, uno::UNO_QUERY
);
708 uno::Reference
< beans::XPropertySet
> xShapeProp( m_xCoordinateRegionShape
, uno::UNO_QUERY
);
709 DBG_ASSERT(xShapeProp
.is(), "created shape offers no XPropertySet");
714 double fXScale
= (FIXED_SIZE_FOR_3D_CHART_VOLUME
-GRID_TO_WALL_DISTANCE
) /FIXED_SIZE_FOR_3D_CHART_VOLUME
;
715 double fYScale
= (FIXED_SIZE_FOR_3D_CHART_VOLUME
-FLOOR_THICKNESS
-GRID_TO_WALL_DISTANCE
) /FIXED_SIZE_FOR_3D_CHART_VOLUME
;
716 double fZScale
= (FIXED_SIZE_FOR_3D_CHART_VOLUME
-GRID_TO_WALL_DISTANCE
) /FIXED_SIZE_FOR_3D_CHART_VOLUME
;
718 ::basegfx::B3DHomMatrix aM
;
719 aM
.translate(GRID_TO_WALL_DISTANCE
/fXScale
, (FLOOR_THICKNESS
+GRID_TO_WALL_DISTANCE
)/fYScale
, GRID_TO_WALL_DISTANCE
/fZScale
);
720 aM
.scale( fXScale
, fYScale
, fZScale
);
721 E3DModifySceneSnapRectUpdater
aUpdater(lcl_getE3dScene( m_xOuterGroupShape
));
722 xShapeProp
->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX
)
723 , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix(aM
)) );
725 catch( uno::Exception
& e
)
727 ASSERT_EXCEPTION( e
);
732 m_aCurrentPosWithoutAxes
= m_aAvailablePosIncludingAxes
;
733 m_aCurrentSizeWithoutAxes
= m_aAvailableSizeIncludingAxes
;
734 adjustPosAndSize_3d( m_aAvailablePosIncludingAxes
, m_aAvailableSizeIncludingAxes
);
737 uno::Reference
< drawing::XShapes
> VDiagram::getCoordinateRegion()
739 return uno::Reference
<drawing::XShapes
>( m_xCoordinateRegionShape
, uno::UNO_QUERY
);
742 ::basegfx::B2IRectangle
VDiagram::getCurrentRectangle()
744 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes
,m_aCurrentSizeWithoutAxes
);
747 void VDiagram::reduceToMimimumSize()
749 if( m_xOuterGroupShape
.is() )
751 awt::Size
aMaxSize( m_aAvailableSizeIncludingAxes
);
752 awt::Point
aMaxPos( m_aAvailablePosIncludingAxes
);
754 sal_Int32 nNewWidth
= aMaxSize
.Width
/3;
755 sal_Int32 nNewHeight
= aMaxSize
.Height
/3;
756 awt::Size
aNewSize( nNewWidth
, nNewHeight
);
757 awt::Point
aNewPos( aMaxPos
);
758 aNewPos
.X
+= nNewWidth
;
759 aNewPos
.Y
+= nNewHeight
;
761 adjustPosAndSize( aNewPos
, aNewSize
);
765 ::basegfx::B2IRectangle
VDiagram::adjustInnerSize( const ::basegfx::B2IRectangle
& rConsumedOuterRect
)
767 awt::Point
aNewPos( m_aCurrentPosWithoutAxes
);
768 awt::Size
aNewSize( m_aCurrentSizeWithoutAxes
);
770 ::basegfx::B2IRectangle
rAvailableOuterRect(
771 BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes
,m_aAvailableSizeIncludingAxes
) );
773 sal_Int32 nDeltaWidth
= static_cast<sal_Int32
>(rAvailableOuterRect
.getWidth() - rConsumedOuterRect
.getWidth());
774 sal_Int32 nDeltaHeight
= static_cast<sal_Int32
>(rAvailableOuterRect
.getHeight() - rConsumedOuterRect
.getHeight());
775 if( (aNewSize
.Width
+ nDeltaWidth
) < rAvailableOuterRect
.getWidth()/3 )
776 nDeltaWidth
= static_cast<sal_Int32
>(rAvailableOuterRect
.getWidth()/3 - aNewSize
.Width
);
777 aNewSize
.Width
+= nDeltaWidth
;
779 if( (aNewSize
.Height
+ nDeltaHeight
) < rAvailableOuterRect
.getHeight()/3 )
780 nDeltaHeight
= static_cast<sal_Int32
>(rAvailableOuterRect
.getHeight()/3 - aNewSize
.Height
);
781 aNewSize
.Height
+= nDeltaHeight
;
783 sal_Int32 nDiffLeft
= rConsumedOuterRect
.getMinX() - rAvailableOuterRect
.getMinX();
784 sal_Int32 nDiffRight
= rAvailableOuterRect
.getMaxX() - rConsumedOuterRect
.getMaxX();
786 aNewPos
.X
-= nDiffLeft
;
787 else if( nDiffRight
>= 0 )
789 if( nDiffRight
> -nDiffLeft
)
790 aNewPos
.X
+= abs(nDiffLeft
);
791 else if( nDiffRight
> abs(nDeltaWidth
) )
792 aNewPos
.X
+= nDiffRight
;
794 aNewPos
.X
+= abs(nDeltaWidth
);
797 sal_Int32 nDiffUp
= rConsumedOuterRect
.getMinY() - rAvailableOuterRect
.getMinY();
798 sal_Int32 nDiffDown
= rAvailableOuterRect
.getMaxY() - rConsumedOuterRect
.getMaxY();
800 aNewPos
.Y
-= nDiffUp
;
801 else if( nDiffDown
>= 0 )
803 if( nDiffDown
> -nDiffUp
)
804 aNewPos
.Y
+= abs(nDiffUp
);
805 else if( nDiffDown
> abs(nDeltaHeight
) )
806 aNewPos
.Y
+= nDiffDown
;
808 aNewPos
.Y
+= abs(nDeltaHeight
);
811 return adjustPosAndSize( aNewPos
, aNewSize
);
814 //.............................................................................
816 //.............................................................................