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 <ShapeFactory.hxx>
21 #include <VDiagram.hxx>
22 #include <Diagram.hxx>
23 #include <PropertyMapper.hxx>
24 #include <ViewDefines.hxx>
26 #include <ObjectIdentifier.hxx>
27 #include <DiagramHelper.hxx>
28 #include <ChartType.hxx>
29 #include <BaseGFXHelper.hxx>
30 #include <ChartTypeHelper.hxx>
31 #include <ThreeDHelper.hxx>
32 #include <defines.hxx>
33 #include <editeng/unoprnms.hxx>
34 #include <svx/scene3d.hxx>
35 #include <svx/e3dsceneupdater.hxx>
36 #include <comphelper/diagnose_ex.hxx>
40 using namespace ::com::sun::star
;
41 using namespace ::com::sun::star::chart2
;
44 const rtl::Reference
<Diagram
> & xDiagram
, const drawing::Direction3D
& rPreferredAspectRatio
,
45 sal_Int32 nDimension
)
46 : m_nDimensionCount(nDimension
)
47 , m_xDiagram(xDiagram
)
48 , m_aPreferredAspectRatio(rPreferredAspectRatio
)
52 , m_bRightAngledAxes(false)
54 if( m_nDimensionCount
!= 3)
57 xDiagram
->getRotationAngle( m_fXAnglePi
, m_fYAnglePi
, m_fZAnglePi
);
58 if( ChartTypeHelper::isSupportingRightAngledAxes(
59 m_xDiagram
->getChartTypeByIndex( 0 ) ) )
62 xDiagram
->getPropertyValue(u
"RightAngledAxes"_ustr
) >>= m_bRightAngledAxes
;
63 if( m_bRightAngledAxes
)
65 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi
, m_fYAnglePi
);
75 void VDiagram::init( const rtl::Reference
<SvxShapeGroupAnyD
>& xTarget
)
80 void VDiagram::createShapes( const awt::Point
& rPos
, const awt::Size
& rSize
)
82 m_aAvailablePosIncludingAxes
= rPos
;
83 m_aAvailableSizeIncludingAxes
= rSize
;
85 if( m_nDimensionCount
== 3 )
91 ::basegfx::B2IRectangle
VDiagram::adjustPosAndSize( const awt::Point
& rPos
, const awt::Size
& rSize
)
93 ::basegfx::B2IRectangle
aAllowedRect( BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes
,m_aAvailableSizeIncludingAxes
) );
94 ::basegfx::B2IRectangle
aNewInnerRect( BaseGFXHelper::makeRectangle(rPos
,rSize
) );
95 aNewInnerRect
.intersect( aAllowedRect
);
97 if( m_nDimensionCount
== 3 )
98 aNewInnerRect
= adjustPosAndSize_3d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect
), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect
) );
100 aNewInnerRect
= adjustPosAndSize_2d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect
), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect
) );
102 return aNewInnerRect
;
105 ::basegfx::B2IRectangle
VDiagram::adjustPosAndSize_2d( const awt::Point
& rPos
, const awt::Size
& rAvailableSize
)
107 m_aCurrentPosWithoutAxes
= rPos
;
108 m_aCurrentSizeWithoutAxes
= rAvailableSize
;
109 if( m_aPreferredAspectRatio
.DirectionX
> 0 && m_aPreferredAspectRatio
.DirectionY
> 0)
111 //do not change aspect ratio
112 awt::Size
aAspectRatio( static_cast<sal_Int32
>(m_aPreferredAspectRatio
.DirectionX
*FIXED_SIZE_FOR_3D_CHART_VOLUME
),
113 static_cast<sal_Int32
>(m_aPreferredAspectRatio
.DirectionY
*FIXED_SIZE_FOR_3D_CHART_VOLUME
));
114 m_aCurrentSizeWithoutAxes
= ShapeFactory::calculateNewSizeRespectingAspectRatio(
115 rAvailableSize
, aAspectRatio
);
116 //center diagram position
117 m_aCurrentPosWithoutAxes
= ShapeFactory::calculateTopLeftPositionToCenterObject(
118 rPos
, rAvailableSize
, m_aCurrentSizeWithoutAxes
);
124 m_xWall2D
->setSize( m_aCurrentSizeWithoutAxes
);
125 m_xWall2D
->setPosition(m_aCurrentPosWithoutAxes
);
128 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes
,m_aCurrentSizeWithoutAxes
);
131 void VDiagram::createShapes_2d()
133 OSL_PRECOND(m_xTarget
.is(), "is not proper initialized");
138 rtl::Reference
<SvxShapeGroupAnyD
> xOuterGroup_Shapes
= ShapeFactory::createGroup2D(m_xTarget
);
139 m_xOuterGroupShape
= xOuterGroup_Shapes
;
141 rtl::Reference
<SvxShapeGroupAnyD
> xGroupForWall( ShapeFactory::createGroup2D(xOuterGroup_Shapes
,u
"PlotAreaExcludingAxes"_ustr
) );
143 //create independent group shape as container for datapoints and such things
144 m_xCoordinateRegionShape
= ShapeFactory::createGroup2D(xOuterGroup_Shapes
,u
"testonly;CooContainer=XXX_CID"_ustr
);
146 bool bAddFloorAndWall
= m_xDiagram
->isSupportingFloorAndWall();
150 m_xWall2D
= ShapeFactory::createRectangle( xGroupForWall
);
154 OSL_ENSURE( m_xDiagram
.is(), "Invalid Diagram model" );
155 if( m_xDiagram
.is() )
157 uno::Reference
< beans::XPropertySet
> xWallProp( m_xDiagram
->getWall());
159 PropertyMapper::setMappedProperties( *m_xWall2D
, xWallProp
, PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
161 if( !bAddFloorAndWall
)
163 //we always need this object as dummy object for correct scene dimensions
164 //but it should not be visible in this case:
165 ShapeFactory::makeShapeInvisible( m_xWall2D
);
169 //CID for selection handling
170 OUString
aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL
, u
"" ) );//@todo read CID from model
171 m_xWall2D
->SvxShape::setPropertyValue( UNO_NAME_MISC_OBJ_NAME
, uno::Any( aWallCID
) );
174 catch( const uno::Exception
& )
176 TOOLS_WARN_EXCEPTION("chart2", "" );
180 //position and size for diagram
181 adjustPosAndSize_2d( m_aAvailablePosIncludingAxes
, m_aAvailableSizeIncludingAxes
);
184 static E3dScene
* lcl_getE3dScene( const rtl::Reference
<SvxShapeGroupAnyD
>& xShape
)
186 return DynCastE3dScene(xShape
->GetSdrObject());
189 static void lcl_setLightSources(
190 const uno::Reference
< beans::XPropertySet
> & xSource
,
191 const uno::Reference
< beans::XPropertySet
> & xDest
)
193 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1
,
194 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1
));
195 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2
,
196 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2
));
197 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3
,
198 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3
));
199 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4
,
200 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4
));
201 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5
,
202 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5
));
203 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6
,
204 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6
));
205 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7
,
206 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7
));
207 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8
,
208 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8
));
210 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1
,
211 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1
));
212 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
,
213 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
));
214 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3
,
215 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3
));
216 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4
,
217 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4
));
218 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5
,
219 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5
));
220 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6
,
221 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6
));
222 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7
,
223 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7
));
224 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8
,
225 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8
));
227 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1
,
228 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1
));
229 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
,
230 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2
));
231 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3
,
232 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3
));
233 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4
,
234 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4
));
235 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5
,
236 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5
));
237 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6
,
238 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6
));
239 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7
,
240 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7
));
241 xDest
->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8
,
242 xSource
->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8
));
248 void lcl_ensureScaleValue( double& rfScale
)
250 OSL_ENSURE(rfScale
>0, "calculation error for automatic 3D height in chart");
253 else if( rfScale
<0.2 )
255 else if( rfScale
>5.0 )
261 void VDiagram::adjustAspectRatio3d( const awt::Size
& rAvailableSize
)
263 OSL_PRECOND(m_xAspectRatio3D
.is(), "created shape offers no XPropertySet");
264 if( !m_xAspectRatio3D
.is())
269 double fScaleX
= m_aPreferredAspectRatio
.DirectionX
;
270 double fScaleY
= m_aPreferredAspectRatio
.DirectionY
;
271 double fScaleZ
= m_aPreferredAspectRatio
.DirectionZ
;
273 //normalize scale factors
275 double fMax
= std::max( std::max( fScaleX
, fScaleY
) , fScaleZ
);
281 if( fScaleX
<0 || fScaleY
<0 || fScaleZ
<0 )
283 //calculate automatic 3D aspect ratio that fits good into the given 2D area
284 double fW
= rAvailableSize
.Width
;
285 double fH
= rAvailableSize
.Height
;
287 double sx
= fabs(sin(m_fXAnglePi
));
288 double sy
= fabs(sin(m_fYAnglePi
));
289 double cz
= fabs(cos(m_fZAnglePi
));
290 double sz
= fabs(sin(m_fZAnglePi
));
292 if(m_bRightAngledAxes
)
295 //fH*zoomfactor == sx*fScaleZ + fScaleY;
296 //fW*zoomfactor == sy*fScaleZ + fScaleX;
298 if( fScaleX
>0 && fScaleZ
>0 )
301 if( !::basegfx::fTools::equalZero(fW
) )
303 fScaleY
= (fH
/fW
)*(sy
*fScaleZ
+fScaleX
)-(sx
*fScaleZ
);
304 lcl_ensureScaleValue( fScaleY
);
307 fScaleY
= 1.0;//looking from top or bottom the height is irrelevant
309 else if( fScaleY
>0 && fScaleZ
>0 )
312 if( !::basegfx::fTools::equalZero(fH
) )
314 fScaleX
= (fW
/fH
)*(sx
*fScaleZ
+fScaleY
)-(sy
*fScaleZ
);
315 lcl_ensureScaleValue(fScaleX
);
318 fScaleX
= 1.0;//looking from top or bottom height is irrelevant
323 OSL_FAIL("not implemented yet");
336 //fH*zoomfactor == cz*fScaleY + sz*fScaleX;
337 //fW*zoomfactor == cz*fScaleX + sz*fScaleY;
338 //==> fScaleY*(fH*sz-fW*cz) == fScaleX*(fW*sz-fH*cz);
339 if( fScaleX
>0 && fScaleZ
>0 )
342 double fDivide
= fH
*sz
-fW
*cz
;
343 if( !::basegfx::fTools::equalZero(fDivide
) )
345 fScaleY
= fScaleX
*(fW
*sz
-fH
*cz
) / fDivide
;
346 lcl_ensureScaleValue(fScaleY
);
349 fScaleY
= 1.0;//looking from top or bottom the height is irrelevant
352 else if( fScaleY
>0 && fScaleZ
>0 )
355 double fDivide
= fW
*sz
-fH
*cz
;
356 if( !::basegfx::fTools::equalZero(fDivide
) )
358 fScaleX
= fScaleY
*(fH
*sz
-fW
*cz
) / fDivide
;
359 lcl_ensureScaleValue(fScaleX
);
362 fScaleX
= 1.0;//looking from top or bottom height is irrelevant
367 OSL_FAIL("not implemented yet");
379 //normalize scale factors
381 double fMax
= std::max( std::max( fScaleX
, fScaleY
) , fScaleZ
);
388 ::basegfx::B3DHomMatrix aResult
;
389 aResult
.translate( -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
390 -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
391 -FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0 );
392 aResult
.scale( fScaleX
, fScaleY
, fScaleZ
);
393 aResult
.translate( FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
394 FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0,
395 FIXED_SIZE_FOR_3D_CHART_VOLUME
/2.0 );
397 // To get the 3D aspect ratio's effect on the 2D scene size, the scene's 2D size needs to be adapted to
398 // 3D content changes here. The tooling class remembers the current 3D transformation stack
399 // and in its destructor, calculates a new 2D SnapRect for the scene and it's modified 3D geometry.
400 E3DModifySceneSnapRectUpdater
aUpdater(lcl_getE3dScene(m_xOuterGroupShape
));
402 m_xAspectRatio3D
->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
403 , uno::Any(BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aResult
)) );
405 catch( const uno::Exception
& )
407 TOOLS_WARN_EXCEPTION("chart2", "" );
411 ::basegfx::B2IRectangle
VDiagram::adjustPosAndSize_3d( const awt::Point
& rPos
, const awt::Size
& rAvailableSize
)
413 adjustAspectRatio3d( rAvailableSize
);
415 //do not change aspect ratio of 3D scene with 2D bound rect
416 m_aCurrentSizeWithoutAxes
= ShapeFactory::calculateNewSizeRespectingAspectRatio(
417 rAvailableSize
, m_xOuterGroupShape
->getSize() );
418 m_xOuterGroupShape
->setSize( m_aCurrentSizeWithoutAxes
);
420 //center diagram position
421 m_aCurrentPosWithoutAxes
= ShapeFactory::calculateTopLeftPositionToCenterObject(
422 rPos
, rAvailableSize
, m_aCurrentSizeWithoutAxes
);
423 m_xOuterGroupShape
->setPosition(m_aCurrentPosWithoutAxes
);
425 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes
,m_aCurrentSizeWithoutAxes
);
428 void VDiagram::createShapes_3d()
430 OSL_PRECOND(m_xTarget
.is(), "is not proper initialized");
435 rtl::Reference
<Svx3DSceneObject
> xShapes
= ShapeFactory::createGroup3D( m_xTarget
, u
"PlotAreaExcludingAxes"_ustr
);
436 m_xOuterGroupShape
= xShapes
;
438 rtl::Reference
<SvxShapeGroupAnyD
> xOuterGroup_Shapes
= m_xOuterGroupShape
;
440 //create additional group to manipulate the aspect ratio of the whole diagram:
442 rtl::Reference
<Svx3DSceneObject
> xAdditionalGroup
= ShapeFactory::createGroup3D( xOuterGroup_Shapes
);
443 xOuterGroup_Shapes
= xAdditionalGroup
;
445 m_xAspectRatio3D
= std::move(xAdditionalGroup
);
448 bool bAddFloorAndWall
= m_xDiagram
->isSupportingFloorAndWall();
450 const bool bDoubleSided
= false;
454 uno::Reference
< beans::XPropertySet
> xWallProp
;
455 if( m_xDiagram
.is() )
456 xWallProp
.set( m_xDiagram
->getWall() );
458 OUString
aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL
, u
"" ) );//@todo read CID from model
459 if( !bAddFloorAndWall
)
461 rtl::Reference
<Svx3DSceneObject
> xWallGroup_Shapes
= ShapeFactory::createGroup3D( xOuterGroup_Shapes
, aWallCID
);
463 CuboidPlanePosition
eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( m_xDiagram
) );
464 CuboidPlanePosition
eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( m_xDiagram
) );
468 short nRotatedTexture
= ( eBackWallPos
==CuboidPlanePosition_Front
) ? 3 : 1;
470 if( eLeftWallPos
==CuboidPlanePosition_Right
)
471 xPos
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
472 Stripe
aStripe( drawing::Position3D(xPos
,FIXED_SIZE_FOR_3D_CHART_VOLUME
,0)
473 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME
)
474 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME
,0) );
475 if( eLeftWallPos
==CuboidPlanePosition_Right
)
477 nRotatedTexture
= ( eBackWallPos
==CuboidPlanePosition_Front
) ? 2 : 0;
478 aStripe
= Stripe( drawing::Position3D(xPos
,FIXED_SIZE_FOR_3D_CHART_VOLUME
,0)
479 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME
,0)
480 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME
) );
482 aStripe
.InvertNormal(true);
484 rtl::Reference
<Svx3DPolygonObject
> xShape
=
485 ShapeFactory::createStripe( xWallGroup_Shapes
, aStripe
486 , xWallProp
, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided
, nRotatedTexture
);
487 if( !bAddFloorAndWall
)
489 //we always need this object as dummy object for correct scene dimensions
490 //but it should not be visible in this case:
491 ShapeFactory::makeShapeInvisible( xShape
);
496 short nRotatedTexture
= 0;
498 if( eBackWallPos
==CuboidPlanePosition_Front
)
499 zPos
= FIXED_SIZE_FOR_3D_CHART_VOLUME
;
500 Stripe
aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME
,zPos
)
501 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME
,0)
502 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME
,0,0) );
503 if( eBackWallPos
==CuboidPlanePosition_Front
)
505 aStripe
= Stripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME
,zPos
)
506 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME
,0,0)
507 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME
,0) );
510 aStripe
.InvertNormal(true);
512 rtl::Reference
<Svx3DPolygonObject
> xShape
=
513 ShapeFactory::createStripe(xWallGroup_Shapes
, aStripe
514 , xWallProp
, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided
, nRotatedTexture
);
515 if( !bAddFloorAndWall
)
517 //we always need this object as dummy object for correct scene dimensions
518 //but it should not be visible in this case:
519 ShapeFactory::makeShapeInvisible( xShape
);
528 //ignore distance and focal length from file format and model completely
529 //use vrp only to indicate the distance of the camera and thus influence the perspective
530 m_xOuterGroupShape
->setPropertyValue( UNO_NAME_3D_SCENE_DISTANCE
, uno::Any(
531 static_cast<sal_Int32
>(m_xDiagram
->getCameraDistance())));
532 m_xOuterGroupShape
->setPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE
,
533 m_xDiagram
->getPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE
));
538 m_xOuterGroupShape
->setPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE
,
539 m_xDiagram
->getPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE
));
540 m_xOuterGroupShape
->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR
,
541 m_xDiagram
->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR
));
542 m_xOuterGroupShape
->setPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING
,
543 m_xDiagram
->getPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING
));
544 lcl_setLightSources( m_xDiagram
, m_xOuterGroupShape
);
549 //set diagrams rotation is set exclusively via the transformation matrix
550 //don't set a camera at all!
551 //the camera's rotation is incorporated into this matrix
553 ::basegfx::B3DHomMatrix aEffectiveTransformation
;
554 aEffectiveTransformation
.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);
556 if(!m_bRightAngledAxes
)
557 aEffectiveTransformation
.rotate(m_fXAnglePi
,m_fYAnglePi
,m_fZAnglePi
);
559 aEffectiveTransformation
.shearXY(m_fYAnglePi
,-m_fXAnglePi
);
561 //#i98497# 3D charts are rendered with wrong size
562 E3DModifySceneSnapRectUpdater
aUpdater(lcl_getE3dScene(m_xOuterGroupShape
));
564 m_xOuterGroupShape
->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
,
565 uno::Any( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aEffectiveTransformation
) ) );
568 catch( const uno::Exception
& )
570 DBG_UNHANDLED_EXCEPTION("chart2" );
575 uno::Reference
< beans::XPropertySet
> xFloorProp
;
576 if( m_xDiagram
.is() )
577 xFloorProp
.set( m_xDiagram
->getFloor() );
579 Stripe
aStripe( drawing::Position3D(0,0,0)
580 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME
)
581 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME
,0,0) );
582 aStripe
.InvertNormal(true);
584 rtl::Reference
<Svx3DPolygonObject
> xShape
=
585 ShapeFactory::createStripe(xOuterGroup_Shapes
, aStripe
586 , xFloorProp
, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided
);
588 CuboidPlanePosition
eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( m_xDiagram
) );
589 if( !bAddFloorAndWall
|| (eBottomPos
!=CuboidPlanePosition_Bottom
) )
591 //we always need this object as dummy object for correct scene dimensions
592 //but it should not be visible in this case:
593 ShapeFactory::makeShapeInvisible( xShape
);
597 OUString
aFloorCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR
, u
"" ) );//@todo read CID from model
598 ShapeFactory::setShapeName( xShape
, aFloorCID
);
602 //create an additional scene for the smaller inner coordinate region:
604 rtl::Reference
<Svx3DSceneObject
> xShapes2
= ShapeFactory::createGroup3D( xOuterGroup_Shapes
,u
"testonly;CooContainer=XXX_CID"_ustr
);
605 m_xCoordinateRegionShape
= xShapes2
;
609 double fXScale
= (FIXED_SIZE_FOR_3D_CHART_VOLUME
-GRID_TO_WALL_DISTANCE
) /FIXED_SIZE_FOR_3D_CHART_VOLUME
;
610 double fYScale
= (FIXED_SIZE_FOR_3D_CHART_VOLUME
-GRID_TO_WALL_DISTANCE
) /FIXED_SIZE_FOR_3D_CHART_VOLUME
;
611 double fZScale
= (FIXED_SIZE_FOR_3D_CHART_VOLUME
-GRID_TO_WALL_DISTANCE
) /FIXED_SIZE_FOR_3D_CHART_VOLUME
;
613 ::basegfx::B3DHomMatrix aM
;
614 aM
.translate(GRID_TO_WALL_DISTANCE
/fXScale
, GRID_TO_WALL_DISTANCE
/fYScale
, GRID_TO_WALL_DISTANCE
/fZScale
);
615 aM
.scale( fXScale
, fYScale
, fZScale
);
616 E3DModifySceneSnapRectUpdater
aUpdater(lcl_getE3dScene(m_xOuterGroupShape
));
618 xShapes2
->SvxShape::setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
619 , uno::Any(BaseGFXHelper::B3DHomMatrixToHomogenMatrix(aM
)) );
621 catch( const uno::Exception
& )
623 TOOLS_WARN_EXCEPTION("chart2", "" );
627 m_aCurrentPosWithoutAxes
= m_aAvailablePosIncludingAxes
;
628 m_aCurrentSizeWithoutAxes
= m_aAvailableSizeIncludingAxes
;
629 adjustPosAndSize_3d( m_aAvailablePosIncludingAxes
, m_aAvailableSizeIncludingAxes
);
632 basegfx::B2IRectangle
VDiagram::getCurrentRectangle() const
634 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes
,m_aCurrentSizeWithoutAxes
);
637 void VDiagram::reduceToMinimumSize()
639 if( !m_xOuterGroupShape
.is() )
642 awt::Size
aMaxSize( m_aAvailableSizeIncludingAxes
);
643 awt::Point
aMaxPos( m_aAvailablePosIncludingAxes
);
645 sal_Int32 nNewWidth
= std::round(aMaxSize
.Width
/2.2);
646 sal_Int32 nNewHeight
= std::round(aMaxSize
.Height
/2.2);
647 awt::Size
aNewSize( nNewWidth
, nNewHeight
);
648 awt::Point
aNewPos( aMaxPos
);
649 aNewPos
.X
+= nNewWidth
;
650 aNewPos
.Y
+= nNewHeight
;
652 adjustPosAndSize( aNewPos
, aNewSize
);
655 ::basegfx::B2IRectangle
VDiagram::adjustInnerSize( const ::basegfx::B2IRectangle
& rConsumedOuterRect
)
657 awt::Point aNewPos
= m_aCurrentPosWithoutAxes
;
658 awt::Size aNewSize
= m_aCurrentSizeWithoutAxes
;
660 basegfx::B2IRectangle aAvailableOuterRect
=
661 BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes
, m_aAvailableSizeIncludingAxes
);
663 sal_Int32 nDeltaWidth
= aAvailableOuterRect
.getWidth() - rConsumedOuterRect
.getWidth();
664 sal_Int32 nDeltaHeight
= aAvailableOuterRect
.getHeight() - rConsumedOuterRect
.getHeight();
665 if( (aNewSize
.Width
+ nDeltaWidth
) < aAvailableOuterRect
.getWidth()/3 )
666 nDeltaWidth
= aAvailableOuterRect
.getWidth()/3 - aNewSize
.Width
;
667 aNewSize
.Width
+= nDeltaWidth
;
669 if( (aNewSize
.Height
+ nDeltaHeight
) < aAvailableOuterRect
.getHeight()/3 )
670 nDeltaHeight
= aAvailableOuterRect
.getHeight()/3 - aNewSize
.Height
;
671 aNewSize
.Height
+= nDeltaHeight
;
673 sal_Int32 nDiffLeft
= rConsumedOuterRect
.getMinX() - aAvailableOuterRect
.getMinX();
674 sal_Int32 nDiffRight
= aAvailableOuterRect
.getMaxX() - rConsumedOuterRect
.getMaxX();
676 aNewPos
.X
-= nDiffLeft
;
677 else if( nDiffRight
>= 0 )
679 if( nDiffRight
> -nDiffLeft
)
680 aNewPos
.X
+= abs(nDiffLeft
);
681 else if( nDiffRight
> abs(nDeltaWidth
) )
682 aNewPos
.X
+= nDiffRight
;
684 aNewPos
.X
+= abs(nDeltaWidth
);
687 sal_Int32 nDiffUp
= rConsumedOuterRect
.getMinY() - aAvailableOuterRect
.getMinY();
688 sal_Int32 nDiffDown
= aAvailableOuterRect
.getMaxY() - rConsumedOuterRect
.getMaxY();
690 aNewPos
.Y
-= nDiffUp
;
691 else if( nDiffDown
>= 0 )
693 if( nDiffDown
> -nDiffUp
)
694 aNewPos
.Y
+= abs(nDiffUp
);
695 else if( nDiffDown
> abs(nDeltaHeight
) )
696 aNewPos
.Y
+= nDiffDown
;
698 aNewPos
.Y
+= abs(nDeltaHeight
);
701 return adjustPosAndSize( aNewPos
, aNewSize
);
706 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */