LibreOffice Module svx (master)  1
helperminimaldepth3d.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include "helperminimaldepth3d.hxx"
29 #include <svx/obj3d.hxx>
30 #include <svx/scene3d.hxx>
31 
32 
33 namespace drawinglayer
34 {
35  namespace processor3d
36  {
37  namespace {
38 
39  class MinimalDephInViewExtractor : public BaseProcessor3D
40  {
41  private:
42  // the value which will be fetched as result
44 
45  // as tooling, the process() implementation takes over API handling and calls this
46  // virtual render method when the primitive implementation is BasePrimitive3D-based.
47  virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate) override;
48 
49  public:
50  explicit MinimalDephInViewExtractor(const geometry::ViewInformation3D& rViewInformation)
51  : BaseProcessor3D(rViewInformation),
52  mfMinimalDepth(DBL_MAX)
53  {}
54 
55  // data access
56  double getMinimalDepth() const { return mfMinimalDepth; }
57  };
58 
59  }
60 
61  void MinimalDephInViewExtractor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate)
62  {
63  // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch
64  switch(rCandidate.getPrimitive3DID())
65  {
67  {
68  // transform group. Remember current transformations
69  const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate);
70  const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
71 
72  // create new transformation; add new object transform from right side
73  const geometry::ViewInformation3D aNewViewInformation3D(
74  aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(),
75  aLastViewInformation3D.getOrientation(),
76  aLastViewInformation3D.getProjection(),
77  aLastViewInformation3D.getDeviceToView(),
78  aLastViewInformation3D.getViewTime(),
79  aLastViewInformation3D.getExtendedInformationSequence());
80  updateViewInformation(aNewViewInformation3D);
81 
82  // let break down
83  process(rPrimitive.getChildren());
84 
85  // restore transformations
86  updateViewInformation(aLastViewInformation3D);
87  break;
88  }
90  {
91  // PolygonHairlinePrimitive3D
92  const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rCandidate);
93  const basegfx::B3DPolygon& rPolygon = rPrimitive.getB3DPolygon();
94  const sal_uInt32 nCount(rPolygon.count());
95 
96  for(sal_uInt32 a(0); a < nCount; a++)
97  {
98  const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * rPolygon.getB3DPoint(a));
99 
100  if(aPointInView.getZ() < mfMinimalDepth)
101  {
102  mfMinimalDepth = aPointInView.getZ();
103  }
104  }
105 
106  break;
107  }
109  {
110  // PolyPolygonMaterialPrimitive3D
111  const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate);
112  const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon();
113  const sal_uInt32 nPolyCount(rPolyPolygon.count());
114 
115  for(sal_uInt32 a(0); a < nPolyCount; a++)
116  {
117  const basegfx::B3DPolygon& aPolygon(rPolyPolygon.getB3DPolygon(a));
118  const sal_uInt32 nCount(aPolygon.count());
119 
120  for(sal_uInt32 b(0); b < nCount; b++)
121  {
122  const basegfx::B3DPoint aPointInView(getViewInformation3D().getObjectToView() * aPolygon.getB3DPoint(b));
123 
124  if(aPointInView.getZ() < mfMinimalDepth)
125  {
126  mfMinimalDepth = aPointInView.getZ();
127  }
128  }
129  }
130 
131  break;
132  }
133  default :
134  {
135  // process recursively
136  process(rCandidate.get3DDecomposition(getViewInformation3D()));
137  break;
138  }
139  }
140  }
141  } // end of namespace processor3d
142 } // end of namespace drawinglayer
143 
144 
145 // changed to create values using VCs, Primitive3DContainer and ViewInformation3D to allow
146 // removal of old 3D bucket geometry. There is one slight difference in the result, it's
147 // in [0.0 .. 1.0] for Z-Depth since the scaling of the scene as 2D object is no longer
148 // part of the 3D transformations. This could be added since the ViewContactOfE3dScene is
149 // given, but is not needed since the permutation of the depth values needs only be correct
150 // relative to each other
151 
153 {
154  // this is an E3dCompoundObject, so it cannot be a scene (which is an E3dObject).
155  // Get primitive sequence using VC
156  const sdr::contact::ViewContactOfE3d& rVCObject = static_cast< sdr::contact::ViewContactOfE3d& >(rObject.GetViewContact());
158  double fRetval(DBL_MAX);
159 
160  if(!aPrimitives.empty())
161  {
162  const E3dScene* pScene(rObject.getRootE3dSceneFromE3dObject());
163 
164  if(pScene)
165  {
166  // get ViewInformation3D from scene using VC
167  const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
169 
170  // the scene's object transformation is already part of aViewInfo3D.getObjectTransformation()
171  // for historical reasons (see ViewContactOfE3dScene::createViewInformation3D for more info)
172  // and the object's transform is part of aPrimitives (and taken into account when decomposing
173  // to PolygonHairlinePrimitive3D and PolyPolygonMaterialPrimitive3D). The missing part may be
174  // some Scene SdrObjects lying in-between which may need to be added. This is e.g. used in chart,
175  // and generally allowed in 3d scenes and their 3d object hierarchy
176  basegfx::B3DHomMatrix aInBetweenSceneMatrix;
177  E3dScene* pParentScene(rObject.getParentE3dSceneFromE3dObject());
178 
179  while(pParentScene && pParentScene != pScene)
180  {
181  aInBetweenSceneMatrix = pParentScene->GetTransform() * aInBetweenSceneMatrix;
182  pParentScene = pParentScene->getParentE3dSceneFromE3dObject();
183  }
184 
185  // build new ViewInformation containing all transforms
186  const drawinglayer::geometry::ViewInformation3D aNewViewInformation3D(
187  aViewInfo3D.getObjectTransformation() * aInBetweenSceneMatrix,
188  aViewInfo3D.getOrientation(),
189  aViewInfo3D.getProjection(),
190  aViewInfo3D.getDeviceToView(),
191  aViewInfo3D.getViewTime(),
192  aViewInfo3D.getExtendedInformationSequence());
193 
194  // create extractor helper, process geometry and get return value
195  drawinglayer::processor3d::MinimalDephInViewExtractor aExtractor(aNewViewInformation3D);
196  aExtractor.process(aPrimitives);
197  fRetval = aExtractor.getMinimalDepth();
198  }
199  }
200 
201  return fRetval;
202 }
203 
204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D
double getMinimalDepthInViewCoordinates(const E3dCompoundObject &rObject)
support extracting the minimal depth of a 3d object in its scene
sal_uInt32 count() const
const drawinglayer::geometry::ViewInformation3D & getViewInformation3D(const ::basegfx::B3DRange &rContentRange) const
drawinglayer::primitive3d::Primitive3DContainer getViewIndependentPrimitive3DContainer() const
const basegfx::B3DHomMatrix & GetTransform() const
Definition: obj3d.hxx:111
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:271
sal_uInt32 count() const
int nCount
B3DPoint const & getB3DPoint(sal_uInt32 nIndex) const
E3dScene * getParentE3dSceneFromE3dObject() const
Definition: obj3d.cxx:281
uno_Any a
#define PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D
virtual E3dScene * getRootE3dSceneFromE3dObject() const
Definition: obj3d.cxx:287
double mfMinimalDepth
B3DPolygon const & getB3DPolygon(sal_uInt32 nIndex) const
#define PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D