LibreOffice Module svx (master)  1
viewcontactofe3dpolygon.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 
22 #include <svx/polygn3d.hxx>
28 #include <memory>
29 
30 
31 namespace sdr
32 {
33  namespace contact
34  {
36  : ViewContactOfE3d(rPolygon)
37  {
38  }
39 
41  {
42  }
43 
45  {
47  const SfxItemSet& rItemSet = GetE3dPolygonObj().GetMergedItemSet();
48  const bool bSuppressFill(GetE3dPolygonObj().GetLineOnly());
51 
52  // get extrude geometry
53  basegfx::B3DPolyPolygon aPolyPolygon3D(GetE3dPolygonObj().GetPolyPolygon3D());
54  const basegfx::B3DPolyPolygon aPolyNormals3D(GetE3dPolygonObj().GetPolyNormals3D());
55  const basegfx::B2DPolyPolygon aPolyTexture2D(GetE3dPolygonObj().GetPolyTexture2D());
56  const bool bNormals(aPolyNormals3D.count() && aPolyNormals3D.count() == aPolyPolygon3D.count());
57  const bool bTexture(aPolyTexture2D.count() && aPolyTexture2D.count() == aPolyPolygon3D.count());
58 
59  if(bNormals || bTexture)
60  {
61  for(sal_uInt32 a(0); a < aPolyPolygon3D.count(); a++)
62  {
63  basegfx::B3DPolygon aCandidate3D(aPolyPolygon3D.getB3DPolygon(a));
64  basegfx::B3DPolygon aNormals3D;
65  basegfx::B2DPolygon aTexture2D;
66 
67  if(bNormals)
68  {
69  aNormals3D = aPolyNormals3D.getB3DPolygon(a);
70  }
71 
72  if(bTexture)
73  {
74  aTexture2D = aPolyTexture2D.getB2DPolygon(a);
75  }
76 
77  for(sal_uInt32 b(0); b < aCandidate3D.count(); b++)
78  {
79  if(bNormals)
80  {
81  sal_uInt32 nNormalCount = aNormals3D.count();
82  if( b < nNormalCount )
83  aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(b));
84  else if( nNormalCount > 0 )
85  aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(0));
86  }
87  if(bTexture)
88  {
89  sal_uInt32 nTextureCount = aTexture2D.count();
90  if( b < nTextureCount )
91  aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(b));
92  else if( nTextureCount > 0 )
93  aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(0));
94  }
95  }
96 
97  aPolyPolygon3D.setB3DPolygon(a, aCandidate3D);
98  }
99  }
100 
101  // get 3D Object Attributes
102  std::unique_ptr<drawinglayer::attribute::Sdr3DObjectAttribute> pSdr3DObjectAttribute(drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet));
103 
104  // calculate texture size
105  basegfx::B2DVector aTextureSize(1.0, 1.0);
106 
107  if(bTexture)
108  {
109  // #i98314#
110  // create texture size from object's size
111  const basegfx::B3DRange aObjectRange(basegfx::utils::getRange(aPolyPolygon3D));
112 
113  double fWidth(0.0);
114  double fHeight(0.0);
115 
116  // this is a polygon object, so Width/Height and/or Depth may be zero (e.g. left
117  // wall of chart). Take this into account
118  if(basegfx::fTools::equalZero(aObjectRange.getWidth()))
119  {
120  // width is zero, use height and depth
121  fWidth = aObjectRange.getHeight();
122  fHeight = aObjectRange.getDepth();
123  }
124  else if(basegfx::fTools::equalZero(aObjectRange.getHeight()))
125  {
126  // height is zero, use width and depth
127  fWidth = aObjectRange.getWidth();
128  fHeight = aObjectRange.getDepth();
129  }
130  else
131  {
132  // use width and height
133  fWidth = aObjectRange.getWidth();
134  fHeight = aObjectRange.getHeight();
135  }
136 
137  if(basegfx::fTools::lessOrEqual(fWidth, 0.0) ||basegfx::fTools::lessOrEqual(fHeight, 0.0))
138  {
139  // no texture; fallback to very small size
140  aTextureSize.setX(0.01);
141  aTextureSize.setY(0.01);
142  }
143  else
144  {
145  aTextureSize.setX(fWidth);
146  aTextureSize.setY(fHeight);
147  }
148  }
149 
150  // #i98295#
151  // unfortunately, this SdrObject type which allows a free 3d geometry definition was defined
152  // wrong topologically in relation to its plane normal and 3D visibility when it was invented
153  // a long time ago. Since the API allows creation of this SDrObject type, it is not possible to
154  // simply change this definition. Only the chart should use it, and at least this object type
155  // only exists at Runtime (is not saved and/or loaded in any FileFormat). Still someone external
156  // may have used it in its API. To not risk wrong 3D lightings, I have to switch the orientation
157  // of the polygon here
158  aPolyPolygon3D.flip();
159 
160  // create primitive and add
161  const basegfx::B3DHomMatrix aWorldTransform;
164  aPolyPolygon3D, aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute));
165  xRetval = { xReference };
166 
167  return xRetval;
168  }
169  } // end of namespace contact
170 } // end of namespace sdr
171 
172 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool lessOrEqual(const double &rfValA, const double &rfValB)
void setX(double fX)
const E3dPolygonObj & GetE3dPolygonObj() const
virtual drawinglayer::primitive3d::Primitive3DContainer createViewIndependentPrimitive3DContainer() const override
attribute::Sdr3DObjectAttribute * createNewSdr3DObjectAttribute(const SfxItemSet &rSet)
attribute::SdrLineFillShadowAttribute3D createNewSdrLineFillShadowAttribute(const SfxItemSet &rSet, bool bSuppressFill)
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
sal_uInt32 count() const
double getHeight() const
uno_Any a
static bool equalZero(const double &rfVal)
css::uno::Reference< css::graphic::XPrimitive3D > Primitive3DReference
B2DRange getRange(const B2DPolygon &rCandidate)
void setB3DPolygon(sal_uInt32 nIndex, const B3DPolygon &rPolygon)
double getWidth() const
sal_uInt32 count() const
void setY(double fY)
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1911
double getDepth() const
B3DPolygon const & getB3DPolygon(sal_uInt32 nIndex) const
sal_uInt32 count() const
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const