Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/engine3d/polygn3d.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
#include <polygn3d.hxx>
21
#include <svx/svdobjkind.hxx>
22
#include <basegfx/point/b3dpoint.hxx>
23
#include <sdr/contact/viewcontactofe3dpolygon.hxx>
24
#include <basegfx/polygon/b3dpolygon.hxx>
25
#include <basegfx/polygon/b3dpolygontools.hxx>
26
27
// DrawContact section
28
std::unique_ptr<sdr::contact::ViewContact> E3dPolygonObj::CreateObjectSpecificViewContact()
29
0
{
30
0
    return std::make_unique<sdr::contact::ViewContactOfE3dPolygon>(*this);
31
0
}
32
33
E3dPolygonObj::E3dPolygonObj(SdrModel& rSdrModel, const basegfx::B3DPolyPolygon& rPolyPoly3D)
34
0
    : E3dCompoundObject(rSdrModel)
35
0
    , bLineOnly(true)
36
0
{
37
    // Set geometry
38
0
    SetPolyPolygon3D(rPolyPoly3D);
39
40
    // Create default normals
41
0
    CreateDefaultNormals();
42
43
    // Create default texture coordinates
44
0
    CreateDefaultTexture();
45
0
}
46
47
E3dPolygonObj::E3dPolygonObj(SdrModel& rSdrModel)
48
0
    : E3dCompoundObject(rSdrModel)
49
0
    , bLineOnly(false)
50
0
{
51
    // Create no geometry
52
0
}
53
54
E3dPolygonObj::E3dPolygonObj(SdrModel& rSdrModel, E3dPolygonObj const& rSource)
55
0
    : E3dCompoundObject(rSdrModel, rSource)
56
0
    , bLineOnly(false)
57
0
{
58
    // Create no geometry
59
60
0
    aPolyPoly3D = rSource.aPolyPoly3D;
61
0
    aPolyNormals3D = rSource.aPolyNormals3D;
62
0
    aPolyTexture2D = rSource.aPolyTexture2D;
63
0
    bLineOnly = rSource.bLineOnly;
64
0
}
65
66
void E3dPolygonObj::CreateDefaultNormals()
67
0
{
68
0
    basegfx::B3DPolyPolygon aPolyNormals;
69
70
    // Create a complete tools::PolyPolygon with the plane normal
71
0
    for (sal_uInt32 a(0); a < aPolyPoly3D.count(); a++)
72
0
    {
73
        // Find source polygon
74
0
        const basegfx::B3DPolygon aPolygon(aPolyPoly3D.getB3DPolygon(a));
75
76
        // Creating a new polygon for the normal
77
0
        basegfx::B3DPolygon aNormals;
78
79
        // Get normal (and invert)
80
0
        basegfx::B3DVector aNormal(-aPolygon.getNormal());
81
82
        // Fill new polygon
83
0
        for (sal_uInt32 b(0); b < aPolygon.count(); b++)
84
0
        {
85
0
            aNormals.append(aNormal);
86
0
        }
87
88
        // Insert new polygon into the PolyPolygon
89
0
        aPolyNormals.append(aNormals);
90
0
    }
91
92
    // Set default normal
93
0
    SetPolyNormals3D(aPolyNormals);
94
0
}
95
96
void E3dPolygonObj::CreateDefaultTexture()
97
0
{
98
0
    basegfx::B2DPolyPolygon aPolyTexture;
99
    // Create a complete tools::PolyPolygon with the texture coordinates
100
    // The texture coordinates extend over X,Y and Z
101
    // on the whole extreme values in the range 0.0 .. 1.0
102
0
    for (sal_uInt32 a(0); a < aPolyPoly3D.count(); a++)
103
0
    {
104
        // Find source polygon
105
0
        const basegfx::B3DPolygon& aPolygon(aPolyPoly3D.getB3DPolygon(a));
106
107
        // Determine the total size of the object
108
0
        basegfx::B3DRange aVolume(basegfx::utils::getRange(aPolygon));
109
110
        // Get normal
111
0
        basegfx::B3DVector aNormal(aPolygon.getNormal());
112
0
        aNormal.setX(fabs(aNormal.getX()));
113
0
        aNormal.setY(fabs(aNormal.getY()));
114
0
        aNormal.setZ(fabs(aNormal.getZ()));
115
116
        // Decide which coordinates should be used as a source for the mapping
117
0
        sal_uInt16 nSourceMode = 0;
118
119
        // Determine the greatest degree of freedom
120
0
        if (aNormal.getX() <= aNormal.getY() || aNormal.getX() <= aNormal.getZ())
121
0
        {
122
0
            if (aNormal.getY() > aNormal.getZ())
123
0
            {
124
                // Y is the largest, use X,Z as mapping
125
0
                nSourceMode = 1;
126
0
            }
127
0
            else
128
0
            {
129
                // Z is the largest, use X,Y as mapping
130
0
                nSourceMode = 2;
131
0
            }
132
0
        }
133
134
        // Create new polygon for texture coordinates
135
0
        basegfx::B2DPolygon aTexture;
136
137
        // Fill new polygon
138
0
        for (sal_uInt32 b(0); b < aPolygon.count(); b++)
139
0
        {
140
0
            basegfx::B2DPoint aTex;
141
0
            const basegfx::B3DPoint aCandidate(aPolygon.getB3DPoint(b));
142
143
0
            switch (nSourceMode)
144
0
            {
145
0
                case 0: //Source is Y,Z
146
0
                    if (aVolume.getHeight())
147
0
                        aTex.setX((aCandidate.getY() - aVolume.getMinY()) / aVolume.getHeight());
148
0
                    if (aVolume.getDepth())
149
0
                        aTex.setY((aCandidate.getZ() - aVolume.getMinZ()) / aVolume.getDepth());
150
0
                    break;
151
152
0
                case 1: // Source is X,Z
153
0
                    if (aVolume.getWidth())
154
0
                        aTex.setX((aCandidate.getX() - aVolume.getMinX()) / aVolume.getWidth());
155
0
                    if (aVolume.getDepth())
156
0
                        aTex.setY((aCandidate.getZ() - aVolume.getMinZ()) / aVolume.getDepth());
157
0
                    break;
158
159
0
                case 2: // Source is X,Y
160
0
                    if (aVolume.getWidth())
161
0
                        aTex.setX((aCandidate.getX() - aVolume.getMinX()) / aVolume.getWidth());
162
0
                    if (aVolume.getHeight())
163
0
                        aTex.setY((aCandidate.getY() - aVolume.getMinY()) / aVolume.getHeight());
164
0
                    break;
165
0
            }
166
167
0
            aTexture.append(aTex);
168
0
        }
169
170
        // Insert new polygon into the PolyPolygon
171
0
        aPolyTexture.append(aTexture);
172
0
    }
173
174
    // Set default Texture coordinates
175
0
    SetPolyTexture2D(aPolyTexture);
176
0
}
177
178
0
E3dPolygonObj::~E3dPolygonObj() {}
179
180
0
SdrObjKind E3dPolygonObj::GetObjIdentifier() const { return SdrObjKind::E3D_Polygon; }
181
182
void E3dPolygonObj::SetPolyPolygon3D(const basegfx::B3DPolyPolygon& rNewPolyPoly3D)
183
0
{
184
0
    if (aPolyPoly3D != rNewPolyPoly3D)
185
0
    {
186
        // New PolyPolygon; copying
187
0
        aPolyPoly3D = rNewPolyPoly3D;
188
189
        // Create new geometry
190
0
        ActionChanged();
191
0
    }
192
0
}
193
194
void E3dPolygonObj::SetPolyNormals3D(const basegfx::B3DPolyPolygon& rNewPolyNormals3D)
195
0
{
196
0
    if (aPolyNormals3D != rNewPolyNormals3D)
197
0
    {
198
        // New PolyPolygon; copying
199
0
        aPolyNormals3D = rNewPolyNormals3D;
200
201
        // Create new geometry
202
0
        ActionChanged();
203
0
    }
204
0
}
205
206
void E3dPolygonObj::SetPolyTexture2D(const basegfx::B2DPolyPolygon& rNewPolyTexture2D)
207
0
{
208
0
    if (aPolyTexture2D != rNewPolyTexture2D)
209
0
    {
210
        // New PolyPolygon; copying
211
0
        aPolyTexture2D = rNewPolyTexture2D;
212
213
        // Create new geometry
214
0
        ActionChanged();
215
0
    }
216
0
}
217
218
// Convert the object into a group object consisting of 6 polygons
219
220
rtl::Reference<SdrObject> E3dPolygonObj::DoConvertToPolyObj(bool /*bBezier*/,
221
                                                            bool /*bAddText*/) const
222
0
{
223
0
    return nullptr;
224
0
}
225
226
rtl::Reference<SdrObject> E3dPolygonObj::CloneSdrObject(SdrModel& rTargetModel) const
227
0
{
228
0
    return new E3dPolygonObj(rTargetModel, *this);
229
0
}
230
231
void E3dPolygonObj::SetLineOnly(bool bNew)
232
0
{
233
0
    if (bNew != bLineOnly)
234
0
    {
235
0
        bLineOnly = bNew;
236
0
        ActionChanged();
237
0
    }
238
0
}
239
240
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */