1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <helperminimaldepth3d.hxx>
31 #include <drawinglayer/processor3d/baseprocessor3d.hxx>
32 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
33 #include <drawinglayer/primitive3d/transformprimitive3d.hxx>
34 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
35 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
36 #include <svx/sdr/contact/viewcontactofe3d.hxx>
37 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
38 #include <svx/obj3d.hxx>
39 #include <svx/scene3d.hxx>
41 //////////////////////////////////////////////////////////////////////////////
43 namespace drawinglayer
47 class MinimalDephInViewExtractor
: public BaseProcessor3D
50 // the value which will be fetched as result
51 double mfMinimalDepth
;
53 // as tooling, the process() implementation takes over API handling and calls this
54 // virtual render method when the primitive implementation is BasePrimitive3D-based.
55 virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D
& rCandidate
);
58 MinimalDephInViewExtractor(const geometry::ViewInformation3D
& rViewInformation
)
59 : BaseProcessor3D(rViewInformation
),
60 mfMinimalDepth(DBL_MAX
)
64 double getMinimalDepth() const { return mfMinimalDepth
; }
67 void MinimalDephInViewExtractor::processBasePrimitive3D(const primitive3d::BasePrimitive3D
& rCandidate
)
69 // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
70 switch(rCandidate
.getPrimitive3DID())
72 case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D
:
74 // transform group. Remember current transformations
75 const primitive3d::TransformPrimitive3D
& rPrimitive
= static_cast< const primitive3d::TransformPrimitive3D
& >(rCandidate
);
76 const geometry::ViewInformation3D
aLastViewInformation3D(getViewInformation3D());
78 // create new transformation; add new object transform from right side
79 const geometry::ViewInformation3D
aNewViewInformation3D(
80 aLastViewInformation3D
.getObjectTransformation() * rPrimitive
.getTransformation(),
81 aLastViewInformation3D
.getOrientation(),
82 aLastViewInformation3D
.getProjection(),
83 aLastViewInformation3D
.getDeviceToView(),
84 aLastViewInformation3D
.getViewTime(),
85 aLastViewInformation3D
.getExtendedInformationSequence());
86 updateViewInformation(aNewViewInformation3D
);
89 process(rPrimitive
.getChildren());
91 // restore transformations
92 updateViewInformation(aLastViewInformation3D
);
95 case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D
:
97 // PolygonHairlinePrimitive3D
98 const primitive3d::PolygonHairlinePrimitive3D
& rPrimitive
= static_cast< const primitive3d::PolygonHairlinePrimitive3D
& >(rCandidate
);
99 const basegfx::B3DPolygon
& rPolygon
= rPrimitive
.getB3DPolygon();
100 const sal_uInt32
nCount(rPolygon
.count());
102 for(sal_uInt32
a(0); a
< nCount
; a
++)
104 const basegfx::B3DPoint
aPointInView(getViewInformation3D().getObjectToView() * rPolygon
.getB3DPoint(a
));
106 if(aPointInView
.getZ() < mfMinimalDepth
)
108 mfMinimalDepth
= aPointInView
.getZ();
114 case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D
:
116 // PolyPolygonMaterialPrimitive3D
117 const primitive3d::PolyPolygonMaterialPrimitive3D
& rPrimitive
= static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D
& >(rCandidate
);
118 const basegfx::B3DPolyPolygon
& rPolyPolygon
= rPrimitive
.getB3DPolyPolygon();
119 const sal_uInt32
nPolyCount(rPolyPolygon
.count());
121 for(sal_uInt32
a(0); a
< nPolyCount
; a
++)
123 const basegfx::B3DPolygon
aPolygon(rPolyPolygon
.getB3DPolygon(a
));
124 const sal_uInt32
nCount(aPolygon
.count());
126 for(sal_uInt32
b(0); b
< nCount
; b
++)
128 const basegfx::B3DPoint
aPointInView(getViewInformation3D().getObjectToView() * aPolygon
.getB3DPoint(b
));
130 if(aPointInView
.getZ() < mfMinimalDepth
)
132 mfMinimalDepth
= aPointInView
.getZ();
141 // process recursively
142 process(rCandidate
.get3DDecomposition(getViewInformation3D()));
147 } // end of namespace processor3d
148 } // end of namespace drawinglayer
150 //////////////////////////////////////////////////////////////////////////////
151 // changed to create values using VCs, Primitive3DSequence and ViewInformation3D to allow
152 // removal of old 3D bucket geometry. There is one slight difference in the result, it's
153 // in [0.0 .. 1.0] for Z-Depth since the scaling of the scene as 2D object is no longer
154 // part of the 3D transformations. This could be added since the ViewContactOfE3dScene is
155 // given, but is not needed since the permutation of the depth values needs only be correct
156 // relative to each other
158 double getMinimalDepthInViewCoordinates(const E3dCompoundObject
& rObject
)
160 // this is a E3dCompoundObject, so it cannot be a scene (which is a E3dObject).
161 // Get primitive sequence using VC
162 const sdr::contact::ViewContactOfE3d
& rVCObject
= static_cast< sdr::contact::ViewContactOfE3d
& >(rObject
.GetViewContact());
163 const drawinglayer::primitive3d::Primitive3DSequence aPrimitives
= rVCObject
.getViewIndependentPrimitive3DSequence();
164 double fRetval(DBL_MAX
);
166 if(aPrimitives
.hasElements())
168 const E3dScene
* pScene
= rObject
.GetScene();
172 // get ViewInformation3D from scene using VC
173 const sdr::contact::ViewContactOfE3dScene
& rVCScene
= static_cast< sdr::contact::ViewContactOfE3dScene
& >(pScene
->GetViewContact());
174 const drawinglayer::geometry::ViewInformation3D
aViewInfo3D(rVCScene
.getViewInformation3D());
176 // the scene's object transformation is already part of aViewInfo3D.getObjectTransformation()
177 // for historical reasons (see ViewContactOfE3dScene::createViewInformation3D for more info)
178 // and the object's transform is part of aPrimitives (and taken into account when decomposing
179 // to PolygonHairlinePrimitive3D and PolyPolygonMaterialPrimitive3D). The missing part may be
180 // some Scene SdrObjects lying in-between which may need to be added. This is e.g. used in chart,
181 // and generally allowed in 3d scenes an their 3d object hierarchy
182 basegfx::B3DHomMatrix aInBetweenSceneMatrix
;
183 E3dScene
* pParentScene
= dynamic_cast< E3dScene
* >(rObject
.GetParentObj());
185 while(pParentScene
&& pParentScene
!= pScene
)
187 aInBetweenSceneMatrix
= pParentScene
->GetTransform() * aInBetweenSceneMatrix
;
188 pParentScene
= dynamic_cast< E3dScene
* >(pParentScene
->GetParentObj());
191 // build new ViewInformation containing all transforms
192 const drawinglayer::geometry::ViewInformation3D
aNewViewInformation3D(
193 aViewInfo3D
.getObjectTransformation() * aInBetweenSceneMatrix
,
194 aViewInfo3D
.getOrientation(),
195 aViewInfo3D
.getProjection(),
196 aViewInfo3D
.getDeviceToView(),
197 aViewInfo3D
.getViewTime(),
198 aViewInfo3D
.getExtendedInformationSequence());
200 // create extractor helper, proccess geometry and get return value
201 drawinglayer::processor3d::MinimalDephInViewExtractor
aExtractor(aNewViewInformation3D
);
202 aExtractor
.process(aPrimitives
);
203 fRetval
= aExtractor
.getMinimalDepth();
210 //////////////////////////////////////////////////////////////////////////////
213 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */