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: 55 MinimalDephInViewExtractor(const geometry::ViewInformation3D& rViewInformation) 56 : BaseProcessor3D(rViewInformation), 57 mfMinimalDepth(DBL_MAX) 58 {} 59 60 // data access 61 double getMinimalDepth() const { return mfMinimalDepth; } 62 }; 63 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 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