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