1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26
27 #include <helperminimaldepth3d.hxx>
28 #include <drawinglayer/processor3d/baseprocessor3d.hxx>
29 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
30 #include <drawinglayer/primitive3d/transformprimitive3d.hxx>
31 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
32 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
33 #include <svx/sdr/contact/viewcontactofe3d.hxx>
34 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
35 #include <svx/obj3d.hxx>
36 #include <svx/scene3d.hxx>
37
38 //////////////////////////////////////////////////////////////////////////////
39
40 namespace drawinglayer
41 {
42 namespace processor3d
43 {
44 class MinimalDephInViewExtractor : public BaseProcessor3D
45 {
46 private:
47 // the value which will be fetched as result
48 double mfMinimalDepth;
49
50 // as tooling, the process() implementation takes over API handling and calls this
51 // virtual render method when the primitive implementation is BasePrimitive3D-based.
52 virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate);
53
54 public:
MinimalDephInViewExtractor(const geometry::ViewInformation3D & rViewInformation)55 MinimalDephInViewExtractor(const geometry::ViewInformation3D& rViewInformation)
56 : BaseProcessor3D(rViewInformation),
57 mfMinimalDepth(DBL_MAX)
58 {}
59
60 // data access
getMinimalDepth() const61 double getMinimalDepth() const { return mfMinimalDepth; }
62 };
63
processBasePrimitive3D(const primitive3d::BasePrimitive3D & rCandidate)64 void MinimalDephInViewExtractor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate)
65 {
66 // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
67 switch(rCandidate.getPrimitive3DID())
68 {
69 case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
70 {
71 // transform group. Remember current transformations
72 const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate);
73 const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
74
75 // create new transformation; add new object transform from right side
76 const geometry::ViewInformation3D aNewViewInformation3D(
77 aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(),
78 aLastViewInformation3D.getOrientation(),
79 aLastViewInformation3D.getProjection(),
80 aLastViewInformation3D.getDeviceToView(),
81 aLastViewInformation3D.getViewTime(),
82 aLastViewInformation3D.getExtendedInformationSequence());
83 updateViewInformation(aNewViewInformation3D);
84
85 // let break down
86 process(rPrimitive.getChildren());
87
88 // restore transformations
89 updateViewInformation(aLastViewInformation3D);
90 break;
91 }
92 case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
93 {
94 // PolygonHairlinePrimitive3D
95 const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rCandidate);
96 const basegfx::B3DPolygon& rPolygon = rPrimitive.getB3DPolygon();
97 const sal_uInt32 nCount(rPolygon.count());
98
99 for(sal_uInt32 a(0); a < nCount; a++)
100 {
101 const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * rPolygon.getB3DPoint(a));
102
103 if(aPointInView.getZ() < mfMinimalDepth)
104 {
105 mfMinimalDepth = aPointInView.getZ();
106 }
107 }
108
109 break;
110 }
111 case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
112 {
113 // PolyPolygonMaterialPrimitive3D
114 const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate);
115 const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon();
116 const sal_uInt32 nPolyCount(rPolyPolygon.count());
117
118 for(sal_uInt32 a(0); a < nPolyCount; a++)
119 {
120 const basegfx::B3DPolygon aPolygon(rPolyPolygon.getB3DPolygon(a));
121 const sal_uInt32 nCount(aPolygon.count());
122
123 for(sal_uInt32 b(0); b < nCount; b++)
124 {
125 const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * aPolygon.getB3DPoint(b));
126
127 if(aPointInView.getZ() < mfMinimalDepth)
128 {
129 mfMinimalDepth = aPointInView.getZ();
130 }
131 }
132 }
133
134 break;
135 }
136 default :
137 {
138 // process recursively
139 process(rCandidate.get3DDecomposition(getViewInformation3D()));
140 break;
141 }
142 }
143 }
144 } // end of namespace processor3d
145 } // end of namespace drawinglayer
146
147 //////////////////////////////////////////////////////////////////////////////
148 // changed to create values using VCs, Primitive3DSequence and ViewInformation3D to allow
149 // removal of old 3D bucket geometry. There is one slight difference in the result, it's
150 // in [0.0 .. 1.0] for Z-Depth since the scaling of the scene as 2D object is no longer
151 // part of the 3D transformations. This could be added since the ViewContactOfE3dScene is
152 // given, but is not needed since the permutation of the depth values needs only be correct
153 // relative to each other
154
getMinimalDepthInViewCoordinates(const E3dCompoundObject & rObject)155 double getMinimalDepthInViewCoordinates(const E3dCompoundObject& rObject)
156 {
157 // this is a E3dCompoundObject, so it cannot be a scene (which is a E3dObject).
158 // Get primitive sequence using VC
159 const sdr::contact::ViewContactOfE3d& rVCObject = static_cast< sdr::contact::ViewContactOfE3d& >(rObject.GetViewContact());
160 const drawinglayer::primitive3d::Primitive3DSequence aPrimitives = rVCObject.getViewIndependentPrimitive3DSequence();
161 double fRetval(DBL_MAX);
162
163 if(aPrimitives.hasElements())
164 {
165 const E3dScene* pScene = rObject.GetScene();
166
167 if(pScene)
168 {
169 // get ViewInformation3D from scene using VC
170 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
171 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
172
173 // the scene's object transformation is already part of aViewInfo3D.getObjectTransformation()
174 // for historical reasons (see ViewContactOfE3dScene::createViewInformation3D for more info)
175 // and the object's transform is part of aPrimitives (and taken into account when decomposing
176 // to PolygonHairlinePrimitive3D and PolyPolygonMaterialPrimitive3D). The missing part may be
177 // some Scene SdrObjects lying in-between which may need to be added. This is e.g. used in chart,
178 // and generally allowed in 3d scenes an their 3d object hierarchy
179 basegfx::B3DHomMatrix aInBetweenSceneMatrix;
180 E3dScene* pParentScene = dynamic_cast< E3dScene* >(rObject.GetParentObj());
181
182 while(pParentScene && pParentScene != pScene)
183 {
184 aInBetweenSceneMatrix = pParentScene->GetTransform() * aInBetweenSceneMatrix;
185 pParentScene = dynamic_cast< E3dScene* >(pParentScene->GetParentObj());
186 }
187
188 // build new ViewInformation containing all transforms
189 const drawinglayer::geometry::ViewInformation3D aNewViewInformation3D(
190 aViewInfo3D.getObjectTransformation() * aInBetweenSceneMatrix,
191 aViewInfo3D.getOrientation(),
192 aViewInfo3D.getProjection(),
193 aViewInfo3D.getDeviceToView(),
194 aViewInfo3D.getViewTime(),
195 aViewInfo3D.getExtendedInformationSequence());
196
197 // create extractor helper, proccess geometry and get return value
198 drawinglayer::processor3d::MinimalDephInViewExtractor aExtractor(aNewViewInformation3D);
199 aExtractor.process(aPrimitives);
200 fRetval = aExtractor.getMinimalDepth();
201 }
202 }
203
204 return fRetval;
205 }
206
207 //////////////////////////////////////////////////////////////////////////////
208 // eof
209