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