xref: /aoo41x/main/svx/source/engine3d/scene3d.cxx (revision f6e50924)
1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "svx/svdstr.hrc"
28cdf0e10cSrcweir #include "svx/svdglob.hxx"
29cdf0e10cSrcweir #include "svx/svditer.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #if defined( UNX ) || defined( ICC )
32cdf0e10cSrcweir #include <stdlib.h>
33cdf0e10cSrcweir #endif
34cdf0e10cSrcweir #include "svx/globl3d.hxx"
35cdf0e10cSrcweir #include <svx/svdpage.hxx>
36cdf0e10cSrcweir #include <svl/style.hxx>
37cdf0e10cSrcweir #include <svx/scene3d.hxx>
38cdf0e10cSrcweir #include <svx/e3dundo.hxx>
39cdf0e10cSrcweir #include <svx/svdtrans.hxx>
40cdf0e10cSrcweir #include <svx/svxids.hrc>
41cdf0e10cSrcweir #include <editeng/colritem.hxx>
42cdf0e10cSrcweir #include <svx/e3ditem.hxx>
43cdf0e10cSrcweir #include <svx/xlntrit.hxx>
44cdf0e10cSrcweir #include <svx/xfltrit.hxx>
45cdf0e10cSrcweir #include <svx/svx3ditems.hxx>
46cdf0e10cSrcweir #include <svl/whiter.hxx>
47cdf0e10cSrcweir #include <svx/xflftrit.hxx>
48cdf0e10cSrcweir #include <svx/sdr/properties/e3dsceneproperties.hxx>
49cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
50cdf0e10cSrcweir #include <svx/svddrag.hxx>
51cdf0e10cSrcweir #include <helperminimaldepth3d.hxx>
52cdf0e10cSrcweir #include <algorithm>
53cdf0e10cSrcweir #include <drawinglayer/geometry/viewinformation3d.hxx>
54cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
55cdf0e10cSrcweir #include <svx/e3dsceneupdater.hxx>
56cdf0e10cSrcweir 
57cdf0e10cSrcweir #define ITEMVALUE(ItemSet,Id,Cast)	((const Cast&)(ItemSet).Get(Id)).GetValue()
58cdf0e10cSrcweir 
59cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
60cdf0e10cSrcweir // #110988#
61cdf0e10cSrcweir 
62cdf0e10cSrcweir class ImpRemap3DDepth
63cdf0e10cSrcweir {
64cdf0e10cSrcweir 	sal_uInt32					mnOrdNum;
65cdf0e10cSrcweir 	double						mfMinimalDepth;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 	// bitfield
68cdf0e10cSrcweir 	unsigned					mbIsScene : 1;
69cdf0e10cSrcweir 
70cdf0e10cSrcweir public:
71cdf0e10cSrcweir 	ImpRemap3DDepth(sal_uInt32 nOrdNum, double fMinimalDepth);
72cdf0e10cSrcweir 	ImpRemap3DDepth(sal_uInt32 nOrdNum);
73cdf0e10cSrcweir 	~ImpRemap3DDepth();
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 	// for ::std::sort
76cdf0e10cSrcweir 	bool operator<(const ImpRemap3DDepth& rComp) const;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 	sal_uInt32 GetOrdNum() const { return mnOrdNum; }
79cdf0e10cSrcweir 	sal_Bool IsScene() const { return mbIsScene; }
80cdf0e10cSrcweir };
81cdf0e10cSrcweir 
82cdf0e10cSrcweir ImpRemap3DDepth::ImpRemap3DDepth(sal_uInt32 nOrdNum, double fMinimalDepth)
83cdf0e10cSrcweir :	mnOrdNum(nOrdNum),
84cdf0e10cSrcweir 	mfMinimalDepth(fMinimalDepth),
85cdf0e10cSrcweir 	mbIsScene(sal_False)
86cdf0e10cSrcweir {
87cdf0e10cSrcweir }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir ImpRemap3DDepth::ImpRemap3DDepth(sal_uInt32 nOrdNum)
90cdf0e10cSrcweir :	mnOrdNum(nOrdNum),
91cdf0e10cSrcweir 	mbIsScene(sal_True)
92cdf0e10cSrcweir {
93cdf0e10cSrcweir }
94cdf0e10cSrcweir 
95cdf0e10cSrcweir ImpRemap3DDepth::~ImpRemap3DDepth()
96cdf0e10cSrcweir {
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir bool ImpRemap3DDepth::operator<(const ImpRemap3DDepth& rComp) const
100cdf0e10cSrcweir {
101cdf0e10cSrcweir 	if(IsScene())
102cdf0e10cSrcweir 	{
103cdf0e10cSrcweir 		return sal_False;
104cdf0e10cSrcweir 	}
105cdf0e10cSrcweir 	else
106cdf0e10cSrcweir 	{
107cdf0e10cSrcweir 		if(rComp.IsScene())
108cdf0e10cSrcweir 		{
109cdf0e10cSrcweir 			return sal_True;
110cdf0e10cSrcweir 		}
111cdf0e10cSrcweir 		else
112cdf0e10cSrcweir 		{
113cdf0e10cSrcweir 			return mfMinimalDepth < rComp.mfMinimalDepth;
114cdf0e10cSrcweir 		}
115cdf0e10cSrcweir 	}
116cdf0e10cSrcweir }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir // typedefs for a vector of ImpRemap3DDepths
119cdf0e10cSrcweir typedef ::std::vector< ImpRemap3DDepth > ImpRemap3DDepthVector;
120cdf0e10cSrcweir 
121cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
122cdf0e10cSrcweir // #110988#
123cdf0e10cSrcweir 
124cdf0e10cSrcweir class Imp3DDepthRemapper
125cdf0e10cSrcweir {
126cdf0e10cSrcweir 	ImpRemap3DDepthVector		maVector;
127cdf0e10cSrcweir 
128cdf0e10cSrcweir public:
129cdf0e10cSrcweir 	Imp3DDepthRemapper(E3dScene& rScene);
130cdf0e10cSrcweir 	~Imp3DDepthRemapper();
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 	sal_uInt32 RemapOrdNum(sal_uInt32 nOrdNum) const;
133cdf0e10cSrcweir };
134cdf0e10cSrcweir 
135cdf0e10cSrcweir Imp3DDepthRemapper::Imp3DDepthRemapper(E3dScene& rScene)
136cdf0e10cSrcweir {
137cdf0e10cSrcweir 	// only called when rScene.GetSubList() and nObjCount > 1L
138cdf0e10cSrcweir 	SdrObjList* pList = rScene.GetSubList();
139cdf0e10cSrcweir 	const sal_uInt32 nObjCount(pList->GetObjCount());
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 	for(sal_uInt32 a(0L); a < nObjCount; a++)
142cdf0e10cSrcweir 	{
143cdf0e10cSrcweir 		SdrObject* pCandidate = pList->GetObj(a);
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 		if(pCandidate)
146cdf0e10cSrcweir 		{
147cdf0e10cSrcweir 			if(pCandidate->ISA(E3dCompoundObject))
148cdf0e10cSrcweir 			{
149cdf0e10cSrcweir 				// single 3d object, calc depth
150cdf0e10cSrcweir                 const double fMinimalDepth(getMinimalDepthInViewCoordinates(static_cast< const E3dCompoundObject& >(*pCandidate)));
151cdf0e10cSrcweir 				ImpRemap3DDepth aEntry(a, fMinimalDepth);
152cdf0e10cSrcweir 				maVector.push_back(aEntry);
153cdf0e10cSrcweir 			}
154cdf0e10cSrcweir 			else
155cdf0e10cSrcweir 			{
156cdf0e10cSrcweir 				// scene, use standard entry for scene
157cdf0e10cSrcweir 				ImpRemap3DDepth aEntry(a);
158cdf0e10cSrcweir 				maVector.push_back(aEntry);
159cdf0e10cSrcweir 			}
160cdf0e10cSrcweir 		}
161cdf0e10cSrcweir 	}
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 	// now, we need to sort the maVector by it's members minimal depth. The
164cdf0e10cSrcweir 	// smaller, the nearer to the viewer.
165cdf0e10cSrcweir 	::std::sort(maVector.begin(), maVector.end());
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir Imp3DDepthRemapper::~Imp3DDepthRemapper()
169cdf0e10cSrcweir {
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
172cdf0e10cSrcweir sal_uInt32 Imp3DDepthRemapper::RemapOrdNum(sal_uInt32 nOrdNum) const
173cdf0e10cSrcweir {
174cdf0e10cSrcweir 	if(nOrdNum < maVector.size())
175cdf0e10cSrcweir 	{
176cdf0e10cSrcweir 		nOrdNum = maVector[(maVector.size() - 1) - nOrdNum].GetOrdNum();
177cdf0e10cSrcweir 	}
178cdf0e10cSrcweir 
179cdf0e10cSrcweir 	return nOrdNum;
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
182cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
183cdf0e10cSrcweir // BaseProperties section
184cdf0e10cSrcweir 
185cdf0e10cSrcweir sdr::properties::BaseProperties* E3dScene::CreateObjectSpecificProperties()
186cdf0e10cSrcweir {
187cdf0e10cSrcweir 	return new sdr::properties::E3dSceneProperties(*this);
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
190cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
191cdf0e10cSrcweir // #110094# DrawContact section
192cdf0e10cSrcweir 
193cdf0e10cSrcweir sdr::contact::ViewContact* E3dScene::CreateObjectSpecificViewContact()
194cdf0e10cSrcweir {
195cdf0e10cSrcweir 	return new sdr::contact::ViewContactOfE3dScene(*this);
196cdf0e10cSrcweir }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
199cdf0e10cSrcweir 
200cdf0e10cSrcweir TYPEINIT1(E3dScene, E3dObject);
201cdf0e10cSrcweir 
202cdf0e10cSrcweir /*************************************************************************
203cdf0e10cSrcweir |*
204cdf0e10cSrcweir |* E3dScene-Konstruktor
205cdf0e10cSrcweir |*
206cdf0e10cSrcweir \************************************************************************/
207cdf0e10cSrcweir 
208cdf0e10cSrcweir E3dScene::E3dScene()
209cdf0e10cSrcweir :	E3dObject(),
210cdf0e10cSrcweir 	aCamera(basegfx::B3DPoint(0.0, 0.0, 4.0), basegfx::B3DPoint()),
211cdf0e10cSrcweir 	mp3DDepthRemapper(0L),
212cdf0e10cSrcweir 	bDrawOnlySelected(false)
213cdf0e10cSrcweir {
214cdf0e10cSrcweir 	// Defaults setzen
215cdf0e10cSrcweir 	E3dDefaultAttributes aDefault;
216cdf0e10cSrcweir 	SetDefaultAttributes(aDefault);
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
219cdf0e10cSrcweir E3dScene::E3dScene(E3dDefaultAttributes& rDefault)
220cdf0e10cSrcweir :	E3dObject(),
221cdf0e10cSrcweir 	aCamera(basegfx::B3DPoint(0.0, 0.0, 4.0), basegfx::B3DPoint()),
222cdf0e10cSrcweir 	mp3DDepthRemapper(0L),
223cdf0e10cSrcweir 	bDrawOnlySelected(false)
224cdf0e10cSrcweir {
225cdf0e10cSrcweir 	// Defaults setzen
226cdf0e10cSrcweir 	SetDefaultAttributes(rDefault);
227cdf0e10cSrcweir }
228cdf0e10cSrcweir 
229cdf0e10cSrcweir void E3dScene::SetDefaultAttributes(E3dDefaultAttributes& /*rDefault*/)
230cdf0e10cSrcweir {
231cdf0e10cSrcweir 	// Fuer OS/2 die FP-Exceptions abschalten
232cdf0e10cSrcweir #if defined(OS2)
233cdf0e10cSrcweir #define SC_FPEXCEPTIONS_ON()	_control87( MCW_EM, 0 )
234cdf0e10cSrcweir #define SC_FPEXCEPTIONS_OFF()	_control87( MCW_EM, MCW_EM )
235cdf0e10cSrcweir 	SC_FPEXCEPTIONS_OFF();
236cdf0e10cSrcweir #endif
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 	// Fuer WIN95/NT die FP-Exceptions abschalten
239cdf0e10cSrcweir #if defined(WNT)
240cdf0e10cSrcweir #define SC_FPEXCEPTIONS_ON()	_control87( _MCW_EM, 0 )
241cdf0e10cSrcweir #define SC_FPEXCEPTIONS_OFF()	_control87( _MCW_EM, _MCW_EM )
242cdf0e10cSrcweir 	SC_FPEXCEPTIONS_OFF();
243cdf0e10cSrcweir #endif
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 	// Defaults setzen
246cdf0e10cSrcweir 	aCamera.SetViewWindow(-2, -2, 4, 4);
247cdf0e10cSrcweir 	aCameraSet.SetDeviceRectangle(-2, 2, -2, 2);
248cdf0e10cSrcweir 	aCamera.SetDeviceWindow(Rectangle(0, 0, 10, 10));
249cdf0e10cSrcweir 	Rectangle aRect(0, 0, 10, 10);
250cdf0e10cSrcweir 	aCameraSet.SetViewportRectangle(aRect);
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 	// set defaults for Camera from ItemPool
253cdf0e10cSrcweir 	aCamera.SetProjection(GetPerspective());
254cdf0e10cSrcweir 	basegfx::B3DPoint aActualPosition(aCamera.GetPosition());
255cdf0e10cSrcweir 	double fNew = GetDistance();
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	if(fabs(fNew - aActualPosition.getZ()) > 1.0)
258cdf0e10cSrcweir 	{
259cdf0e10cSrcweir 		aCamera.SetPosition( basegfx::B3DPoint( aActualPosition.getX(), aActualPosition.getY(), fNew) );
260cdf0e10cSrcweir 	}
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 	fNew = GetFocalLength() / 100.0;
263cdf0e10cSrcweir 	aCamera.SetFocalLength(fNew);
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir /*************************************************************************
267cdf0e10cSrcweir |*
268cdf0e10cSrcweir |* Destruktor
269cdf0e10cSrcweir |*
270cdf0e10cSrcweir \************************************************************************/
271cdf0e10cSrcweir 
272cdf0e10cSrcweir E3dScene::~E3dScene()
273cdf0e10cSrcweir {
274cdf0e10cSrcweir 	// #110988#
275cdf0e10cSrcweir 	ImpCleanup3DDepthMapper();
276cdf0e10cSrcweir }
277cdf0e10cSrcweir 
278cdf0e10cSrcweir basegfx::B2DPolyPolygon E3dScene::TakeXorPoly() const
279cdf0e10cSrcweir {
280cdf0e10cSrcweir 	const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(GetViewContact());
281cdf0e10cSrcweir 	const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
282cdf0e10cSrcweir 	const basegfx::B3DPolyPolygon aCubePolyPolygon(CreateWireframe());
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aRetval(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCubePolyPolygon,
285cdf0e10cSrcweir 		aViewInfo3D.getObjectToView()));
286cdf0e10cSrcweir 	aRetval.transform(rVCScene.getObjectTransformation());
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 	return aRetval;
289cdf0e10cSrcweir }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir // #110988#
292cdf0e10cSrcweir void E3dScene::ImpCleanup3DDepthMapper()
293cdf0e10cSrcweir {
294cdf0e10cSrcweir 	if(mp3DDepthRemapper)
295cdf0e10cSrcweir 	{
296cdf0e10cSrcweir 		delete mp3DDepthRemapper;
297cdf0e10cSrcweir 		mp3DDepthRemapper = 0L;
298cdf0e10cSrcweir 	}
299cdf0e10cSrcweir }
300cdf0e10cSrcweir 
301cdf0e10cSrcweir // #110988#
302cdf0e10cSrcweir sal_uInt32 E3dScene::RemapOrdNum(sal_uInt32 nNewOrdNum) const
303cdf0e10cSrcweir {
304cdf0e10cSrcweir 	if(!mp3DDepthRemapper)
305cdf0e10cSrcweir 	{
306cdf0e10cSrcweir 		const sal_uInt32 nObjCount(GetSubList() ? GetSubList()->GetObjCount() : 0L);
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 		if(nObjCount > 1L)
309cdf0e10cSrcweir 		{
310cdf0e10cSrcweir 			((E3dScene*)this)->mp3DDepthRemapper = new Imp3DDepthRemapper((E3dScene&)(*this));
311cdf0e10cSrcweir 		}
312cdf0e10cSrcweir 	}
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 	if(mp3DDepthRemapper)
315cdf0e10cSrcweir 	{
316cdf0e10cSrcweir 		return mp3DDepthRemapper->RemapOrdNum(nNewOrdNum);
317cdf0e10cSrcweir 	}
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 	return nNewOrdNum;
320cdf0e10cSrcweir }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir /*************************************************************************
323cdf0e10cSrcweir |*
324cdf0e10cSrcweir |* Identifier zurueckgeben
325cdf0e10cSrcweir |*
326cdf0e10cSrcweir \************************************************************************/
327cdf0e10cSrcweir 
328cdf0e10cSrcweir sal_uInt16 E3dScene::GetObjIdentifier() const
329cdf0e10cSrcweir {
330cdf0e10cSrcweir 	return E3D_SCENE_ID;
331cdf0e10cSrcweir }
332cdf0e10cSrcweir 
333cdf0e10cSrcweir void E3dScene::SetBoundRectDirty()
334cdf0e10cSrcweir {
335cdf0e10cSrcweir 	E3dScene* pScene = GetScene();
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 	if(pScene == this)
338cdf0e10cSrcweir 	{
339cdf0e10cSrcweir 	    // avoid resetting aOutRect which in case of a 3D scene used as 2d object
340cdf0e10cSrcweir 		// is model data,not re-creatable view data
341cdf0e10cSrcweir 	}
342cdf0e10cSrcweir 	else
343cdf0e10cSrcweir 	{
344cdf0e10cSrcweir 		// if not the outmost scene it is used as group in 3d, call parent
345cdf0e10cSrcweir 		E3dObject::SetBoundRectDirty();
346cdf0e10cSrcweir 	}
347cdf0e10cSrcweir }
348cdf0e10cSrcweir 
349cdf0e10cSrcweir /*************************************************************************
350cdf0e10cSrcweir |*
351cdf0e10cSrcweir |* SetSnapRect
352cdf0e10cSrcweir |*
353cdf0e10cSrcweir \************************************************************************/
354cdf0e10cSrcweir 
355cdf0e10cSrcweir void E3dScene::NbcSetSnapRect(const Rectangle& rRect)
356cdf0e10cSrcweir {
357cdf0e10cSrcweir 	SetRectsDirty();
358cdf0e10cSrcweir 	E3dObject::NbcSetSnapRect(rRect);
359cdf0e10cSrcweir 	aCamera.SetDeviceWindow(rRect);
360cdf0e10cSrcweir 	aCameraSet.SetViewportRectangle((Rectangle&)rRect);
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 	// #110988#
363cdf0e10cSrcweir 	ImpCleanup3DDepthMapper();
364cdf0e10cSrcweir }
365cdf0e10cSrcweir 
366cdf0e10cSrcweir /*************************************************************************
367cdf0e10cSrcweir |*
368cdf0e10cSrcweir |* Objekt verschieben
369cdf0e10cSrcweir |*
370cdf0e10cSrcweir \************************************************************************/
371cdf0e10cSrcweir 
372cdf0e10cSrcweir void E3dScene::NbcMove(const Size& rSize)
373cdf0e10cSrcweir {
374cdf0e10cSrcweir 	Rectangle aNewSnapRect = GetSnapRect();
375cdf0e10cSrcweir 	MoveRect(aNewSnapRect, rSize);
376cdf0e10cSrcweir 	NbcSetSnapRect(aNewSnapRect);
377cdf0e10cSrcweir }
378cdf0e10cSrcweir 
379cdf0e10cSrcweir /*************************************************************************
380cdf0e10cSrcweir |*
381cdf0e10cSrcweir |* Objekt Resizen
382cdf0e10cSrcweir |*
383cdf0e10cSrcweir \************************************************************************/
384cdf0e10cSrcweir 
385cdf0e10cSrcweir void E3dScene::NbcResize(const Point& rRef, const Fraction& rXFact,
386cdf0e10cSrcweir 											const Fraction& rYFact)
387cdf0e10cSrcweir {
388cdf0e10cSrcweir 	Rectangle aNewSnapRect = GetSnapRect();
389cdf0e10cSrcweir 	ResizeRect(aNewSnapRect, rRef, rXFact, rYFact);
390cdf0e10cSrcweir 	NbcSetSnapRect(aNewSnapRect);
391cdf0e10cSrcweir }
392cdf0e10cSrcweir 
393cdf0e10cSrcweir /*************************************************************************
394cdf0e10cSrcweir |*
395cdf0e10cSrcweir |* Neue Kamera setzen, und dabei die Szene und ggf. das BoundVolume
396cdf0e10cSrcweir |* als geaendert markieren
397cdf0e10cSrcweir |*
398cdf0e10cSrcweir \************************************************************************/
399cdf0e10cSrcweir 
400cdf0e10cSrcweir void E3dScene::SetCamera(const Camera3D& rNewCamera)
401cdf0e10cSrcweir {
402cdf0e10cSrcweir 	// Alte Kamera setzen
403cdf0e10cSrcweir 	aCamera = rNewCamera;
404cdf0e10cSrcweir 	((sdr::properties::E3dSceneProperties&)GetProperties()).SetSceneItemsFromCamera();
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 	SetRectsDirty();
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 	// Neue Kamera aus alter fuellen
409cdf0e10cSrcweir 	Camera3D& rCam = (Camera3D&)GetCamera();
410cdf0e10cSrcweir 
411cdf0e10cSrcweir 	// Ratio abschalten
412cdf0e10cSrcweir 	if(rCam.GetAspectMapping() == AS_NO_MAPPING)
413cdf0e10cSrcweir 		GetCameraSet().SetRatio(0.0);
414cdf0e10cSrcweir 
415cdf0e10cSrcweir 	// Abbildungsgeometrie setzen
416cdf0e10cSrcweir 	basegfx::B3DPoint aVRP(rCam.GetViewPoint());
417cdf0e10cSrcweir 	basegfx::B3DVector aVPN(aVRP - rCam.GetVRP());
418cdf0e10cSrcweir 	basegfx::B3DVector aVUV(rCam.GetVUV());
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 	// #91047# use SetViewportValues() to set VRP, VPN and VUV as vectors, too.
421cdf0e10cSrcweir 	// Else these values would not be exported/imported correctly.
422cdf0e10cSrcweir 	GetCameraSet().SetViewportValues(aVRP, aVPN, aVUV);
423cdf0e10cSrcweir 
424cdf0e10cSrcweir 	// Perspektive setzen
425cdf0e10cSrcweir 	GetCameraSet().SetPerspective(rCam.GetProjection() == PR_PERSPECTIVE);
426cdf0e10cSrcweir 	GetCameraSet().SetViewportRectangle((Rectangle&)rCam.GetDeviceWindow());
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 	// #110988#
429cdf0e10cSrcweir 	ImpCleanup3DDepthMapper();
430cdf0e10cSrcweir }
431cdf0e10cSrcweir 
432cdf0e10cSrcweir /*************************************************************************
433cdf0e10cSrcweir |*
434cdf0e10cSrcweir |* 3D-Objekt einfuegen
435cdf0e10cSrcweir |*
436cdf0e10cSrcweir \************************************************************************/
437cdf0e10cSrcweir 
438cdf0e10cSrcweir void E3dScene::NewObjectInserted(const E3dObject* p3DObj)
439cdf0e10cSrcweir {
440cdf0e10cSrcweir 	E3dObject::NewObjectInserted(p3DObj);
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 	if ( p3DObj == this )
443cdf0e10cSrcweir 		return;
444cdf0e10cSrcweir 
445cdf0e10cSrcweir 	// #110988#
446cdf0e10cSrcweir 	ImpCleanup3DDepthMapper();
447cdf0e10cSrcweir }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir /*************************************************************************
450cdf0e10cSrcweir |*
451cdf0e10cSrcweir |* Parent ueber Aenderung eines Childs informieren
452cdf0e10cSrcweir |*
453cdf0e10cSrcweir \************************************************************************/
454cdf0e10cSrcweir 
455cdf0e10cSrcweir void E3dScene::StructureChanged()
456cdf0e10cSrcweir {
457cdf0e10cSrcweir 	E3dObject::StructureChanged();
458cdf0e10cSrcweir 	SetRectsDirty();
459cdf0e10cSrcweir 
460cdf0e10cSrcweir 	// #110988#
461cdf0e10cSrcweir 	ImpCleanup3DDepthMapper();
462cdf0e10cSrcweir }
463cdf0e10cSrcweir 
464cdf0e10cSrcweir /*************************************************************************
465cdf0e10cSrcweir |*
466cdf0e10cSrcweir |* Uebergeordnetes Szenenobjekt bestimmen
467cdf0e10cSrcweir |*
468cdf0e10cSrcweir \************************************************************************/
469cdf0e10cSrcweir 
470cdf0e10cSrcweir E3dScene* E3dScene::GetScene() const
471cdf0e10cSrcweir {
472cdf0e10cSrcweir 	if(GetParentObj())
473cdf0e10cSrcweir 		return GetParentObj()->GetScene();
474cdf0e10cSrcweir 	else
475cdf0e10cSrcweir 		return (E3dScene*)this;
476cdf0e10cSrcweir }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir void E3dScene::removeAllNonSelectedObjects()
479cdf0e10cSrcweir {
480cdf0e10cSrcweir 	E3DModifySceneSnapRectUpdater aUpdater(this);
481cdf0e10cSrcweir 
482cdf0e10cSrcweir     for(sal_uInt32 a(0); a < maSubList.GetObjCount(); a++)
483cdf0e10cSrcweir     {
484cdf0e10cSrcweir 		SdrObject* pObj = maSubList.GetObj(a);
485cdf0e10cSrcweir 
486cdf0e10cSrcweir         if(pObj)
487cdf0e10cSrcweir 		{
488cdf0e10cSrcweir             bool bRemoveObject(false);
489cdf0e10cSrcweir 
490cdf0e10cSrcweir             if(pObj->ISA(E3dScene))
491cdf0e10cSrcweir             {
492cdf0e10cSrcweir                 E3dScene* pScene = (E3dScene*)pObj;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir                 // iterate over this sub-scene
495cdf0e10cSrcweir                 pScene->removeAllNonSelectedObjects();
496cdf0e10cSrcweir 
497cdf0e10cSrcweir                 // check object count. Empty scenes can be deleted
498cdf0e10cSrcweir                 const sal_uInt32 nObjCount(pScene->GetSubList() ? pScene->GetSubList()->GetObjCount() : 0);
499cdf0e10cSrcweir 
500cdf0e10cSrcweir                 if(!nObjCount)
501cdf0e10cSrcweir 			    {
502cdf0e10cSrcweir                     // all objects removed, scene can be removed, too
503cdf0e10cSrcweir                     bRemoveObject = true;
504cdf0e10cSrcweir 			    }
505cdf0e10cSrcweir 			}
506cdf0e10cSrcweir             else if(pObj->ISA(E3dCompoundObject))
507cdf0e10cSrcweir 			{
508cdf0e10cSrcweir                 E3dCompoundObject* pCompound = (E3dCompoundObject*)pObj;
509cdf0e10cSrcweir 
510cdf0e10cSrcweir 			    if(!pCompound->GetSelected())
511cdf0e10cSrcweir 				{
512cdf0e10cSrcweir                     bRemoveObject = true;
513cdf0e10cSrcweir 				}
514cdf0e10cSrcweir 			}
515cdf0e10cSrcweir 
516cdf0e10cSrcweir             if(bRemoveObject)
517cdf0e10cSrcweir 			{
518cdf0e10cSrcweir 			    maSubList.NbcRemoveObject(pObj->GetOrdNum());
519cdf0e10cSrcweir 			    a--;
520cdf0e10cSrcweir                 SdrObject::Free(pObj);
521cdf0e10cSrcweir             }
522cdf0e10cSrcweir         }
523cdf0e10cSrcweir     }
524cdf0e10cSrcweir }
525cdf0e10cSrcweir 
526cdf0e10cSrcweir /*************************************************************************
527cdf0e10cSrcweir |*
528cdf0e10cSrcweir |* Zuweisungsoperator
529cdf0e10cSrcweir |*
530cdf0e10cSrcweir \************************************************************************/
531cdf0e10cSrcweir 
532cdf0e10cSrcweir void E3dScene::operator=(const SdrObject& rObj)
533cdf0e10cSrcweir {
534cdf0e10cSrcweir 	E3dObject::operator=(rObj);
535cdf0e10cSrcweir 
536cdf0e10cSrcweir 	const E3dScene& r3DObj = (const E3dScene&) rObj;
537cdf0e10cSrcweir 	aCamera			 = r3DObj.aCamera;
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 	// neu ab 377:
540cdf0e10cSrcweir 	aCameraSet = r3DObj.aCameraSet;
541cdf0e10cSrcweir 	((sdr::properties::E3dSceneProperties&)GetProperties()).SetSceneItemsFromCamera();
542cdf0e10cSrcweir 
543cdf0e10cSrcweir     // SetSnapRect(r3DObj.GetSnapRect());
544cdf0e10cSrcweir 	InvalidateBoundVolume();
545cdf0e10cSrcweir 	RebuildLists();
546cdf0e10cSrcweir 	SetRectsDirty();
547cdf0e10cSrcweir 
548cdf0e10cSrcweir 	// #110988#
549cdf0e10cSrcweir 	ImpCleanup3DDepthMapper();
550cdf0e10cSrcweir 
551cdf0e10cSrcweir     // #i101941#
552cdf0e10cSrcweir     // After a Scene as model object is cloned, the used
553cdf0e10cSrcweir     // ViewContactOfE3dScene is created and partially used
554cdf0e10cSrcweir     // to calculate Bound/SnapRects, but - since quite some
555cdf0e10cSrcweir     // values are buffered at the VC - not really well
556cdf0e10cSrcweir     // initialized. It would be possible to always watch for
557cdf0e10cSrcweir     // preconditions of buffered data, but this would be expensive
558cdf0e10cSrcweir     // and would create a lot of short living data structures.
559cdf0e10cSrcweir     // It is currently better to flush that data, e.g. by using
560cdf0e10cSrcweir     // ActionChanged at the VC which will for this class
561cdf0e10cSrcweir     // flush that cached data and initalize it's valid reconstruction
562cdf0e10cSrcweir     GetViewContact().ActionChanged();
563cdf0e10cSrcweir }
564cdf0e10cSrcweir 
565cdf0e10cSrcweir /*************************************************************************
566cdf0e10cSrcweir |*
567cdf0e10cSrcweir |* Licht- und Labelobjektlisten neu aufbauen (nach Laden, Zuweisung)
568cdf0e10cSrcweir |*
569cdf0e10cSrcweir \************************************************************************/
570cdf0e10cSrcweir 
571cdf0e10cSrcweir void E3dScene::RebuildLists()
572cdf0e10cSrcweir {
573cdf0e10cSrcweir 	// zuerst loeschen
574cdf0e10cSrcweir 	SdrLayerID nCurrLayerID = GetLayer();
575cdf0e10cSrcweir 
576cdf0e10cSrcweir 	SdrObjListIter a3DIterator(maSubList, IM_FLAT);
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 	// dann alle Objekte in der Szene pruefen
579cdf0e10cSrcweir 	while ( a3DIterator.IsMore() )
580cdf0e10cSrcweir 	{
581cdf0e10cSrcweir 		E3dObject* p3DObj = (E3dObject*) a3DIterator.Next();
582cdf0e10cSrcweir 		p3DObj->NbcSetLayer(nCurrLayerID);
583cdf0e10cSrcweir 		NewObjectInserted(p3DObj);
584cdf0e10cSrcweir 	}
585cdf0e10cSrcweir }
586cdf0e10cSrcweir 
587cdf0e10cSrcweir /*************************************************************************
588cdf0e10cSrcweir |*
589cdf0e10cSrcweir |* erstelle neues GeoData-Objekt
590cdf0e10cSrcweir |*
591cdf0e10cSrcweir \************************************************************************/
592cdf0e10cSrcweir 
593cdf0e10cSrcweir SdrObjGeoData *E3dScene::NewGeoData() const
594cdf0e10cSrcweir {
595cdf0e10cSrcweir 	return new E3DSceneGeoData;
596cdf0e10cSrcweir }
597cdf0e10cSrcweir 
598cdf0e10cSrcweir /*************************************************************************
599cdf0e10cSrcweir |*
600cdf0e10cSrcweir |* uebergebe aktuelle werte an das GeoData-Objekt
601cdf0e10cSrcweir |*
602cdf0e10cSrcweir \************************************************************************/
603cdf0e10cSrcweir 
604cdf0e10cSrcweir void E3dScene::SaveGeoData(SdrObjGeoData& rGeo) const
605cdf0e10cSrcweir {
606cdf0e10cSrcweir 	E3dObject::SaveGeoData (rGeo);
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 	((E3DSceneGeoData &) rGeo).aCamera = aCamera;
609cdf0e10cSrcweir }
610cdf0e10cSrcweir 
611cdf0e10cSrcweir /*************************************************************************
612cdf0e10cSrcweir |*
613cdf0e10cSrcweir |* uebernehme werte aus dem GeoData-Objekt
614cdf0e10cSrcweir |*
615cdf0e10cSrcweir \************************************************************************/
616cdf0e10cSrcweir 
617cdf0e10cSrcweir void E3dScene::RestGeoData(const SdrObjGeoData& rGeo)
618cdf0e10cSrcweir {
619cdf0e10cSrcweir 	// #i94832# removed E3DModifySceneSnapRectUpdater here.
620cdf0e10cSrcweir     // It should not be needed, is already part of E3dObject::RestGeoData
621cdf0e10cSrcweir 	E3dObject::RestGeoData (rGeo);
622cdf0e10cSrcweir 	SetCamera (((E3DSceneGeoData &) rGeo).aCamera);
623cdf0e10cSrcweir }
624cdf0e10cSrcweir 
625cdf0e10cSrcweir /*************************************************************************
626cdf0e10cSrcweir |*
627cdf0e10cSrcweir |* Am StyleSheet wurde etwas geaendert, also Scene aendern
628cdf0e10cSrcweir |*
629cdf0e10cSrcweir \************************************************************************/
630cdf0e10cSrcweir 
631cdf0e10cSrcweir void E3dScene::Notify(SfxBroadcaster &rBC, const SfxHint  &rHint)
632cdf0e10cSrcweir {
633cdf0e10cSrcweir 	SetRectsDirty();
634cdf0e10cSrcweir 	E3dObject::Notify(rBC, rHint);
635cdf0e10cSrcweir }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir /*************************************************************************
638cdf0e10cSrcweir |*
639cdf0e10cSrcweir \************************************************************************/
640cdf0e10cSrcweir 
641cdf0e10cSrcweir void E3dScene::RotateScene (const Point& rRef, long /*nWink*/, double sn, double cs)
642cdf0e10cSrcweir {
643cdf0e10cSrcweir 	Point UpperLeft, LowerRight, Center, NewCenter;
644cdf0e10cSrcweir 
645cdf0e10cSrcweir 	UpperLeft = aOutRect.TopLeft();
646cdf0e10cSrcweir 	LowerRight = aOutRect.BottomRight();
647cdf0e10cSrcweir 
648cdf0e10cSrcweir 	long dxOutRectHalf = labs(UpperLeft.X() - LowerRight.X());
649cdf0e10cSrcweir 	dxOutRectHalf /= 2;
650cdf0e10cSrcweir 	long dyOutRectHalf = labs(UpperLeft.Y() - LowerRight.Y());
651cdf0e10cSrcweir 	dyOutRectHalf /= 2;
652cdf0e10cSrcweir 
653cdf0e10cSrcweir 	Rectangle RectQuelle(aOutRect), RectZiel(aOutRect);
654cdf0e10cSrcweir 
655cdf0e10cSrcweir 	   // Nur der Mittelpunkt wird bewegt. Die Ecken werden von NbcMove bewegt.
656cdf0e10cSrcweir 	   // Fuer das Drehen wird von mir ein kartesisches Koordinatensystem verwendet in dem der Drehpunkt
657cdf0e10cSrcweir 	   // der Nullpunkt ist und die Y- Achse nach oben ansteigt, die X-Achse nach rechts.
658cdf0e10cSrcweir 	   // Dies muss bei den Y-Werten beachtet werden. (Auf dem Blatt zeigt die Y-Achse nach unten
659cdf0e10cSrcweir 	Center.X() = (UpperLeft.X() + dxOutRectHalf) - rRef.X();
660cdf0e10cSrcweir 	Center.Y() = -((UpperLeft.Y() + dyOutRectHalf) - rRef.Y());
661cdf0e10cSrcweir 				  // Ein paar Spezialfaelle zuerst abhandeln (n*90 Grad n ganzzahlig)
662cdf0e10cSrcweir     if (sn==1.0 && cs==0.0) { // 90deg
663cdf0e10cSrcweir 		NewCenter.X() = -Center.Y();
664cdf0e10cSrcweir 		NewCenter.Y() = -Center.X();
665cdf0e10cSrcweir     } else if (sn==0.0 && cs==-1.0) { // 180deg
666cdf0e10cSrcweir 		NewCenter.X() = -Center.X();
667cdf0e10cSrcweir 		NewCenter.Y() = -Center.Y();
668cdf0e10cSrcweir     } else if (sn==-1.0 && cs==0.0) { // 270deg
669cdf0e10cSrcweir 		NewCenter.X() =  Center.Y();
670cdf0e10cSrcweir 		NewCenter.Y() = -Center.X();
671cdf0e10cSrcweir 	}
672cdf0e10cSrcweir 	else          // Hier wird um einen beliebigen Winkel in mathematisch positiver Richtung gedreht!
673cdf0e10cSrcweir 	{             // xneu = x * cos(alpha) - y * sin(alpha)
674cdf0e10cSrcweir 				  // yneu = x * sin(alpha) + y * cos(alpha)
675cdf0e10cSrcweir 				  // Unten Rechts wird nicht gedreht: die Seiten von RectQuelle muessen parallel
676cdf0e10cSrcweir 				  // zu den Koordinatenachsen bleiben.
677cdf0e10cSrcweir 		NewCenter.X() = (long) (Center.X() * cs - Center.Y() * sn);
678cdf0e10cSrcweir 		NewCenter.Y() = (long) (Center.X() * sn + Center.Y() * cs);
679cdf0e10cSrcweir 	}
680cdf0e10cSrcweir 
681cdf0e10cSrcweir 	Size Differenz;
682cdf0e10cSrcweir 	Point DiffPoint = (NewCenter - Center);
683cdf0e10cSrcweir 	Differenz.Width() = DiffPoint.X();
684cdf0e10cSrcweir 	Differenz.Height() = -DiffPoint.Y();  // Man beachte dass die Y-Achse nach unten positiv gezaehlt wird.
685cdf0e10cSrcweir 	NbcMove (Differenz);  // fuehrt die eigentliche Koordinatentransformation durch.
686cdf0e10cSrcweir }
687cdf0e10cSrcweir 
688cdf0e10cSrcweir /*************************************************************************
689cdf0e10cSrcweir |*
690cdf0e10cSrcweir |* Get the name of the object (singular)
691cdf0e10cSrcweir |*
692cdf0e10cSrcweir \************************************************************************/
693cdf0e10cSrcweir 
694cdf0e10cSrcweir void E3dScene::TakeObjNameSingul(XubString& rName) const
695cdf0e10cSrcweir {
696cdf0e10cSrcweir 	rName=ImpGetResStr(STR_ObjNameSingulScene3d);
697cdf0e10cSrcweir 
698cdf0e10cSrcweir 	String aName( GetName() );
699cdf0e10cSrcweir 	if(aName.Len())
700cdf0e10cSrcweir 	{
701cdf0e10cSrcweir 		rName += sal_Unicode(' ');
702cdf0e10cSrcweir 		rName += sal_Unicode('\'');
703cdf0e10cSrcweir 		rName += aName;
704cdf0e10cSrcweir 		rName += sal_Unicode('\'');
705cdf0e10cSrcweir 	}
706cdf0e10cSrcweir }
707cdf0e10cSrcweir 
708cdf0e10cSrcweir /*************************************************************************
709cdf0e10cSrcweir |*
710cdf0e10cSrcweir |* Get the name of the object (plural)
711cdf0e10cSrcweir |*
712cdf0e10cSrcweir \************************************************************************/
713cdf0e10cSrcweir 
714cdf0e10cSrcweir void E3dScene::TakeObjNamePlural(XubString& rName) const
715cdf0e10cSrcweir {
716cdf0e10cSrcweir 	rName=ImpGetResStr(STR_ObjNamePluralScene3d);
717cdf0e10cSrcweir }
718cdf0e10cSrcweir 
719cdf0e10cSrcweir /*************************************************************************
720cdf0e10cSrcweir |*
721cdf0e10cSrcweir |* Die NbcRotate-Routine ueberlaedt die des SdrObject. Die Idee ist die Scene
722cdf0e10cSrcweir |* drehen zu koennen und relativ zur Lage der Scene dann auch die Objekte
723cdf0e10cSrcweir |* in der Scene
724cdf0e10cSrcweir |*
725cdf0e10cSrcweir \************************************************************************/
726cdf0e10cSrcweir 
727cdf0e10cSrcweir void E3dScene::NbcSetTransform(const basegfx::B3DHomMatrix& rMatrix)
728cdf0e10cSrcweir {
729cdf0e10cSrcweir     if(maTransformation != rMatrix)
730cdf0e10cSrcweir     {
731cdf0e10cSrcweir 		// call parent
732cdf0e10cSrcweir 		E3dObject::NbcSetTransform(rMatrix);
733cdf0e10cSrcweir 	}
734cdf0e10cSrcweir }
735cdf0e10cSrcweir 
736cdf0e10cSrcweir void E3dScene::SetTransform(const basegfx::B3DHomMatrix& rMatrix)
737cdf0e10cSrcweir {
738cdf0e10cSrcweir     if(rMatrix != maTransformation)
739cdf0e10cSrcweir     {
740cdf0e10cSrcweir 		// call parent
741cdf0e10cSrcweir 		E3dObject::SetTransform(rMatrix);
742cdf0e10cSrcweir 	}
743cdf0e10cSrcweir }
744cdf0e10cSrcweir 
745cdf0e10cSrcweir void E3dScene::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
746cdf0e10cSrcweir {
747cdf0e10cSrcweir 	// Also derzeit sind die Klebepunkte relativ zum aOutRect der Szene definiert. Vor dem Drehen
748cdf0e10cSrcweir 	// werden die Klebepunkte relativ zur Seite definiert. Sie nehmen an der Drehung der Szene noch nicht Teil
749cdf0e10cSrcweir 	// dafuer gibt es den
750cdf0e10cSrcweir 	SetGlueReallyAbsolute(sal_True);
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 	// So dass war die Szene, ab jetzt kommen die Objekte in der Szene
753cdf0e10cSrcweir     // 3D-Objekte gibt es nur ein einziges das kann zwar mehrere Flaechen haben aber die Flaechen
754cdf0e10cSrcweir 	// muessen ja nicht zusammenhaengend sein
755cdf0e10cSrcweir 	// es ermoeglicht den Zugriff auf Kindobjekte
756cdf0e10cSrcweir 	// Ich gehe also die gesamte Liste durch und rotiere um die Z-Achse die durch den
757cdf0e10cSrcweir 	// Mittelpunkt von aOutRect geht (Satz von Steiner), also RotateZ
758cdf0e10cSrcweir 
759cdf0e10cSrcweir 	RotateScene (rRef, nWink, sn, cs);  // Rotiert die Szene
760cdf0e10cSrcweir 	double fWinkelInRad = nWink/100 * F_PI180;
761cdf0e10cSrcweir 
762cdf0e10cSrcweir 	basegfx::B3DHomMatrix aRotation;
763cdf0e10cSrcweir 	aRotation.rotate(0.0, 0.0, fWinkelInRad);
764cdf0e10cSrcweir 	NbcSetTransform(aRotation * GetTransform());
765cdf0e10cSrcweir 
766cdf0e10cSrcweir 	SetRectsDirty();    // Veranlasst eine Neuberechnung aller BoundRects
767cdf0e10cSrcweir 	NbcRotateGluePoints(rRef,nWink,sn,cs);  // Rotiert die Klebepunkte (die haben noch Koordinaten relativ
768cdf0e10cSrcweir 											// zum Urpsung des Blattes
769cdf0e10cSrcweir 	SetGlueReallyAbsolute(sal_False);  // ab jetzt sind sie wieder relativ zum BoundRect (also dem aOutRect definiert)
770cdf0e10cSrcweir 	SetRectsDirty();
771cdf0e10cSrcweir }
772cdf0e10cSrcweir 
773cdf0e10cSrcweir /*************************************************************************
774cdf0e10cSrcweir |*
775cdf0e10cSrcweir |* SnapRect berechnen
776cdf0e10cSrcweir |*
777cdf0e10cSrcweir \************************************************************************/
778cdf0e10cSrcweir 
779cdf0e10cSrcweir void E3dScene::RecalcSnapRect()
780cdf0e10cSrcweir {
781cdf0e10cSrcweir 	E3dScene* pScene = GetScene();
782cdf0e10cSrcweir 
783cdf0e10cSrcweir 	if(pScene == this)
784cdf0e10cSrcweir 	{
785cdf0e10cSrcweir 		// Szene wird als 2D-Objekt benutzt, nimm SnapRect aus der
786cdf0e10cSrcweir 		// 2D Bildschrimdarstellung
787cdf0e10cSrcweir 		Camera3D& rCam = (Camera3D&)pScene->GetCamera();
788cdf0e10cSrcweir 		maSnapRect = rCam.GetDeviceWindow();
789cdf0e10cSrcweir 	}
790cdf0e10cSrcweir 	else
791cdf0e10cSrcweir 	{
792cdf0e10cSrcweir 		// Szene ist selbst Mitglied einer anderen Szene, hole das
793cdf0e10cSrcweir 		// SnapRect als zusammengesetztes Objekt
794cdf0e10cSrcweir 		E3dObject::RecalcSnapRect();
795cdf0e10cSrcweir 	}
796cdf0e10cSrcweir }
797cdf0e10cSrcweir 
798cdf0e10cSrcweir /*************************************************************************
799cdf0e10cSrcweir |*
800cdf0e10cSrcweir |* Aufbrechen
801cdf0e10cSrcweir |*
802cdf0e10cSrcweir \************************************************************************/
803cdf0e10cSrcweir 
804cdf0e10cSrcweir sal_Bool E3dScene::IsBreakObjPossible()
805cdf0e10cSrcweir {
806cdf0e10cSrcweir 	// Szene ist aufzubrechen, wenn alle Mitglieder aufzubrechen sind
807cdf0e10cSrcweir 	SdrObjListIter a3DIterator(maSubList, IM_DEEPWITHGROUPS);
808cdf0e10cSrcweir 
809cdf0e10cSrcweir 	while ( a3DIterator.IsMore() )
810cdf0e10cSrcweir 	{
811cdf0e10cSrcweir 		E3dObject* pObj = (E3dObject*) a3DIterator.Next();
812cdf0e10cSrcweir 		DBG_ASSERT(pObj->ISA(E3dObject), "AW: In Szenen sind nur 3D-Objekte erlaubt!");
813cdf0e10cSrcweir 		if(!pObj->IsBreakObjPossible())
814cdf0e10cSrcweir 			return sal_False;
815cdf0e10cSrcweir 	}
816cdf0e10cSrcweir 
817cdf0e10cSrcweir 	return sal_True;
818cdf0e10cSrcweir }
819cdf0e10cSrcweir 
820cdf0e10cSrcweir basegfx::B3DVector E3dScene::GetShadowPlaneDirection() const
821cdf0e10cSrcweir {
822cdf0e10cSrcweir 	double fWink = (double)GetShadowSlant() * F_PI180;
823cdf0e10cSrcweir 	basegfx::B3DVector aShadowPlaneDir(0.0, sin(fWink), cos(fWink));
824cdf0e10cSrcweir 	aShadowPlaneDir.normalize();
825cdf0e10cSrcweir 	return aShadowPlaneDir;
826cdf0e10cSrcweir }
827cdf0e10cSrcweir 
828cdf0e10cSrcweir void E3dScene::SetShadowPlaneDirection(const basegfx::B3DVector& rVec)
829cdf0e10cSrcweir {
830cdf0e10cSrcweir 	sal_uInt16 nSceneShadowSlant = (sal_uInt16)((atan2(rVec.getY(), rVec.getZ()) / F_PI180) + 0.5);
831cdf0e10cSrcweir 	GetProperties().SetObjectItemDirect(Svx3DShadowSlantItem(nSceneShadowSlant));
832cdf0e10cSrcweir }
833cdf0e10cSrcweir 
834cdf0e10cSrcweir basegfx::B2DPolyPolygon E3dScene::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
835cdf0e10cSrcweir {
836cdf0e10cSrcweir 	return TakeXorPoly();
837cdf0e10cSrcweir }
838cdf0e10cSrcweir 
839cdf0e10cSrcweir FASTBOOL E3dScene::BegCreate(SdrDragStat& rStat)
840cdf0e10cSrcweir {
841cdf0e10cSrcweir 	rStat.SetOrtho4Possible();
842cdf0e10cSrcweir 	Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
843cdf0e10cSrcweir 	aRect1.Justify();
844cdf0e10cSrcweir 	rStat.SetActionRect(aRect1);
845cdf0e10cSrcweir 	NbcSetSnapRect(aRect1);
846cdf0e10cSrcweir 	return sal_True;
847cdf0e10cSrcweir }
848cdf0e10cSrcweir 
849cdf0e10cSrcweir FASTBOOL E3dScene::MovCreate(SdrDragStat& rStat)
850cdf0e10cSrcweir {
851cdf0e10cSrcweir 	Rectangle aRect1;
852cdf0e10cSrcweir 	rStat.TakeCreateRect(aRect1);
853cdf0e10cSrcweir 	aRect1.Justify();
854cdf0e10cSrcweir 	rStat.SetActionRect(aRect1);
855cdf0e10cSrcweir 	NbcSetSnapRect(aRect1);
856cdf0e10cSrcweir 	SetBoundRectDirty();
857cdf0e10cSrcweir 	bSnapRectDirty=sal_True;
858cdf0e10cSrcweir 	return sal_True;
859cdf0e10cSrcweir }
860cdf0e10cSrcweir 
861cdf0e10cSrcweir FASTBOOL E3dScene::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
862cdf0e10cSrcweir {
863cdf0e10cSrcweir 	Rectangle aRect1;
864cdf0e10cSrcweir 	rStat.TakeCreateRect(aRect1);
865cdf0e10cSrcweir 	aRect1.Justify();
866cdf0e10cSrcweir 	NbcSetSnapRect(aRect1);
867cdf0e10cSrcweir 	SetRectsDirty();
868cdf0e10cSrcweir 	return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
869cdf0e10cSrcweir }
870cdf0e10cSrcweir 
871cdf0e10cSrcweir FASTBOOL E3dScene::BckCreate(SdrDragStat& /*rStat*/)
872cdf0e10cSrcweir {
873cdf0e10cSrcweir 	return sal_False;
874cdf0e10cSrcweir }
875cdf0e10cSrcweir 
876cdf0e10cSrcweir void E3dScene::BrkCreate(SdrDragStat& /*rStat*/)
877cdf0e10cSrcweir {
878cdf0e10cSrcweir }
879cdf0e10cSrcweir 
880cdf0e10cSrcweir // eof
881