Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/drawinglayer/source/primitive3d/sdrcubeprimitive3d.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 <com/sun/star/drawing/NormalsKind.hpp>
21
#include <drawinglayer/primitive3d/sdrcubeprimitive3d.hxx>
22
#include <basegfx/point/b2dpoint.hxx>
23
#include <basegfx/polygon/b3dpolypolygontools.hxx>
24
#include <basegfx/polygon/b3dpolygon.hxx>
25
#include <basegfx/range/b3drange.hxx>
26
#include <basegfx/matrix/b2dhommatrix.hxx>
27
#include <primitive3d/sdrdecompositiontools3d.hxx>
28
#include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
29
#include <drawinglayer/attribute/sdrfillattribute.hxx>
30
#include <drawinglayer/attribute/sdrlineattribute.hxx>
31
#include <drawinglayer/attribute/sdrshadowattribute.hxx>
32
33
34
using namespace com::sun::star;
35
36
37
namespace drawinglayer::primitive3d
38
{
39
        Primitive3DContainer SdrCubePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const
40
0
        {
41
0
            const basegfx::B3DRange aUnitRange(0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
42
0
            Primitive3DContainer aRetval;
43
0
            basegfx::B3DPolyPolygon aFill(basegfx::utils::createCubeFillPolyPolygonFromB3DRange(aUnitRange));
44
45
            // normal creation
46
0
            if(!getSdrLFSAttribute().getFill().isDefault())
47
0
            {
48
0
                if(css::drawing::NormalsKind_SPECIFIC == getSdr3DObjectAttribute().getNormalsKind()
49
0
                    || css::drawing::NormalsKind_SPHERE == getSdr3DObjectAttribute().getNormalsKind())
50
0
                {
51
                    // create sphere normals
52
0
                    const basegfx::B3DPoint aCenter(basegfx::utils::getRange(aFill).getCenter());
53
0
                    aFill = basegfx::utils::applyDefaultNormalsSphere(aFill, aCenter);
54
0
                }
55
56
0
                if(getSdr3DObjectAttribute().getNormalsInvert())
57
0
                {
58
                    // invert normals
59
0
                    aFill = basegfx::utils::invertNormals(aFill);
60
0
                }
61
0
            }
62
63
            // texture coordinates
64
0
            if(!getSdrLFSAttribute().getFill().isDefault())
65
0
            {
66
                // handle texture coordinates X
67
0
                const bool bParallelX(css::drawing::TextureProjectionMode_PARALLEL == getSdr3DObjectAttribute().getTextureProjectionX());
68
0
                const bool bObjectSpecificX(css::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionX());
69
0
                const bool bSphereX(!bParallelX && (css::drawing::TextureProjectionMode_SPHERE == getSdr3DObjectAttribute().getTextureProjectionX()));
70
71
                // handle texture coordinates Y
72
0
                const bool bParallelY(css::drawing::TextureProjectionMode_PARALLEL == getSdr3DObjectAttribute().getTextureProjectionY());
73
0
                const bool bObjectSpecificY(css::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionY());
74
0
                const bool bSphereY(!bParallelY && (css::drawing::TextureProjectionMode_SPHERE == getSdr3DObjectAttribute().getTextureProjectionY()));
75
76
0
                if(bParallelX || bParallelY)
77
0
                {
78
                    // apply parallel texture coordinates in X and/or Y
79
0
                    const basegfx::B3DRange aRange(basegfx::utils::getRange(aFill));
80
0
                    aFill = basegfx::utils::applyDefaultTextureCoordinatesParallel(aFill, aRange, bParallelX, bParallelY);
81
0
                }
82
83
0
                if(bSphereX || bSphereY)
84
0
                {
85
                    // apply spherical texture coordinates in X and/or Y
86
0
                    const basegfx::B3DRange aRange(basegfx::utils::getRange(aFill));
87
0
                    const basegfx::B3DPoint aCenter(aRange.getCenter());
88
0
                    aFill = basegfx::utils::applyDefaultTextureCoordinatesSphere(aFill, aCenter, bSphereX, bSphereY);
89
0
                }
90
91
0
                if(bObjectSpecificX || bObjectSpecificY)
92
0
                {
93
                    // object-specific
94
0
                    for(sal_uInt32 a(0); a < aFill.count(); a++)
95
0
                    {
96
0
                        basegfx::B3DPolygon aTmpPoly(aFill.getB3DPolygon(a));
97
98
0
                        if(aTmpPoly.count() >= 4)
99
0
                        {
100
0
                            for(sal_uInt32 b(0); b < 4; b++)
101
0
                            {
102
0
                                basegfx::B2DPoint aPoint(aTmpPoly.getTextureCoordinate(b));
103
104
0
                                if(bObjectSpecificX)
105
0
                                {
106
0
                                    aPoint.setX((1 == b || 2 == b) ? 1.0 : 0.0);
107
0
                                }
108
109
0
                                if(bObjectSpecificY)
110
0
                                {
111
0
                                    aPoint.setY((2 == b || 3 == b) ? 1.0 : 0.0);
112
0
                                }
113
114
0
                                aTmpPoly.setTextureCoordinate(b, aPoint);
115
0
                            }
116
117
0
                            aFill.setB3DPolygon(a, aTmpPoly);
118
0
                        }
119
0
                    }
120
0
                }
121
122
                // transform texture coordinates to texture size
123
0
                basegfx::B2DHomMatrix aTexMatrix;
124
0
                aTexMatrix.scale(getTextureSize().getX(), getTextureSize().getY());
125
0
                aFill.transformTextureCoordinates(aTexMatrix);
126
0
            }
127
128
            // build vector of PolyPolygons
129
0
            std::vector< basegfx::B3DPolyPolygon > a3DPolyPolygonVector;
130
131
0
            for(sal_uInt32 a(0); a < aFill.count(); a++)
132
0
            {
133
0
                a3DPolyPolygonVector.emplace_back(aFill.getB3DPolygon(a));
134
0
            }
135
136
0
            if(!getSdrLFSAttribute().getFill().isDefault())
137
0
            {
138
                // add fill
139
0
                aRetval = create3DPolyPolygonFillPrimitives(
140
0
                    a3DPolyPolygonVector,
141
0
                    getTransform(),
142
0
                    getTextureSize(),
143
0
                    getSdr3DObjectAttribute(),
144
0
                    getSdrLFSAttribute().getFill(),
145
0
                    getSdrLFSAttribute().getFillFloatTransGradient());
146
0
            }
147
0
            else
148
0
            {
149
                // create simplified 3d hit test geometry
150
0
                aRetval = createHiddenGeometryPrimitives3D(
151
0
                    a3DPolyPolygonVector,
152
0
                    getTransform(),
153
0
                    getTextureSize(),
154
0
                    getSdr3DObjectAttribute());
155
0
            }
156
157
            // add line
158
0
            if(!getSdrLFSAttribute().getLine().isDefault())
159
0
            {
160
0
                basegfx::B3DPolyPolygon aLine(basegfx::utils::createCubePolyPolygonFromB3DRange(aUnitRange));
161
0
                const Primitive3DContainer aLines(create3DPolyPolygonLinePrimitives(
162
0
                    aLine, getTransform(), getSdrLFSAttribute().getLine()));
163
0
                aRetval.append(aLines);
164
0
            }
165
166
            // add shadow
167
0
            if(!getSdrLFSAttribute().getShadow().isDefault() && !aRetval.empty())
168
0
            {
169
0
                const Primitive3DContainer aShadow(createShadowPrimitive3D(
170
0
                    aRetval, getSdrLFSAttribute().getShadow(), getSdr3DObjectAttribute().getShadow3D()));
171
0
                aRetval.append(aShadow);
172
0
            }
173
174
0
            return aRetval;
175
0
        }
176
177
        SdrCubePrimitive3D::SdrCubePrimitive3D(
178
            const basegfx::B3DHomMatrix& rTransform,
179
            const basegfx::B2DVector& rTextureSize,
180
            const attribute::SdrLineFillShadowAttribute3D& rSdrLFSAttribute,
181
            const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute)
182
0
        :   SdrPrimitive3D(rTransform, rTextureSize, rSdrLFSAttribute, rSdr3DObjectAttribute)
183
0
        {
184
0
        }
Unexecuted instantiation: drawinglayer::primitive3d::SdrCubePrimitive3D::SdrCubePrimitive3D(basegfx::B3DHomMatrix const&, basegfx::B2DVector const&, drawinglayer::attribute::SdrLineFillShadowAttribute3D const&, drawinglayer::attribute::Sdr3DObjectAttribute const&)
Unexecuted instantiation: drawinglayer::primitive3d::SdrCubePrimitive3D::SdrCubePrimitive3D(basegfx::B3DHomMatrix const&, basegfx::B2DVector const&, drawinglayer::attribute::SdrLineFillShadowAttribute3D const&, drawinglayer::attribute::Sdr3DObjectAttribute const&)
185
186
        basegfx::B3DRange SdrCubePrimitive3D::getB3DRange(const geometry::ViewInformation3D& /*rViewInformation*/) const
187
0
        {
188
            // use default from sdrPrimitive3D which uses transformation expanded by line width/2.
189
            // The parent implementation which uses the ranges of the decomposition would be more
190
            // correct, but for historical reasons it is necessary to do the old method: To get
191
            // the range of the non-transformed geometry and transform it then. This leads to different
192
            // ranges where the new method is more correct, but the need to keep the old behaviour
193
            // has priority here.
194
0
            return getStandard3DRange();
195
0
        }
196
197
        // provide unique ID
198
        ImplPrimitive3DIDBlock(SdrCubePrimitive3D, PRIMITIVE3D_ID_SDRCUBEPRIMITIVE3D)
199
200
} // end of namespace
201
202
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */