1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svx.hxx"
30*cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
31*cdf0e10cSrcweir #include <svx/polysc3d.hxx>
32*cdf0e10cSrcweir #include <svx/sdr/contact/displayinfo.hxx>
33*cdf0e10cSrcweir #include <svx/sdr/contact/viewobjectcontact.hxx>
34*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
35*cdf0e10cSrcweir #include <basegfx/color/bcolor.hxx>
36*cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
37*cdf0e10cSrcweir #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
38*cdf0e10cSrcweir #include <svx/sdr/contact/viewobjectcontactofe3dscene.hxx>
39*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
40*cdf0e10cSrcweir #include <basegfx/range/b3drange.hxx>
41*cdf0e10cSrcweir #include <drawinglayer/primitive3d/baseprimitive3d.hxx>
42*cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofe3d.hxx>
43*cdf0e10cSrcweir #include <drawinglayer/primitive2d/sceneprimitive2d.hxx>
44*cdf0e10cSrcweir #include <drawinglayer/primitive3d/transformprimitive3d.hxx>
45*cdf0e10cSrcweir #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir using namespace com::sun::star;
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir namespace
54*cdf0e10cSrcweir {
55*cdf0e10cSrcweir 	// pActiveVC is only true if ghosted is still activated and maybe needs to be switched off in this path
56*cdf0e10cSrcweir 	void createSubPrimitive3DVector(
57*cdf0e10cSrcweir 		const sdr::contact::ViewContact& rCandidate,
58*cdf0e10cSrcweir 		drawinglayer::primitive3d::Primitive3DSequence& o_rAllTarget,
59*cdf0e10cSrcweir 		drawinglayer::primitive3d::Primitive3DSequence* o_pVisibleTarget,
60*cdf0e10cSrcweir 		const SetOfByte* pVisibleLayerSet,
61*cdf0e10cSrcweir 		const bool bTestSelectedVisibility)
62*cdf0e10cSrcweir 	{
63*cdf0e10cSrcweir 		const sdr::contact::ViewContactOfE3dScene* pViewContactOfE3dScene = dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(&rCandidate);
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir 		if(pViewContactOfE3dScene)
66*cdf0e10cSrcweir 		{
67*cdf0e10cSrcweir 			const sal_uInt32 nChildrenCount(rCandidate.GetObjectCount());
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir 			if(nChildrenCount)
70*cdf0e10cSrcweir 			{
71*cdf0e10cSrcweir 				// provide new collection sequences
72*cdf0e10cSrcweir 				drawinglayer::primitive3d::Primitive3DSequence aNewAllTarget;
73*cdf0e10cSrcweir 				drawinglayer::primitive3d::Primitive3DSequence aNewVisibleTarget;
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir 				// add children recursively
76*cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < nChildrenCount; a++)
77*cdf0e10cSrcweir 				{
78*cdf0e10cSrcweir 					createSubPrimitive3DVector(
79*cdf0e10cSrcweir 						rCandidate.GetViewContact(a),
80*cdf0e10cSrcweir 						aNewAllTarget,
81*cdf0e10cSrcweir 						o_pVisibleTarget ? &aNewVisibleTarget : 0,
82*cdf0e10cSrcweir 						pVisibleLayerSet,
83*cdf0e10cSrcweir 						bTestSelectedVisibility);
84*cdf0e10cSrcweir 				}
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 				// create transform primitive for the created content combining content and transformtion
87*cdf0e10cSrcweir 				const drawinglayer::primitive3d::Primitive3DReference xReference(new drawinglayer::primitive3d::TransformPrimitive3D(
88*cdf0e10cSrcweir 					pViewContactOfE3dScene->GetE3dScene().GetTransform(),
89*cdf0e10cSrcweir 					aNewAllTarget));
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir 				// add created content to all target
92*cdf0e10cSrcweir 				drawinglayer::primitive3d::appendPrimitive3DReferenceToPrimitive3DSequence(o_rAllTarget, xReference);
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 				// add created content to visibiel target if exists
95*cdf0e10cSrcweir 				if(o_pVisibleTarget)
96*cdf0e10cSrcweir 				{
97*cdf0e10cSrcweir 					drawinglayer::primitive3d::appendPrimitive3DReferenceToPrimitive3DSequence(*o_pVisibleTarget, xReference);
98*cdf0e10cSrcweir 				}
99*cdf0e10cSrcweir 			}
100*cdf0e10cSrcweir 		}
101*cdf0e10cSrcweir 		else
102*cdf0e10cSrcweir 		{
103*cdf0e10cSrcweir 			// access view independent representation of rCandidate
104*cdf0e10cSrcweir 			const sdr::contact::ViewContactOfE3d* pViewContactOfE3d = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&rCandidate);
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir 			if(pViewContactOfE3d)
107*cdf0e10cSrcweir 			{
108*cdf0e10cSrcweir 				drawinglayer::primitive3d::Primitive3DSequence xPrimitive3DSeq(pViewContactOfE3d->getViewIndependentPrimitive3DSequence());
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir 				if(xPrimitive3DSeq.hasElements())
111*cdf0e10cSrcweir 				{
112*cdf0e10cSrcweir 					// add to all target vector
113*cdf0e10cSrcweir 					drawinglayer::primitive3d::appendPrimitive3DSequenceToPrimitive3DSequence(o_rAllTarget, xPrimitive3DSeq);
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir 					if(o_pVisibleTarget)
116*cdf0e10cSrcweir 					{
117*cdf0e10cSrcweir 						// test visibility. Primitive is visible when both tests are true (AND)
118*cdf0e10cSrcweir 						bool bVisible(true);
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir 						if(pVisibleLayerSet)
121*cdf0e10cSrcweir 						{
122*cdf0e10cSrcweir 							// test layer visibility
123*cdf0e10cSrcweir 							const E3dObject& rE3dObject = pViewContactOfE3d->GetE3dObject();
124*cdf0e10cSrcweir 							const SdrLayerID aLayerID(rE3dObject.GetLayer());
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir 							bVisible = pVisibleLayerSet->IsSet(aLayerID);
127*cdf0e10cSrcweir 						}
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir 						if(bVisible && bTestSelectedVisibility)
130*cdf0e10cSrcweir 						{
131*cdf0e10cSrcweir 							// test selected visibility (see 3D View's DrawMarkedObj implementation)
132*cdf0e10cSrcweir 							const E3dObject& rE3dObject = pViewContactOfE3d->GetE3dObject();
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir 							bVisible = rE3dObject.GetSelected();
135*cdf0e10cSrcweir 						}
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir 						if(bVisible && o_pVisibleTarget)
138*cdf0e10cSrcweir 						{
139*cdf0e10cSrcweir 							// add to visible target vector
140*cdf0e10cSrcweir 							drawinglayer::primitive3d::appendPrimitive3DSequenceToPrimitive3DSequence(*o_pVisibleTarget, xPrimitive3DSeq);
141*cdf0e10cSrcweir 						}
142*cdf0e10cSrcweir 					}
143*cdf0e10cSrcweir 				}
144*cdf0e10cSrcweir 			}
145*cdf0e10cSrcweir 		}
146*cdf0e10cSrcweir 	}
147*cdf0e10cSrcweir } // end of anonymous namespace
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir namespace sdr
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir 	namespace contact
154*cdf0e10cSrcweir 	{
155*cdf0e10cSrcweir 		// Create a Object-Specific ViewObjectContact, set ViewContact and
156*cdf0e10cSrcweir 		// ObjectContact. Always needs to return something.
157*cdf0e10cSrcweir 		ViewObjectContact& ViewContactOfE3dScene::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
158*cdf0e10cSrcweir 		{
159*cdf0e10cSrcweir 			ViewObjectContact* pRetval = new ViewObjectContactOfE3dScene(rObjectContact, *this);
160*cdf0e10cSrcweir 			DBG_ASSERT(pRetval, "ViewContactOfE3dScene::CreateObjectSpecificViewObjectContact() failed (!)");
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 			return *pRetval;
163*cdf0e10cSrcweir 		}
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir 		ViewContactOfE3dScene::ViewContactOfE3dScene(E3dScene& rScene)
166*cdf0e10cSrcweir 		:	ViewContactOfSdrObj(rScene),
167*cdf0e10cSrcweir 			maViewInformation3D(),
168*cdf0e10cSrcweir 			maObjectTransformation(),
169*cdf0e10cSrcweir 			maSdrSceneAttribute(),
170*cdf0e10cSrcweir 			maSdrLightingAttribute()
171*cdf0e10cSrcweir 		{
172*cdf0e10cSrcweir 		}
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 		void ViewContactOfE3dScene::createViewInformation3D(const basegfx::B3DRange& rContentRange)
175*cdf0e10cSrcweir 		{
176*cdf0e10cSrcweir 			basegfx::B3DHomMatrix aTransformation;
177*cdf0e10cSrcweir 			basegfx::B3DHomMatrix aOrientation;
178*cdf0e10cSrcweir 			basegfx::B3DHomMatrix aProjection;
179*cdf0e10cSrcweir 			basegfx::B3DHomMatrix aDeviceToView;
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir 			// create transformation (scene as group's transformation)
182*cdf0e10cSrcweir 			// For historical reasons, the outmost scene's transformation is handles as part of the
183*cdf0e10cSrcweir 			// view transformation. This means that the BoundRect of the contained 3D Objects is
184*cdf0e10cSrcweir 			// without that transformation and makes it necessary to NOT add the first scene to the
185*cdf0e10cSrcweir 			// Primitive3DSequence of contained objects.
186*cdf0e10cSrcweir 			{
187*cdf0e10cSrcweir 				aTransformation = GetE3dScene().GetTransform();
188*cdf0e10cSrcweir 			}
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 			// create orientation (world to camera coordinate system)
191*cdf0e10cSrcweir 			{
192*cdf0e10cSrcweir 				// calculate orientation from VRP, VPN and VUV
193*cdf0e10cSrcweir 				const B3dCamera& rSceneCamera = GetE3dScene().GetCameraSet();
194*cdf0e10cSrcweir 				const basegfx::B3DPoint aVRP(rSceneCamera.GetVRP());
195*cdf0e10cSrcweir 				const basegfx::B3DVector aVPN(rSceneCamera.GetVRP());
196*cdf0e10cSrcweir 				const basegfx::B3DVector aVUV(rSceneCamera.GetVUV());
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir                 aOrientation.orientation(aVRP, aVPN, aVUV);
199*cdf0e10cSrcweir 			}
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir 			// create projection (camera coordinate system to relative 2d where X,Y and Z are [0.0 .. 1.0])
202*cdf0e10cSrcweir 			{
203*cdf0e10cSrcweir 				const basegfx::B3DHomMatrix aWorldToCamera(aOrientation * aTransformation);
204*cdf0e10cSrcweir 				basegfx::B3DRange aCameraRange(rContentRange);
205*cdf0e10cSrcweir 				aCameraRange.transform(aWorldToCamera);
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 				// remember Z-Values, but change orientation
208*cdf0e10cSrcweir 				const double fMinZ(-aCameraRange.getMaxZ());
209*cdf0e10cSrcweir 				const double fMaxZ(-aCameraRange.getMinZ());
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir 				// construct temorary matrix from world to device. Use unit values here to measure expansion
212*cdf0e10cSrcweir 				basegfx::B3DHomMatrix aWorldToDevice(aWorldToCamera);
213*cdf0e10cSrcweir 				const drawinglayer::attribute::SdrSceneAttribute& rSdrSceneAttribute = getSdrSceneAttribute();
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir 				if(::com::sun::star::drawing::ProjectionMode_PERSPECTIVE == rSdrSceneAttribute.getProjectionMode())
216*cdf0e10cSrcweir 				{
217*cdf0e10cSrcweir 					aWorldToDevice.frustum(-1.0, 1.0, -1.0, 1.0, fMinZ, fMaxZ);
218*cdf0e10cSrcweir 				}
219*cdf0e10cSrcweir 				else
220*cdf0e10cSrcweir 				{
221*cdf0e10cSrcweir 					aWorldToDevice.ortho(-1.0, 1.0, -1.0, 1.0, fMinZ, fMaxZ);
222*cdf0e10cSrcweir 				}
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir 				// create B3DRange in device. This will create the real used ranges
225*cdf0e10cSrcweir 				// in camera space. Do not use the Z-Values, though.
226*cdf0e10cSrcweir 				basegfx::B3DRange aDeviceRange(rContentRange);
227*cdf0e10cSrcweir 				aDeviceRange.transform(aWorldToDevice);
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir 				// set projection
230*cdf0e10cSrcweir 				if(::com::sun::star::drawing::ProjectionMode_PERSPECTIVE == rSdrSceneAttribute.getProjectionMode())
231*cdf0e10cSrcweir 				{
232*cdf0e10cSrcweir 					aProjection.frustum(
233*cdf0e10cSrcweir 						aDeviceRange.getMinX(), aDeviceRange.getMaxX(),
234*cdf0e10cSrcweir 						aDeviceRange.getMinY(), aDeviceRange.getMaxY(),
235*cdf0e10cSrcweir 						fMinZ, fMaxZ);
236*cdf0e10cSrcweir 				}
237*cdf0e10cSrcweir 				else
238*cdf0e10cSrcweir 				{
239*cdf0e10cSrcweir 					aProjection.ortho(
240*cdf0e10cSrcweir 						aDeviceRange.getMinX(), aDeviceRange.getMaxX(),
241*cdf0e10cSrcweir 						aDeviceRange.getMinY(), aDeviceRange.getMaxY(),
242*cdf0e10cSrcweir 						fMinZ, fMaxZ);
243*cdf0e10cSrcweir 				}
244*cdf0e10cSrcweir 			}
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir 			// create device to view transform
247*cdf0e10cSrcweir 			{
248*cdf0e10cSrcweir 				// create standard deviceToView projection for geometry
249*cdf0e10cSrcweir 				// input is [-1.0 .. 1.0] in X,Y and Z. bring to [0.0 .. 1.0]. Also
250*cdf0e10cSrcweir 				// necessary to flip Y due to screen orientation
251*cdf0e10cSrcweir 				// Z is not needed, but will also be brought to [0.0 .. 1.0]
252*cdf0e10cSrcweir 				aDeviceToView.scale(0.5, -0.5, 0.5);
253*cdf0e10cSrcweir 				aDeviceToView.translate(0.5, 0.5, 0.5);
254*cdf0e10cSrcweir 			}
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir 			const uno::Sequence< beans::PropertyValue > aEmptyProperties;
257*cdf0e10cSrcweir 			maViewInformation3D = drawinglayer::geometry::ViewInformation3D(
258*cdf0e10cSrcweir 				aTransformation, aOrientation, aProjection,
259*cdf0e10cSrcweir 				aDeviceToView, 0.0, aEmptyProperties);
260*cdf0e10cSrcweir 		}
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 		void ViewContactOfE3dScene::createObjectTransformation()
263*cdf0e10cSrcweir 		{
264*cdf0e10cSrcweir 			// create 2d Object Transformation from relative point in 2d scene to world
265*cdf0e10cSrcweir 			const Rectangle& rRectangle = GetE3dScene().GetSnapRect();
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 			maObjectTransformation.set(0, 0, rRectangle.getWidth());
268*cdf0e10cSrcweir 			maObjectTransformation.set(1, 1, rRectangle.getHeight());
269*cdf0e10cSrcweir 			maObjectTransformation.set(0, 2, rRectangle.Left());
270*cdf0e10cSrcweir 			maObjectTransformation.set(1, 2, rRectangle.Top());
271*cdf0e10cSrcweir 		}
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 		void ViewContactOfE3dScene::createSdrSceneAttribute()
274*cdf0e10cSrcweir 		{
275*cdf0e10cSrcweir 			const SfxItemSet& rItemSet = GetE3dScene().GetMergedItemSet();
276*cdf0e10cSrcweir 			maSdrSceneAttribute = drawinglayer::primitive2d::createNewSdrSceneAttribute(rItemSet);
277*cdf0e10cSrcweir 		}
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir 		void ViewContactOfE3dScene::createSdrLightingAttribute()
280*cdf0e10cSrcweir 		{
281*cdf0e10cSrcweir 			const SfxItemSet& rItemSet = GetE3dScene().GetMergedItemSet();
282*cdf0e10cSrcweir 			maSdrLightingAttribute = drawinglayer::primitive2d::createNewSdrLightingAttribute(rItemSet);
283*cdf0e10cSrcweir 		}
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 		drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3dScene::createScenePrimitive2DSequence(
286*cdf0e10cSrcweir             const SetOfByte* pLayerVisibility) const
287*cdf0e10cSrcweir 		{
288*cdf0e10cSrcweir 			drawinglayer::primitive2d::Primitive2DSequence xRetval;
289*cdf0e10cSrcweir 			const sal_uInt32 nChildrenCount(GetObjectCount());
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir 			if(nChildrenCount)
292*cdf0e10cSrcweir 			{
293*cdf0e10cSrcweir 				// create 3d scene primitive with visible content tested against rLayerVisibility
294*cdf0e10cSrcweir 				drawinglayer::primitive3d::Primitive3DSequence aAllSequence;
295*cdf0e10cSrcweir 				drawinglayer::primitive3d::Primitive3DSequence aVisibleSequence;
296*cdf0e10cSrcweir 				const bool bTestLayerVisibility(0 != pLayerVisibility);
297*cdf0e10cSrcweir 				const bool bTestSelectedVisibility(GetE3dScene().GetDrawOnlySelected());
298*cdf0e10cSrcweir 				const bool bTestVisibility(bTestLayerVisibility || bTestSelectedVisibility);
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir 				// add children recursively. Do NOT start with (*this), this would create
301*cdf0e10cSrcweir 				// a 3D transformPrimitive for the start scene. While this is theoretically not
302*cdf0e10cSrcweir 				// a bad thing, for historical reasons the transformation of the outmost scene
303*cdf0e10cSrcweir 				// is seen as part of the ViewTransformation (see text in createViewInformation3D)
304*cdf0e10cSrcweir 				for(sal_uInt32 a(0L); a < nChildrenCount; a++)
305*cdf0e10cSrcweir 				{
306*cdf0e10cSrcweir 					createSubPrimitive3DVector(
307*cdf0e10cSrcweir 						GetViewContact(a),
308*cdf0e10cSrcweir 						aAllSequence,
309*cdf0e10cSrcweir 						bTestLayerVisibility ? &aVisibleSequence : 0,
310*cdf0e10cSrcweir 						bTestLayerVisibility ? pLayerVisibility : 0,
311*cdf0e10cSrcweir 						bTestSelectedVisibility);
312*cdf0e10cSrcweir 				}
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir 				const sal_uInt32 nAllSize(aAllSequence.hasElements() ? aAllSequence.getLength() : 0);
315*cdf0e10cSrcweir 				const sal_uInt32 nVisibleSize(aVisibleSequence.hasElements() ? aVisibleSequence.getLength() : 0);
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir 				if((bTestVisibility && nVisibleSize) || nAllSize)
318*cdf0e10cSrcweir 				{
319*cdf0e10cSrcweir 					// for getting the 3D range using getB3DRangeFromPrimitive3DSequence a ViewInformation3D
320*cdf0e10cSrcweir 					// needs to be given for evtl. decompositions. At the same time createViewInformation3D
321*cdf0e10cSrcweir 					// currently is based on creating the target-ViewInformation3D using a given range. To
322*cdf0e10cSrcweir 					// get the true range, use a neutral ViewInformation3D here. This leaves all matrices
323*cdf0e10cSrcweir 					// on identity and the time on 0.0.
324*cdf0e10cSrcweir 					const uno::Sequence< beans::PropertyValue > aEmptyProperties;
325*cdf0e10cSrcweir 					const drawinglayer::geometry::ViewInformation3D aNeutralViewInformation3D(aEmptyProperties);
326*cdf0e10cSrcweir 					const basegfx::B3DRange aContentRange(
327*cdf0e10cSrcweir 						drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(aAllSequence, aNeutralViewInformation3D));
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 					// create 2d primitive 3dscene with generated sub-list from collector
330*cdf0e10cSrcweir 					const drawinglayer::primitive2d::Primitive2DReference xReference(
331*cdf0e10cSrcweir 						new drawinglayer::primitive2d::ScenePrimitive2D(
332*cdf0e10cSrcweir 							bTestVisibility ? aVisibleSequence : aAllSequence,
333*cdf0e10cSrcweir 							getSdrSceneAttribute(),
334*cdf0e10cSrcweir 							getSdrLightingAttribute(),
335*cdf0e10cSrcweir 							getObjectTransformation(),
336*cdf0e10cSrcweir 							getViewInformation3D(aContentRange)));
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir 					xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
339*cdf0e10cSrcweir 				}
340*cdf0e10cSrcweir 			}
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir 			// always append an invisible outline for the cases where no visible content exists
343*cdf0e10cSrcweir 			drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
344*cdf0e10cSrcweir 				drawinglayer::primitive2d::createHiddenGeometryPrimitives2D(
345*cdf0e10cSrcweir 					false, getObjectTransformation()));
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir 			return xRetval;
348*cdf0e10cSrcweir 		}
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir 		drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3dScene::createViewIndependentPrimitive2DSequence() const
351*cdf0e10cSrcweir 		{
352*cdf0e10cSrcweir 			drawinglayer::primitive2d::Primitive2DSequence xRetval;
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir 			if(GetObjectCount())
355*cdf0e10cSrcweir 			{
356*cdf0e10cSrcweir 				// create a default ScenePrimitive2D (without visibility test of members)
357*cdf0e10cSrcweir 				xRetval = createScenePrimitive2DSequence(0);
358*cdf0e10cSrcweir 			}
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir             return xRetval;
361*cdf0e10cSrcweir 		}
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir 		void ViewContactOfE3dScene::ActionChanged()
364*cdf0e10cSrcweir 		{
365*cdf0e10cSrcweir 			// call parent
366*cdf0e10cSrcweir 			ViewContactOfSdrObj::ActionChanged();
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir 			// mark locally cached values as invalid
369*cdf0e10cSrcweir     		maViewInformation3D = drawinglayer::geometry::ViewInformation3D();
370*cdf0e10cSrcweir 			maObjectTransformation.identity();
371*cdf0e10cSrcweir 			maSdrSceneAttribute = drawinglayer::attribute::SdrSceneAttribute();
372*cdf0e10cSrcweir 			maSdrLightingAttribute = drawinglayer::attribute::SdrLightingAttribute();
373*cdf0e10cSrcweir 		}
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir 		const drawinglayer::geometry::ViewInformation3D& ViewContactOfE3dScene::getViewInformation3D() const
376*cdf0e10cSrcweir 		{
377*cdf0e10cSrcweir 			if(maViewInformation3D.isDefault())
378*cdf0e10cSrcweir 			{
379*cdf0e10cSrcweir 				// this version will create the content range on demand locally and thus is less
380*cdf0e10cSrcweir 				// performant than the other one. Since the information is buffered the planned
381*cdf0e10cSrcweir 				// behaviour is that the version with the given range is used initially.
382*cdf0e10cSrcweir                 basegfx::B3DRange aContentRange(getAllContentRange3D());
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir 				if(aContentRange.isEmpty())
385*cdf0e10cSrcweir 				{
386*cdf0e10cSrcweir 					// empty scene, no 3d action should be necessary. Prepare some
387*cdf0e10cSrcweir                     // fallback size
388*cdf0e10cSrcweir 					OSL_ENSURE(false, "No need to get ViewInformation3D from an empty scene (!)");
389*cdf0e10cSrcweir 					aContentRange.expand(basegfx::B3DPoint(-100.0, -100.0, -100.0));
390*cdf0e10cSrcweir 					aContentRange.expand(basegfx::B3DPoint( 100.0,  100.0,  100.0));
391*cdf0e10cSrcweir 				}
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir 				const_cast < ViewContactOfE3dScene* >(this)->createViewInformation3D(aContentRange);
394*cdf0e10cSrcweir 			}
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir 			return maViewInformation3D;
397*cdf0e10cSrcweir 		}
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir 		const drawinglayer::geometry::ViewInformation3D& ViewContactOfE3dScene::getViewInformation3D(const basegfx::B3DRange& rContentRange) const
400*cdf0e10cSrcweir 		{
401*cdf0e10cSrcweir             if(maViewInformation3D.isDefault())
402*cdf0e10cSrcweir 			{
403*cdf0e10cSrcweir 				const_cast < ViewContactOfE3dScene* >(this)->createViewInformation3D(rContentRange);
404*cdf0e10cSrcweir 			}
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 			return maViewInformation3D;
407*cdf0e10cSrcweir 		}
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir 		const basegfx::B2DHomMatrix& ViewContactOfE3dScene::getObjectTransformation() const
410*cdf0e10cSrcweir 		{
411*cdf0e10cSrcweir             if(maObjectTransformation.isIdentity())
412*cdf0e10cSrcweir 			{
413*cdf0e10cSrcweir 				const_cast < ViewContactOfE3dScene* >(this)->createObjectTransformation();
414*cdf0e10cSrcweir 			}
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir 			return maObjectTransformation;
417*cdf0e10cSrcweir 		}
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir 		const drawinglayer::attribute::SdrSceneAttribute& ViewContactOfE3dScene::getSdrSceneAttribute() const
420*cdf0e10cSrcweir 		{
421*cdf0e10cSrcweir             if(maSdrSceneAttribute.isDefault())
422*cdf0e10cSrcweir 			{
423*cdf0e10cSrcweir 				const_cast < ViewContactOfE3dScene* >(this)->createSdrSceneAttribute();
424*cdf0e10cSrcweir 			}
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir 			return maSdrSceneAttribute;
427*cdf0e10cSrcweir 		}
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir 		const drawinglayer::attribute::SdrLightingAttribute& ViewContactOfE3dScene::getSdrLightingAttribute() const
430*cdf0e10cSrcweir 		{
431*cdf0e10cSrcweir             if(maSdrLightingAttribute.isDefault())
432*cdf0e10cSrcweir 			{
433*cdf0e10cSrcweir 				const_cast < ViewContactOfE3dScene* >(this)->createSdrLightingAttribute();
434*cdf0e10cSrcweir 			}
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir 			return maSdrLightingAttribute;
437*cdf0e10cSrcweir 		}
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir         drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dScene::getAllPrimitive3DSequence() const
440*cdf0e10cSrcweir         {
441*cdf0e10cSrcweir             drawinglayer::primitive3d::Primitive3DSequence aAllPrimitive3DSequence;
442*cdf0e10cSrcweir 			const sal_uInt32 nChildrenCount(GetObjectCount());
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir 		    // add children recursively. Do NOT start with (*this), this would create
445*cdf0e10cSrcweir 		    // a 3D transformPrimitive for the start scene. While this is theoretically not
446*cdf0e10cSrcweir 		    // a bad thing, for historical reasons the transformation of the outmost scene
447*cdf0e10cSrcweir 		    // is seen as part of the ViewTransformation (see text in createViewInformation3D)
448*cdf0e10cSrcweir             for(sal_uInt32 a(0L); a < nChildrenCount; a++)
449*cdf0e10cSrcweir 		    {
450*cdf0e10cSrcweir 			    createSubPrimitive3DVector(GetViewContact(a), aAllPrimitive3DSequence, 0, 0, false);
451*cdf0e10cSrcweir 		    }
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir             return aAllPrimitive3DSequence;
454*cdf0e10cSrcweir         }
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir         basegfx::B3DRange ViewContactOfE3dScene::getAllContentRange3D() const
457*cdf0e10cSrcweir         {
458*cdf0e10cSrcweir             const drawinglayer::primitive3d::Primitive3DSequence xAllSequence(getAllPrimitive3DSequence());
459*cdf0e10cSrcweir             basegfx::B3DRange aAllContentRange3D;
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir             if(xAllSequence.hasElements())
462*cdf0e10cSrcweir 			{
463*cdf0e10cSrcweir 				// for getting the 3D range using getB3DRangeFromPrimitive3DSequence a ViewInformation3D
464*cdf0e10cSrcweir 				// needs to be given for evtl. decompositions. Use a neutral ViewInformation3D here. This
465*cdf0e10cSrcweir                 // leaves all matrices on identity and the time on 0.0.
466*cdf0e10cSrcweir 				const uno::Sequence< beans::PropertyValue > aEmptyProperties;
467*cdf0e10cSrcweir 				const drawinglayer::geometry::ViewInformation3D aNeutralViewInformation3D(aEmptyProperties);
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir 				aAllContentRange3D = drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(xAllSequence, aNeutralViewInformation3D);
470*cdf0e10cSrcweir             }
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir             return aAllContentRange3D;
473*cdf0e10cSrcweir         }
474*cdf0e10cSrcweir 	} // end of namespace contact
475*cdf0e10cSrcweir } // end of namespace sdr
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
478*cdf0e10cSrcweir // eof
479