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: e3dsceneupdater.cxx,v $
10 * $Revision: 1.1.2.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_svx.hxx"
33 #include <svx/e3dsceneupdater.hxx>
34 #include <drawinglayer/geometry/viewinformation3d.hxx>
35 #include <svx/obj3d.hxx>
36 #include <svx/scene3d.hxx>
37 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
39 //////////////////////////////////////////////////////////////////////////////
41 E3DModifySceneSnapRectUpdater::E3DModifySceneSnapRectUpdater(const SdrObject
* pObject
)
43 mpViewInformation3D(0)
45 // Secure old 3D transformation stack before modification
48 const E3dObject
* pE3dObject
= dynamic_cast< const E3dObject
* >(pObject
);
52 mpScene
= pE3dObject
->GetScene();
54 if(mpScene
&& mpScene
->GetScene() == mpScene
)
56 // if there is a scene and it's the outmost scene, get current 3D range
57 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(mpScene
->GetViewContact());
58 const basegfx::B3DRange
aAllContentRange(rVCScene
.getAllContentRange3D());
60 if(aAllContentRange
.isEmpty())
62 // no content, nothing to do
67 // secure current 3D transformation stack
68 mpViewInformation3D
= new drawinglayer::geometry::ViewInformation3D(rVCScene
.getViewInformation3D(aAllContentRange
));
75 E3DModifySceneSnapRectUpdater::~E3DModifySceneSnapRectUpdater()
77 if(mpScene
&& mpViewInformation3D
)
79 // after changing parts of the scene, use the secured last 3d transformation stack and the new content
80 // range to calculate a new, eventually expanded or shrunk, 2D geometry for the scene and apply it.
81 // Get new content range
82 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(mpScene
->GetViewContact());
83 basegfx::B3DRange
aAllContentRange(rVCScene
.getAllContentRange3D());
85 // only change when there is still content; else let scene stay at old SnapRect
86 if(!aAllContentRange
.isEmpty())
88 // check if object transform of scene has changed
89 if(mpViewInformation3D
->getObjectTransformation() != mpScene
->GetTransform())
91 // If Yes, it needs to be updated since it's - for historical reasons -
92 // part of the basic 3d transformation stack of the scene
93 drawinglayer::geometry::ViewInformation3D
* pNew
= new drawinglayer::geometry::ViewInformation3D(
94 mpScene
->GetTransform(), // replace object transformation with new local transform
95 mpViewInformation3D
->getOrientation(),
96 mpViewInformation3D
->getProjection(),
97 mpViewInformation3D
->getDeviceToView(),
98 mpViewInformation3D
->getViewTime(),
99 mpViewInformation3D
->getExtendedInformationSequence());
100 delete mpViewInformation3D
;
101 mpViewInformation3D
= pNew
;
104 // transform content range to scene-relative coordinates using old 3d transformation stack
105 aAllContentRange
.transform(mpViewInformation3D
->getObjectToView());
107 // build 2d relative content range
108 basegfx::B2DRange
aSnapRange(
109 aAllContentRange
.getMinX(), aAllContentRange
.getMinY(),
110 aAllContentRange
.getMaxX(), aAllContentRange
.getMaxY());
112 // transform to 2D world coordiantes using scene's 2D transformation
113 aSnapRange
.transform(rVCScene
.getObjectTransformation());
115 // snap to (old) integer
116 const Rectangle
aNewSnapRect(
117 sal_Int32(floor(aSnapRange
.getMinX())), sal_Int32(floor(aSnapRange
.getMinY())),
118 sal_Int32(ceil(aSnapRange
.getMaxX())), sal_Int32(ceil(aSnapRange
.getMaxY())));
120 // set as new SnapRect and invalidate bound volume
121 if(mpScene
->GetSnapRect() != aNewSnapRect
)
123 mpScene
->SetSnapRect(aNewSnapRect
);
124 mpScene
->InvalidateBoundVolume();
129 delete mpViewInformation3D
;
132 //////////////////////////////////////////////////////////////////////////////