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