Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / drawinglayer / source / primitive3d / sdrdecompositiontools3d.cxx
blobc54976a998cb5a4e1ba867223fe9fbab7a5220fc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx>
21 #include <basegfx/polygon/b3dpolygon.hxx>
22 #include <drawinglayer/attribute/strokeattribute.hxx>
23 #include <drawinglayer/primitive3d/baseprimitive3d.hxx>
24 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
25 #include <basegfx/polygon/b3dpolypolygon.hxx>
26 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
27 #include <vcl/vclenum.hxx>
28 #include <drawinglayer/attribute/fillgraphicattribute.hxx>
29 #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
30 #include <vcl/bitmapaccess.hxx>
31 #include <basegfx/polygon/b3dpolypolygontools.hxx>
32 #include <drawinglayer/primitive3d/textureprimitive3d.hxx>
33 #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx>
34 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
35 #include <drawinglayer/primitive3d/shadowprimitive3d.hxx>
36 #include <basegfx/range/b2drange.hxx>
37 #include <drawinglayer/attribute/sdrlineattribute.hxx>
38 #include <drawinglayer/attribute/sdrobjectattribute3d.hxx>
39 #include <drawinglayer/attribute/sdrfillattribute.hxx>
40 #include <drawinglayer/attribute/sdrshadowattribute.hxx>
41 #include <drawinglayer/primitive3d/hiddengeometryprimitive3d.hxx>
44 namespace drawinglayer
46 namespace primitive3d
48 basegfx::B3DRange getRangeFrom3DGeometry(std::vector< basegfx::B3DPolyPolygon >& rFill)
50 basegfx::B3DRange aRetval;
52 for(const basegfx::B3DPolyPolygon & a : rFill)
54 aRetval.expand(basegfx::utils::getRange(a));
57 return aRetval;
60 void applyNormalsKindSphereTo3DGeometry(std::vector< basegfx::B3DPolyPolygon >& rFill, const basegfx::B3DRange& rRange)
62 // create sphere normals
63 const basegfx::B3DPoint aCenter(rRange.getCenter());
65 for(basegfx::B3DPolyPolygon & a : rFill)
67 a = basegfx::utils::applyDefaultNormalsSphere(a, aCenter);
71 void applyNormalsKindFlatTo3DGeometry(std::vector< basegfx::B3DPolyPolygon >& rFill)
73 for(basegfx::B3DPolyPolygon & a : rFill)
75 a.clearNormals();
79 void applyNormalsInvertTo3DGeometry(std::vector< basegfx::B3DPolyPolygon >& rFill)
81 // invert normals
82 for(basegfx::B3DPolyPolygon & a : rFill)
84 a = basegfx::utils::invertNormals(a);
88 void applyTextureTo3DGeometry(
89 css::drawing::TextureProjectionMode eModeX,
90 css::drawing::TextureProjectionMode eModeY,
91 std::vector< basegfx::B3DPolyPolygon >& rFill,
92 const basegfx::B3DRange& rRange,
93 const basegfx::B2DVector& rTextureSize)
95 // handle texture coordinates X
96 const bool bParallelX(css::drawing::TextureProjectionMode_PARALLEL == eModeX);
97 const bool bSphereX(!bParallelX && (css::drawing::TextureProjectionMode_SPHERE == eModeX));
99 // handle texture coordinates Y
100 const bool bParallelY(css::drawing::TextureProjectionMode_PARALLEL == eModeY);
101 const bool bSphereY(!bParallelY && (css::drawing::TextureProjectionMode_SPHERE == eModeY));
103 if(bParallelX || bParallelY)
105 // apply parallel texture coordinates in X and/or Y
106 for(auto & a: rFill)
108 a = basegfx::utils::applyDefaultTextureCoordinatesParallel(a, rRange, bParallelX, bParallelY);
112 if(bSphereX || bSphereY)
114 // apply spherical texture coordinates in X and/or Y
115 const basegfx::B3DPoint aCenter(rRange.getCenter());
117 for(auto & a: rFill)
119 a = basegfx::utils::applyDefaultTextureCoordinatesSphere(a, aCenter, bSphereX, bSphereY);
123 // transform texture coordinates to texture size
124 basegfx::B2DHomMatrix aTexMatrix;
125 aTexMatrix.scale(rTextureSize.getX(), rTextureSize.getY());
127 for(auto & a: rFill)
129 a.transformTextureCoordinates(aTexMatrix);
133 Primitive3DContainer create3DPolyPolygonLinePrimitives(
134 const basegfx::B3DPolyPolygon& rUnitPolyPolygon,
135 const basegfx::B3DHomMatrix& rObjectTransform,
136 const attribute::SdrLineAttribute& rLine)
138 // prepare fully scaled polyPolygon
139 basegfx::B3DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon);
140 aScaledPolyPolygon.transform(rObjectTransform);
142 // create line and stroke attribute
143 const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin(), rLine.getCap());
144 const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen());
146 // create primitives
147 Primitive3DContainer aRetval(aScaledPolyPolygon.count());
149 for(sal_uInt32 a(0); a < aScaledPolyPolygon.count(); a++)
151 const Primitive3DReference xRef(new PolygonStrokePrimitive3D(aScaledPolyPolygon.getB3DPolygon(a), aLineAttribute, aStrokeAttribute));
152 aRetval[a] = xRef;
155 if(0.0 != rLine.getTransparence())
157 // create UnifiedTransparenceTexturePrimitive3D, add created primitives and exchange
158 const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rLine.getTransparence(), aRetval));
159 aRetval = { xRef };
162 return aRetval;
165 Primitive3DContainer create3DPolyPolygonFillPrimitives(
166 const std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector,
167 const basegfx::B3DHomMatrix& rObjectTransform,
168 const basegfx::B2DVector& rTextureSize,
169 const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute,
170 const attribute::SdrFillAttribute& rFill,
171 const attribute::FillGradientAttribute& rFillGradient)
173 Primitive3DContainer aRetval;
175 if(!r3DPolyPolygonVector.empty())
177 // create list of simple fill primitives
178 aRetval.resize(r3DPolyPolygonVector.size());
180 for(size_t a(0); a < r3DPolyPolygonVector.size(); a++)
182 // get scaled PolyPolygon
183 basegfx::B3DPolyPolygon aScaledPolyPolygon(r3DPolyPolygonVector[a]);
184 aScaledPolyPolygon.transform(rObjectTransform);
186 if(aScaledPolyPolygon.areNormalsUsed())
188 aScaledPolyPolygon.transformNormals(rObjectTransform);
191 const Primitive3DReference xRef(new PolyPolygonMaterialPrimitive3D(
192 aScaledPolyPolygon,
193 aSdr3DObjectAttribute.getMaterial(),
194 aSdr3DObjectAttribute.getDoubleSided()));
195 aRetval[a] = xRef;
198 // look for and evtl. build texture sub-group primitive
199 if(!rFill.getGradient().isDefault()
200 || !rFill.getHatch().isDefault()
201 || !rFill.getFillGraphic().isDefault())
203 bool bModulate(css::drawing::TextureMode_MODULATE == aSdr3DObjectAttribute.getTextureMode());
204 bool bFilter(aSdr3DObjectAttribute.getTextureFilter());
205 BasePrimitive3D* pNewTexturePrimitive3D = nullptr;
207 if(!rFill.getGradient().isDefault())
209 // create gradientTexture3D with sublist, add to local aRetval
210 pNewTexturePrimitive3D = new GradientTexturePrimitive3D(
211 rFill.getGradient(),
212 aRetval,
213 rTextureSize,
214 bModulate,
215 bFilter);
217 else if(!rFill.getHatch().isDefault())
219 // create hatchTexture3D with sublist, add to local aRetval
220 pNewTexturePrimitive3D = new HatchTexturePrimitive3D(
221 rFill.getHatch(),
222 aRetval,
223 rTextureSize,
224 bModulate,
225 bFilter);
227 else // if(!rFill.getFillGraphic().isDefault())
229 // create bitmapTexture3D with sublist, add to local aRetval
230 const basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY());
232 pNewTexturePrimitive3D = new BitmapTexturePrimitive3D(
233 rFill.getFillGraphic().createFillGraphicAttribute(aTexRange),
234 aRetval,
235 rTextureSize,
236 bModulate,
237 bFilter);
240 // exchange aRetval content with texture group
241 const Primitive3DReference xRef(pNewTexturePrimitive3D);
242 aRetval = { xRef };
244 if(css::drawing::TextureKind2_LUMINANCE == aSdr3DObjectAttribute.getTextureKind())
246 // use modified color primitive to force textures to gray
247 const basegfx::BColorModifierSharedPtr aBColorModifier(
248 new basegfx::BColorModifier_gray());
249 const Primitive3DReference xRef2(
250 new ModifiedColorPrimitive3D(
251 aRetval,
252 aBColorModifier));
254 aRetval = { xRef2 };
258 if(0.0 != rFill.getTransparence())
260 // create UnifiedTransparenceTexturePrimitive3D with sublist and exchange
261 const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rFill.getTransparence(), aRetval));
262 aRetval = { xRef };
264 else if(!rFillGradient.isDefault())
266 // create TransparenceTexturePrimitive3D with sublist and exchange
267 const Primitive3DReference xRef(new TransparenceTexturePrimitive3D(rFillGradient, aRetval, rTextureSize));
268 aRetval = { xRef };
272 return aRetval;
275 Primitive3DContainer createShadowPrimitive3D(
276 const Primitive3DContainer& rSource,
277 const attribute::SdrShadowAttribute& rShadow,
278 bool bShadow3D)
280 // create Shadow primitives. Uses already created primitives
281 if(!rSource.empty() && !basegfx::fTools::moreOrEqual(rShadow.getTransparence(), 1.0))
283 // prepare new list for shadow geometry
284 basegfx::B2DHomMatrix aShadowOffset;
285 aShadowOffset.set(0, 2, rShadow.getOffset().getX());
286 aShadowOffset.set(1, 2, rShadow.getOffset().getY());
288 // create shadow primitive and add primitives
289 const Primitive3DReference xRef(new ShadowPrimitive3D(aShadowOffset, rShadow.getColor(), rShadow.getTransparence(), bShadow3D, rSource));
290 return { xRef };
292 else
294 return Primitive3DContainer();
298 Primitive3DContainer createHiddenGeometryPrimitives3D(
299 const std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector,
300 const basegfx::B3DHomMatrix& rObjectTransform,
301 const basegfx::B2DVector& rTextureSize,
302 const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute)
304 // create hidden sub-geometry which can be used for HitTest
305 // and BoundRect calculations, but will not be visualized
306 const attribute::SdrFillAttribute aSimplifiedFillAttribute(
307 0.0,
308 basegfx::BColor(),
309 attribute::FillGradientAttribute(),
310 attribute::FillHatchAttribute(),
311 attribute::SdrFillGraphicAttribute());
313 const Primitive3DReference aHidden(
314 new HiddenGeometryPrimitive3D(
315 create3DPolyPolygonFillPrimitives(
316 r3DPolyPolygonVector,
317 rObjectTransform,
318 rTextureSize,
319 aSdr3DObjectAttribute,
320 aSimplifiedFillAttribute,
321 attribute::FillGradientAttribute())));
323 return { aHidden };
326 } // end of namespace primitive3d
327 } // end of namespace drawinglayer
329 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */