Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx
Line
Count
Source
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 <sdr/contact/viewcontactofe3dpolygon.hxx>
22
#include <polygn3d.hxx>
23
#include <drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx>
24
#include <sdr/primitive2d/sdrattributecreator.hxx>
25
#include <sdr/primitive3d/sdrattributecreator3d.hxx>
26
#include <basegfx/polygon/b3dpolygon.hxx>
27
#include <basegfx/polygon/b3dpolypolygontools.hxx>
28
29
30
namespace sdr::contact
31
{
32
        ViewContactOfE3dPolygon::ViewContactOfE3dPolygon(E3dPolygonObj& rPolygon)
33
0
        :   ViewContactOfE3d(rPolygon)
34
0
        {
35
0
        }
36
37
        ViewContactOfE3dPolygon::~ViewContactOfE3dPolygon()
38
0
        {
39
0
        }
40
41
        drawinglayer::primitive3d::Primitive3DContainer ViewContactOfE3dPolygon::createViewIndependentPrimitive3DContainer() const
42
0
        {
43
0
            drawinglayer::primitive3d::Primitive3DContainer xRetval;
44
0
            const SfxItemSet& rItemSet = GetE3dPolygonObj().GetMergedItemSet();
45
0
            const bool bSuppressFill(GetE3dPolygonObj().GetLineOnly());
46
0
            const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute(
47
0
                drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, bSuppressFill));
48
49
            // get extrude geometry
50
0
            basegfx::B3DPolyPolygon aPolyPolygon3D(GetE3dPolygonObj().GetPolyPolygon3D());
51
0
            const basegfx::B3DPolyPolygon aPolyNormals3D(GetE3dPolygonObj().GetPolyNormals3D());
52
0
            const basegfx::B2DPolyPolygon aPolyTexture2D(GetE3dPolygonObj().GetPolyTexture2D());
53
0
            const bool bNormals(aPolyNormals3D.count() && aPolyNormals3D.count() == aPolyPolygon3D.count());
54
0
            const bool bTexture(aPolyTexture2D.count() && aPolyTexture2D.count() == aPolyPolygon3D.count());
55
56
0
            if(bNormals || bTexture)
57
0
            {
58
0
                for(sal_uInt32 a(0); a < aPolyPolygon3D.count(); a++)
59
0
                {
60
0
                    basegfx::B3DPolygon aCandidate3D(aPolyPolygon3D.getB3DPolygon(a));
61
0
                    basegfx::B3DPolygon aNormals3D;
62
0
                    basegfx::B2DPolygon aTexture2D;
63
64
0
                    if(bNormals)
65
0
                    {
66
0
                        aNormals3D = aPolyNormals3D.getB3DPolygon(a);
67
0
                    }
68
69
0
                    if(bTexture)
70
0
                    {
71
0
                        aTexture2D = aPolyTexture2D.getB2DPolygon(a);
72
0
                    }
73
74
0
                    for(sal_uInt32 b(0); b < aCandidate3D.count(); b++)
75
0
                    {
76
0
                        if(bNormals)
77
0
                        {
78
0
                            sal_uInt32 nNormalCount = aNormals3D.count();
79
0
                            if( b < nNormalCount )
80
0
                                aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(b));
81
0
                            else if( nNormalCount > 0 )
82
0
                                aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(0));
83
0
                        }
84
0
                        if(bTexture)
85
0
                        {
86
0
                            sal_uInt32 nTextureCount = aTexture2D.count();
87
0
                            if( b < nTextureCount )
88
0
                                aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(b));
89
0
                            else if( nTextureCount > 0 )
90
0
                                aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(0));
91
0
                        }
92
0
                    }
93
94
0
                    aPolyPolygon3D.setB3DPolygon(a, aCandidate3D);
95
0
                }
96
0
            }
97
98
            // get 3D Object Attributes
99
0
            drawinglayer::attribute::Sdr3DObjectAttribute aSdr3DObjectAttribute(drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet));
100
101
            // calculate texture size
102
0
            basegfx::B2DVector aTextureSize(1.0, 1.0);
103
104
0
            if(bTexture)
105
0
            {
106
                // #i98314#
107
                // create texture size from object's size
108
0
                const basegfx::B3DRange aObjectRange(basegfx::utils::getRange(aPolyPolygon3D));
109
110
0
                double fWidth(0.0);
111
0
                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
0
                if(basegfx::fTools::equalZero(aObjectRange.getWidth()))
116
0
                {
117
                    // width is zero, use height and depth
118
0
                    fWidth = aObjectRange.getHeight();
119
0
                    fHeight = aObjectRange.getDepth();
120
0
                }
121
0
                else if(basegfx::fTools::equalZero(aObjectRange.getHeight()))
122
0
                {
123
                    // height is zero, use width and depth
124
0
                    fWidth = aObjectRange.getWidth();
125
0
                    fHeight = aObjectRange.getDepth();
126
0
                }
127
0
                else
128
0
                {
129
                    // use width and height
130
0
                    fWidth = aObjectRange.getWidth();
131
0
                    fHeight = aObjectRange.getHeight();
132
0
                }
133
134
0
                if(fWidth <= 0.0 || fHeight <= 0.0)
135
0
                {
136
                    // no texture; fallback to very small size
137
0
                    aTextureSize.setX(0.01);
138
0
                    aTextureSize.setY(0.01);
139
0
                }
140
0
                else
141
0
                {
142
0
                    aTextureSize.setX(fWidth);
143
0
                    aTextureSize.setY(fHeight);
144
0
                }
145
0
            }
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
0
            aPolyPolygon3D.flip();
156
157
            // create primitive and add
158
0
            const basegfx::B3DHomMatrix aWorldTransform;
159
0
            const drawinglayer::primitive3d::Primitive3DReference xReference(
160
0
                new drawinglayer::primitive3d::SdrPolyPolygonPrimitive3D(
161
0
                    std::move(aPolyPolygon3D), aWorldTransform, aTextureSize, aAttribute, aSdr3DObjectAttribute));
162
0
            xRetval = { xReference };
163
164
0
            return xRetval;
165
0
        }
166
167
} // end of namespace
168
169
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */