LibreOffice Module chart2 (master) 1
VDiagram.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <ShapeFactory.hxx>
21#include <VDiagram.hxx>
22#include <Diagram.hxx>
23#include <PropertyMapper.hxx>
24#include <ViewDefines.hxx>
25#include <Stripe.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>
37
38namespace chart
39{
40using namespace ::com::sun::star;
41using namespace ::com::sun::star::chart2;
42
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)
49 , m_fXAnglePi(0)
50 , m_fYAnglePi(0)
51 , m_fZAnglePi(0)
52 , m_bRightAngledAxes(false)
53{
54 if( m_nDimensionCount != 3)
55 return;
56
57 xDiagram->getRotationAngle( m_fXAnglePi, m_fYAnglePi, m_fZAnglePi );
58 if( ChartTypeHelper::isSupportingRightAngledAxes(
59 m_xDiagram->getChartTypeByIndex( 0 ) ) )
60 {
61 if(xDiagram.is())
62 xDiagram->getPropertyValue("RightAngledAxes") >>= m_bRightAngledAxes;
63 if( m_bRightAngledAxes )
64 {
65 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi, m_fYAnglePi );
66 m_fZAnglePi=0.0;
67 }
68 }
69}
70
71VDiagram::~VDiagram()
72{
73}
74
75void VDiagram::init( const rtl::Reference<SvxShapeGroupAnyD>& xTarget )
76{
78}
79
80void VDiagram::createShapes( const awt::Point& rPos, const awt::Size& rSize )
81{
82 m_aAvailablePosIncludingAxes = rPos;
83 m_aAvailableSizeIncludingAxes = rSize;
84
85 if( m_nDimensionCount == 3 )
86 createShapes_3d();
87 else
88 createShapes_2d();
89}
90
91::basegfx::B2IRectangle VDiagram::adjustPosAndSize( const awt::Point& rPos, const awt::Size& rSize )
92{
93 ::basegfx::B2IRectangle aAllowedRect( BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes,m_aAvailableSizeIncludingAxes) );
94 ::basegfx::B2IRectangle aNewInnerRect( BaseGFXHelper::makeRectangle(rPos,rSize) );
95 aNewInnerRect.intersect( aAllowedRect );
96
97 if( m_nDimensionCount == 3 )
98 aNewInnerRect = adjustPosAndSize_3d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
99 else
100 aNewInnerRect = adjustPosAndSize_2d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
101
102 return aNewInnerRect;
103}
104
105::basegfx::B2IRectangle VDiagram::adjustPosAndSize_2d( const awt::Point& rPos, const awt::Size& rAvailableSize )
106{
107 m_aCurrentPosWithoutAxes = rPos;
108 m_aCurrentSizeWithoutAxes = rAvailableSize;
109 if( m_aPreferredAspectRatio.DirectionX > 0 && m_aPreferredAspectRatio.DirectionY > 0)
110 {
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 );
119
120 }
121
122 if( m_xWall2D.is() )
123 {
124 m_xWall2D->setSize( m_aCurrentSizeWithoutAxes);
125 m_xWall2D->setPosition(m_aCurrentPosWithoutAxes);
126 }
127
128 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes);
129}
130
131void VDiagram::createShapes_2d()
132{
133 OSL_PRECOND(m_xTarget.is(), "is not proper initialized");
134 if (!m_xTarget.is())
135 return;
136
137 //create group shape
138 rtl::Reference<SvxShapeGroupAnyD> xOuterGroup_Shapes = ShapeFactory::createGroup2D(m_xTarget);
139 m_xOuterGroupShape = xOuterGroup_Shapes;
140
141 rtl::Reference<SvxShapeGroupAnyD> xGroupForWall( ShapeFactory::createGroup2D(xOuterGroup_Shapes,"PlotAreaExcludingAxes") );
142
143 //create independent group shape as container for datapoints and such things
144 m_xCoordinateRegionShape = ShapeFactory::createGroup2D(xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID");
145
146 bool bAddFloorAndWall = m_xDiagram->isSupportingFloorAndWall();
147
148 //add back wall
149 {
150 m_xWall2D = ShapeFactory::createRectangle( xGroupForWall );
151
152 try
153 {
154 OSL_ENSURE( m_xDiagram.is(), "Invalid Diagram model" );
155 if( m_xDiagram.is() )
156 {
157 uno::Reference< beans::XPropertySet > xWallProp( m_xDiagram->getWall());
158 if( xWallProp.is())
159 PropertyMapper::setMappedProperties( *m_xWall2D, xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
160 }
161 if( !bAddFloorAndWall )
162 {
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 );
166 }
167 else
168 {
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 ) );
172 }
173 }
174 catch( const uno::Exception& )
175 {
176 TOOLS_WARN_EXCEPTION("chart2", "" );
177 }
178 }
179
180 //position and size for diagram
181 adjustPosAndSize_2d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
182}
183
185{
186 return DynCastE3dScene(xShape->GetSdrObject());
187}
188
192{
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));
209
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));
226
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));
243}
244
245namespace
246{
247
248void lcl_ensureScaleValue( double& rfScale )
249{
250 OSL_ENSURE(rfScale>0, "calculation error for automatic 3D height in chart");
251 if( rfScale<0 )
252 rfScale = 1.0;
253 else if( rfScale<0.2 )
254 rfScale = 0.2;
255 else if( rfScale>5.0 )
256 rfScale = 5.0;
257}
258
259}
260
261void VDiagram::adjustAspectRatio3d( const awt::Size& rAvailableSize )
262{
263 OSL_PRECOND(m_xAspectRatio3D.is(), "created shape offers no XPropertySet");
264 if( !m_xAspectRatio3D.is())
265 return;
266
267 try
268 {
269 double fScaleX = m_aPreferredAspectRatio.DirectionX;
270 double fScaleY = m_aPreferredAspectRatio.DirectionY;
271 double fScaleZ = m_aPreferredAspectRatio.DirectionZ;
272
273 //normalize scale factors
274 {
275 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
276 fScaleX/=fMax;
277 fScaleY/=fMax;
278 fScaleZ/=fMax;
279 }
280
281 if( fScaleX<0 || fScaleY<0 || fScaleZ<0 )
282 {
283 //calculate automatic 3D aspect ratio that fits good into the given 2D area
284 double fW = rAvailableSize.Width;
285 double fH = rAvailableSize.Height;
286
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));
291
292 if(m_bRightAngledAxes)
293 {
294 //base equations:
295 //fH*zoomfactor == sx*fScaleZ + fScaleY;
296 //fW*zoomfactor == sy*fScaleZ + fScaleX;
297
298 if( fScaleX>0 && fScaleZ>0 )
299 {
300 //calculate fScaleY:
301 if( !::basegfx::fTools::equalZero(fW) )
302 {
303 fScaleY = (fH/fW)*(sy*fScaleZ+fScaleX)-(sx*fScaleZ);
304 lcl_ensureScaleValue( fScaleY );
305 }
306 else
307 fScaleY = 1.0;//looking from top or bottom the height is irrelevant
308 }
309 else if( fScaleY>0 && fScaleZ>0 )
310 {
311 //calculate fScaleX:
312 if( !::basegfx::fTools::equalZero(fH) )
313 {
314 fScaleX = (fW/fH)*(sx*fScaleZ+fScaleY)-(sy*fScaleZ);
315 lcl_ensureScaleValue(fScaleX);
316 }
317 else
318 fScaleX = 1.0;//looking from top or bottom height is irrelevant
319 }
320 else
321 {
322 //todo
323 OSL_FAIL("not implemented yet");
324
325 if( fScaleX<0 )
326 fScaleX = 1.0;
327 if( fScaleY<0 )
328 fScaleY = 1.0;
329 if( fScaleZ<0 )
330 fScaleZ = 1.0;
331 }
332 }
333 else
334 {
335 //base equations:
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 )
340 {
341 //calculate fScaleY:
342 double fDivide = fH*sz-fW*cz;
343 if( !::basegfx::fTools::equalZero(fDivide) )
344 {
345 fScaleY = fScaleX*(fW*sz-fH*cz) / fDivide;
346 lcl_ensureScaleValue(fScaleY);
347 }
348 else
349 fScaleY = 1.0;//looking from top or bottom the height is irrelevant
350
351 }
352 else if( fScaleY>0 && fScaleZ>0 )
353 {
354 //calculate fScaleX:
355 double fDivide = fW*sz-fH*cz;
356 if( !::basegfx::fTools::equalZero(fDivide) )
357 {
358 fScaleX = fScaleY*(fH*sz-fW*cz) / fDivide;
359 lcl_ensureScaleValue(fScaleX);
360 }
361 else
362 fScaleX = 1.0;//looking from top or bottom height is irrelevant
363 }
364 else
365 {
366 //todo
367 OSL_FAIL("not implemented yet");
368
369 if( fScaleX<0 )
370 fScaleX = 1.0;
371 if( fScaleY<0 )
372 fScaleY = 1.0;
373 if( fScaleZ<0 )
374 fScaleZ = 1.0;
375 }
376 }
377 }
378
379 //normalize scale factors
380 {
381 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
382 fScaleX/=fMax;
383 fScaleY/=fMax;
384 fScaleZ/=fMax;
385 }
386
387 // identity matrix
392 aResult.scale( fScaleX, fScaleY, fScaleZ );
396
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));
401
402 m_xAspectRatio3D->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
404 }
405 catch( const uno::Exception& )
406 {
407 TOOLS_WARN_EXCEPTION("chart2", "" );
408 }
409}
410
411::basegfx::B2IRectangle VDiagram::adjustPosAndSize_3d( const awt::Point& rPos, const awt::Size& rAvailableSize )
412{
413 adjustAspectRatio3d( rAvailableSize );
414
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 );
419
420 //center diagram position
421 m_aCurrentPosWithoutAxes= ShapeFactory::calculateTopLeftPositionToCenterObject(
422 rPos, rAvailableSize, m_aCurrentSizeWithoutAxes );
423 m_xOuterGroupShape->setPosition(m_aCurrentPosWithoutAxes);
424
425 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes);
426}
427
428void VDiagram::createShapes_3d()
429{
430 OSL_PRECOND(m_xTarget.is(), "is not proper initialized");
431 if (!m_xTarget.is())
432 return;
433
434 //create shape
435 rtl::Reference<Svx3DSceneObject> xShapes = ShapeFactory::createGroup3D( m_xTarget, "PlotAreaExcludingAxes" );
436 m_xOuterGroupShape = xShapes;
437
438 rtl::Reference<SvxShapeGroupAnyD> xOuterGroup_Shapes = m_xOuterGroupShape;
439
440 //create additional group to manipulate the aspect ratio of the whole diagram:
441 xOuterGroup_Shapes = ShapeFactory::createGroup3D( xOuterGroup_Shapes );
442
443 m_xAspectRatio3D = xOuterGroup_Shapes;
444
445 bool bAddFloorAndWall = m_xDiagram->isSupportingFloorAndWall();
446
447 const bool bDoubleSided = false;
448
449 //add walls
450 {
452 if( m_xDiagram.is() )
453 xWallProp.set( m_xDiagram->getWall() );
454
455 OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, u"" ) );//@todo read CID from model
456 if( !bAddFloorAndWall )
457 aWallCID.clear();
458 rtl::Reference<Svx3DSceneObject> xWallGroup_Shapes = ShapeFactory::createGroup3D( xOuterGroup_Shapes, aWallCID );
459
460 CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( m_xDiagram ) );
461 CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( m_xDiagram ) );
462
463 //add left wall
464 {
465 short nRotatedTexture = ( eBackWallPos==CuboidPlanePosition_Front ) ? 3 : 1;
466 double xPos = 0.0;
467 if( eLeftWallPos==CuboidPlanePosition_Right )
469 Stripe aStripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
470 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
471 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
472 if( eLeftWallPos==CuboidPlanePosition_Right )
473 {
474 nRotatedTexture = ( eBackWallPos==CuboidPlanePosition_Front ) ? 2 : 0;
475 aStripe = Stripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
476 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
477 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) );
478 }
479 aStripe.InvertNormal(true);
480
482 ShapeFactory::createStripe( xWallGroup_Shapes, aStripe
483 , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture );
484 if( !bAddFloorAndWall )
485 {
486 //we always need this object as dummy object for correct scene dimensions
487 //but it should not be visible in this case:
488 ShapeFactory::makeShapeInvisible( xShape );
489 }
490 }
491 //add back wall
492 {
493 short nRotatedTexture = 0;
494 double zPos = 0.0;
495 if( eBackWallPos==CuboidPlanePosition_Front )
497 Stripe aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
498 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
499 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
500 if( eBackWallPos==CuboidPlanePosition_Front )
501 {
502 aStripe = Stripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
503 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0)
504 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
505 nRotatedTexture = 3;
506 }
507 aStripe.InvertNormal(true);
508
510 ShapeFactory::createStripe(xWallGroup_Shapes, aStripe
511 , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture );
512 if( !bAddFloorAndWall )
513 {
514 //we always need this object as dummy object for correct scene dimensions
515 //but it should not be visible in this case:
516 ShapeFactory::makeShapeInvisible( xShape );
517 }
518 }
519 }
520
521 try
522 {
523 //perspective
524 {
525 //ignore distance and focal length from file format and model completely
526 //use vrp only to indicate the distance of the camera and thus influence the perspective
527 m_xOuterGroupShape->setPropertyValue( UNO_NAME_3D_SCENE_DISTANCE, uno::Any(
528 static_cast<sal_Int32>(m_xDiagram->getCameraDistance())));
529 m_xOuterGroupShape->setPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE,
530 m_xDiagram->getPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE));
531 }
532
533 //light
534 {
535 m_xOuterGroupShape->setPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE,
536 m_xDiagram->getPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE));
537 m_xOuterGroupShape->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR,
538 m_xDiagram->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR));
539 m_xOuterGroupShape->setPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING,
540 m_xDiagram->getPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING));
541 lcl_setLightSources( m_xDiagram, m_xOuterGroupShape );
542 }
543
544 //rotation
545 {
546 //set diagrams rotation is set exclusively via the transformation matrix
547 //don't set a camera at all!
548 //the camera's rotation is incorporated into this matrix
549
550 ::basegfx::B3DHomMatrix aEffectiveTransformation;
552
553 if(!m_bRightAngledAxes)
554 aEffectiveTransformation.rotate(m_fXAnglePi,m_fYAnglePi,m_fZAnglePi);
555 else
556 aEffectiveTransformation.shearXY(m_fYAnglePi,-m_fXAnglePi);
557
558 //#i98497# 3D charts are rendered with wrong size
559 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene(m_xOuterGroupShape));
560
561 m_xOuterGroupShape->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX,
562 uno::Any( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aEffectiveTransformation ) ) );
563 }
564 }
565 catch( const uno::Exception & )
566 {
567 DBG_UNHANDLED_EXCEPTION("chart2" );
568 }
569
570 //add floor plate
571 {
573 if( m_xDiagram.is() )
574 xFloorProp.set( m_xDiagram->getFloor() );
575
576 Stripe aStripe( drawing::Position3D(0,0,0)
577 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
578 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
579 aStripe.InvertNormal(true);
580
582 ShapeFactory::createStripe(xOuterGroup_Shapes, aStripe
583 , xFloorProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided );
584
585 CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( m_xDiagram ) );
586 if( !bAddFloorAndWall || (eBottomPos!=CuboidPlanePosition_Bottom) )
587 {
588 //we always need this object as dummy object for correct scene dimensions
589 //but it should not be visible in this case:
590 ShapeFactory::makeShapeInvisible( xShape );
591 }
592 else
593 {
594 OUString aFloorCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, u"" ) );//@todo read CID from model
595 ShapeFactory::setShapeName( xShape, aFloorCID );
596 }
597 }
598
599 //create an additional scene for the smaller inner coordinate region:
600 {
601 rtl::Reference<Svx3DSceneObject> xShapes2 = ShapeFactory::createGroup3D( xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID" );
602 m_xCoordinateRegionShape = xShapes2;
603
604 try
605 {
609
612 aM.scale( fXScale, fYScale, fZScale );
613 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene(m_xOuterGroupShape));
614
615 xShapes2->SvxShape::setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
617 }
618 catch( const uno::Exception& )
619 {
620 TOOLS_WARN_EXCEPTION("chart2", "" );
621 }
622 }
623
624 m_aCurrentPosWithoutAxes = m_aAvailablePosIncludingAxes;
625 m_aCurrentSizeWithoutAxes = m_aAvailableSizeIncludingAxes;
626 adjustPosAndSize_3d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
627}
628
629basegfx::B2IRectangle VDiagram::getCurrentRectangle() const
630{
631 return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes);
632}
633
634void VDiagram::reduceToMinimumSize()
635{
636 if( !m_xOuterGroupShape.is() )
637 return;
638
639 awt::Size aMaxSize( m_aAvailableSizeIncludingAxes );
640 awt::Point aMaxPos( m_aAvailablePosIncludingAxes );
641
642 sal_Int32 nNewWidth = std::round(aMaxSize.Width/2.2);
643 sal_Int32 nNewHeight = std::round(aMaxSize.Height/2.2);
644 awt::Size aNewSize( nNewWidth, nNewHeight );
645 awt::Point aNewPos( aMaxPos );
646 aNewPos.X += nNewWidth;
647 aNewPos.Y += nNewHeight;
648
649 adjustPosAndSize( aNewPos, aNewSize );
650}
651
652::basegfx::B2IRectangle VDiagram::adjustInnerSize( const ::basegfx::B2IRectangle& rConsumedOuterRect )
653{
654 awt::Point aNewPos = m_aCurrentPosWithoutAxes;
655 awt::Size aNewSize = m_aCurrentSizeWithoutAxes;
656
657 basegfx::B2IRectangle aAvailableOuterRect =
658 BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes);
659
660 sal_Int32 nDeltaWidth = aAvailableOuterRect.getWidth() - rConsumedOuterRect.getWidth();
661 sal_Int32 nDeltaHeight = aAvailableOuterRect.getHeight() - rConsumedOuterRect.getHeight();
662 if( (aNewSize.Width + nDeltaWidth) < aAvailableOuterRect.getWidth()/3 )
663 nDeltaWidth = aAvailableOuterRect.getWidth()/3 - aNewSize.Width;
664 aNewSize.Width += nDeltaWidth;
665
666 if( (aNewSize.Height + nDeltaHeight) < aAvailableOuterRect.getHeight()/3 )
667 nDeltaHeight = aAvailableOuterRect.getHeight()/3 - aNewSize.Height;
668 aNewSize.Height += nDeltaHeight;
669
670 sal_Int32 nDiffLeft = rConsumedOuterRect.getMinX() - aAvailableOuterRect.getMinX();
671 sal_Int32 nDiffRight = aAvailableOuterRect.getMaxX() - rConsumedOuterRect.getMaxX();
672 if( nDiffLeft >= 0 )
673 aNewPos.X -= nDiffLeft;
674 else if( nDiffRight >= 0 )
675 {
676 if( nDiffRight > -nDiffLeft )
677 aNewPos.X += abs(nDiffLeft);
678 else if( nDiffRight > abs(nDeltaWidth) )
679 aNewPos.X += nDiffRight;
680 else
681 aNewPos.X += abs(nDeltaWidth);
682 }
683
684 sal_Int32 nDiffUp = rConsumedOuterRect.getMinY() - aAvailableOuterRect.getMinY();
685 sal_Int32 nDiffDown = aAvailableOuterRect.getMaxY() - rConsumedOuterRect.getMaxY();
686 if( nDiffUp >= 0 )
687 aNewPos.Y -= nDiffUp;
688 else if( nDiffDown >= 0 )
689 {
690 if( nDiffDown > -nDiffUp )
691 aNewPos.Y += abs(nDiffUp);
692 else if( nDiffDown > abs(nDeltaHeight) )
693 aNewPos.Y += nDiffDown;
694 else
695 aNewPos.Y += abs(nDeltaHeight);
696 }
697
698 return adjustPosAndSize( aNewPos, aNewSize );
699}
700
701} //namespace chart
702
703/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define GRID_TO_WALL_DISTANCE
Definition: ViewDefines.hxx:27
void shearXY(double fSx, double fSy)
void rotate(double fAngleX, double fAngleY, double fAngleZ)
void translate(double fX, double fY, double fZ)
void scale(double fX, double fY, double fZ)
TYPE getMaxX() const
TYPE getWidth() const
TYPE getMinX() const
TYPE getMinY() const
TYPE getMaxY() const
void intersect(const Range2D &rRange)
TYPE getHeight() const
A Stripe represents a 2 dimensional foursquare plane in a 3 dimensional room.
Definition: Stripe.hxx:34
void InvertNormal(bool bInvertNormal)
Definition: Stripe.cxx:76
VDiagram(const rtl::Reference<::chart::Diagram > &xDiagram, const css::drawing::Direction3D &rPreferredAspectRatio, sal_Int32 nDimension)
Reference< lang::XComponent > m_xTarget
constexpr double FIXED_SIZE_FOR_3D_CHART_VOLUME
Definition: defines.hxx:22
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
float u
Reference< XInterface > xTarget
OOO_DLLPUBLIC_CHARTTOOLS css::awt::Point B2IRectangleToAWTPoint(const ::basegfx::B2IRectangle &rB2IRectangle)
OOO_DLLPUBLIC_CHARTTOOLS css::drawing::HomogenMatrix B3DHomMatrixToHomogenMatrix(const ::basegfx::B3DHomMatrix &rB3DMatrix)
OOO_DLLPUBLIC_CHARTTOOLS::basegfx::B2IRectangle makeRectangle(const css::awt::Point &rPosition, const css::awt::Size &rSize)
OOO_DLLPUBLIC_CHARTTOOLS css::awt::Size B2IRectangleToAWTSize(const ::basegfx::B2IRectangle &rB2IRectangle)
static E3dScene * lcl_getE3dScene(const rtl::Reference< SvxShapeGroupAnyD > &xShape)
Definition: VDiagram.cxx:184
@ OBJECTTYPE_DIAGRAM_FLOOR
@ OBJECTTYPE_DIAGRAM_WALL
static void lcl_setLightSources(const uno::Reference< beans::XPropertySet > &xSource, const uno::Reference< beans::XPropertySet > &xDest)
Definition: VDiagram.cxx:189
CuboidPlanePosition
@ CuboidPlanePosition_Right
@ CuboidPlanePosition_Front
@ CuboidPlanePosition_Bottom
SwNodeOffset abs(const SwNodeOffset &a)
SVXCORE_DLLPUBLIC E3dScene * DynCastE3dScene(SdrObject *)
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTON_7
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTDIRECTION_8
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTDIRECTION_5
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTCOLOR_8
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTDIRECTION_6
constexpr OUStringLiteral UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTCOLOR_7
constexpr OUStringLiteral UNO_NAME_3D_SCENE_DISTANCE
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTON_6
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTON_3
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTON_8
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTDIRECTION_7
constexpr OUStringLiteral UNO_NAME_3D_SCENE_PERSPECTIVE
constexpr OUStringLiteral UNO_NAME_3D_TRANSFORM_MATRIX
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTON_5
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTCOLOR_5
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTDIRECTION_2
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTON_1
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTDIRECTION_3
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTDIRECTION_4
constexpr OUStringLiteral UNO_NAME_3D_SCENE_SHADE_MODE
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTCOLOR_1
constexpr OUStringLiteral UNO_NAME_3D_SCENE_AMBIENTCOLOR
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTON_4
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTDIRECTION_1
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTCOLOR_3
constexpr OUStringLiteral UNO_NAME_MISC_OBJ_NAME
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTCOLOR_2
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTCOLOR_6
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTON_2
constexpr OUStringLiteral UNO_NAME_3D_SCENE_LIGHTCOLOR_4