1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <primitive3d/sdrdecompositiontools3d.hxx>
21 #include <drawinglayer/attribute/strokeattribute.hxx>
22 #include <drawinglayer/primitive3d/baseprimitive3d.hxx>
23 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
24 #include <basegfx/polygon/b3dpolypolygon.hxx>
25 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
26 #include <drawinglayer/attribute/fillgraphicattribute.hxx>
27 #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
28 #include <basegfx/polygon/b3dpolypolygontools.hxx>
29 #include <primitive3d/textureprimitive3d.hxx>
30 #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx>
31 #include <primitive3d/hatchtextureprimitive3d.hxx>
32 #include <primitive3d/shadowprimitive3d.hxx>
33 #include <basegfx/range/b2drange.hxx>
34 #include <drawinglayer/attribute/sdrlineattribute.hxx>
35 #include <drawinglayer/attribute/sdrobjectattribute3d.hxx>
36 #include <drawinglayer/attribute/sdrfillattribute.hxx>
37 #include <drawinglayer/attribute/sdrshadowattribute.hxx>
38 #include <primitive3d/hiddengeometryprimitive3d.hxx>
39 #include <rtl/ref.hxx>
42 namespace drawinglayer::primitive3d
44 basegfx::B3DRange
getRangeFrom3DGeometry(std::vector
< basegfx::B3DPolyPolygon
>& rFill
)
46 basegfx::B3DRange aRetval
;
48 for(const basegfx::B3DPolyPolygon
& a
: rFill
)
50 aRetval
.expand(basegfx::utils::getRange(a
));
56 void applyNormalsKindSphereTo3DGeometry(std::vector
< basegfx::B3DPolyPolygon
>& rFill
, const basegfx::B3DRange
& rRange
)
58 // create sphere normals
59 const basegfx::B3DPoint
aCenter(rRange
.getCenter());
61 for(basegfx::B3DPolyPolygon
& a
: rFill
)
63 a
= basegfx::utils::applyDefaultNormalsSphere(a
, aCenter
);
67 void applyNormalsKindFlatTo3DGeometry(std::vector
< basegfx::B3DPolyPolygon
>& rFill
)
69 for(basegfx::B3DPolyPolygon
& a
: rFill
)
75 void applyNormalsInvertTo3DGeometry(std::vector
< basegfx::B3DPolyPolygon
>& rFill
)
78 for(basegfx::B3DPolyPolygon
& a
: rFill
)
80 a
= basegfx::utils::invertNormals(a
);
84 void applyTextureTo3DGeometry(
85 css::drawing::TextureProjectionMode eModeX
,
86 css::drawing::TextureProjectionMode eModeY
,
87 std::vector
< basegfx::B3DPolyPolygon
>& rFill
,
88 const basegfx::B3DRange
& rRange
,
89 const basegfx::B2DVector
& rTextureSize
)
91 // handle texture coordinates X
92 const bool bParallelX(css::drawing::TextureProjectionMode_PARALLEL
== eModeX
);
93 const bool bSphereX(!bParallelX
&& (css::drawing::TextureProjectionMode_SPHERE
== eModeX
));
95 // handle texture coordinates Y
96 const bool bParallelY(css::drawing::TextureProjectionMode_PARALLEL
== eModeY
);
97 const bool bSphereY(!bParallelY
&& (css::drawing::TextureProjectionMode_SPHERE
== eModeY
));
99 if(bParallelX
|| bParallelY
)
101 // apply parallel texture coordinates in X and/or Y
104 a
= basegfx::utils::applyDefaultTextureCoordinatesParallel(a
, rRange
, bParallelX
, bParallelY
);
108 if(bSphereX
|| bSphereY
)
110 // apply spherical texture coordinates in X and/or Y
111 const basegfx::B3DPoint
aCenter(rRange
.getCenter());
115 a
= basegfx::utils::applyDefaultTextureCoordinatesSphere(a
, aCenter
, bSphereX
, bSphereY
);
119 // transform texture coordinates to texture size
120 basegfx::B2DHomMatrix aTexMatrix
;
121 aTexMatrix
.scale(rTextureSize
.getX(), rTextureSize
.getY());
125 a
.transformTextureCoordinates(aTexMatrix
);
129 Primitive3DContainer
create3DPolyPolygonLinePrimitives(
130 const basegfx::B3DPolyPolygon
& rUnitPolyPolygon
,
131 const basegfx::B3DHomMatrix
& rObjectTransform
,
132 const attribute::SdrLineAttribute
& rLine
)
134 // prepare fully scaled polyPolygon
135 basegfx::B3DPolyPolygon
aScaledPolyPolygon(rUnitPolyPolygon
);
136 aScaledPolyPolygon
.transform(rObjectTransform
);
138 // create line and stroke attribute
139 const attribute::LineAttribute
aLineAttribute(rLine
.getColor(), rLine
.getWidth(), rLine
.getJoin(), rLine
.getCap());
140 const attribute::StrokeAttribute
aStrokeAttribute(std::vector(rLine
.getDotDashArray()), rLine
.getFullDotDashLen());
143 Primitive3DContainer
aRetval(aScaledPolyPolygon
.count());
145 for(sal_uInt32
a(0); a
< aScaledPolyPolygon
.count(); a
++)
147 aRetval
[a
] = new PolygonStrokePrimitive3D(aScaledPolyPolygon
.getB3DPolygon(a
), aLineAttribute
, aStrokeAttribute
);
150 if(0.0 != rLine
.getTransparence())
152 // create UnifiedTransparenceTexturePrimitive3D, add created primitives and exchange
153 const Primitive3DReference
xRef(new UnifiedTransparenceTexturePrimitive3D(rLine
.getTransparence(), aRetval
));
160 Primitive3DContainer
create3DPolyPolygonFillPrimitives(
161 const std::vector
< basegfx::B3DPolyPolygon
>& r3DPolyPolygonVector
,
162 const basegfx::B3DHomMatrix
& rObjectTransform
,
163 const basegfx::B2DVector
& rTextureSize
,
164 const attribute::Sdr3DObjectAttribute
& aSdr3DObjectAttribute
,
165 const attribute::SdrFillAttribute
& rFill
,
166 const attribute::FillGradientAttribute
& rFillGradient
)
168 Primitive3DContainer aRetval
;
170 if(!r3DPolyPolygonVector
.empty())
172 // create list of simple fill primitives
173 aRetval
.resize(r3DPolyPolygonVector
.size());
175 for(size_t a(0); a
< r3DPolyPolygonVector
.size(); a
++)
177 // get scaled PolyPolygon
178 basegfx::B3DPolyPolygon
aScaledPolyPolygon(r3DPolyPolygonVector
[a
]);
179 aScaledPolyPolygon
.transform(rObjectTransform
);
181 if(aScaledPolyPolygon
.areNormalsUsed())
183 aScaledPolyPolygon
.transformNormals(rObjectTransform
);
186 const Primitive3DReference
xRef(new PolyPolygonMaterialPrimitive3D(
187 std::move(aScaledPolyPolygon
),
188 aSdr3DObjectAttribute
.getMaterial(),
189 aSdr3DObjectAttribute
.getDoubleSided()));
193 // look for and evtl. build texture sub-group primitive
194 if(!rFill
.getGradient().isDefault()
195 || !rFill
.getHatch().isDefault()
196 || !rFill
.getFillGraphic().isDefault())
198 bool bModulate(css::drawing::TextureMode_MODULATE
== aSdr3DObjectAttribute
.getTextureMode());
199 bool bFilter(aSdr3DObjectAttribute
.getTextureFilter());
200 rtl::Reference
<BasePrimitive3D
> pNewTexturePrimitive3D
;
202 if(!rFill
.getGradient().isDefault())
204 // create gradientTexture3D with sublist, add to local aRetval
205 pNewTexturePrimitive3D
= new GradientTexturePrimitive3D(
212 else if(!rFill
.getHatch().isDefault())
214 // create hatchTexture3D with sublist, add to local aRetval
215 pNewTexturePrimitive3D
= new HatchTexturePrimitive3D(
222 else // if(!rFill.getFillGraphic().isDefault())
224 // create bitmapTexture3D with sublist, add to local aRetval
225 const basegfx::B2DRange
aTexRange(0.0, 0.0, rTextureSize
.getX(), rTextureSize
.getY());
227 pNewTexturePrimitive3D
= new BitmapTexturePrimitive3D(
228 rFill
.getFillGraphic().createFillGraphicAttribute(aTexRange
),
235 // exchange aRetval content with texture group
236 const Primitive3DReference
xRef(pNewTexturePrimitive3D
);
239 if(css::drawing::TextureKind2_LUMINANCE
== aSdr3DObjectAttribute
.getTextureKind())
241 // use modified color primitive to force textures to gray
242 const basegfx::BColorModifierSharedPtr aBColorModifier
=
243 std::make_shared
<basegfx::BColorModifier_gray
>();
244 const Primitive3DReference
xRef2(
245 new ModifiedColorPrimitive3D(
253 if(0.0 != rFill
.getTransparence())
255 // create UnifiedTransparenceTexturePrimitive3D with sublist and exchange
256 const Primitive3DReference
xRef(new UnifiedTransparenceTexturePrimitive3D(rFill
.getTransparence(), aRetval
));
259 else if(!rFillGradient
.isDefault())
261 // create TransparenceTexturePrimitive3D with sublist and exchange
262 const Primitive3DReference
xRef(new TransparenceTexturePrimitive3D(rFillGradient
, aRetval
, rTextureSize
));
270 Primitive3DContainer
createShadowPrimitive3D(
271 const Primitive3DContainer
& rSource
,
272 const attribute::SdrShadowAttribute
& rShadow
,
275 // create Shadow primitives. Uses already created primitives
276 if(!rSource
.empty() && !basegfx::fTools::moreOrEqual(rShadow
.getTransparence(), 1.0))
278 // prepare new list for shadow geometry
279 basegfx::B2DHomMatrix aShadowOffset
;
280 aShadowOffset
.set(0, 2, rShadow
.getOffset().getX());
281 aShadowOffset
.set(1, 2, rShadow
.getOffset().getY());
283 // create shadow primitive and add primitives
284 const Primitive3DReference
xRef(new ShadowPrimitive3D(aShadowOffset
, rShadow
.getColor(), rShadow
.getTransparence(), bShadow3D
, rSource
));
289 return Primitive3DContainer();
293 Primitive3DContainer
createHiddenGeometryPrimitives3D(
294 const std::vector
< basegfx::B3DPolyPolygon
>& r3DPolyPolygonVector
,
295 const basegfx::B3DHomMatrix
& rObjectTransform
,
296 const basegfx::B2DVector
& rTextureSize
,
297 const attribute::Sdr3DObjectAttribute
& aSdr3DObjectAttribute
)
299 // create hidden sub-geometry which can be used for HitTest
300 // and BoundRect calculations, but will not be visualized
301 const attribute::SdrFillAttribute
aSimplifiedFillAttribute(
304 attribute::FillGradientAttribute(),
305 attribute::FillHatchAttribute(),
306 attribute::SdrFillGraphicAttribute());
308 const Primitive3DReference
aHidden(
309 new HiddenGeometryPrimitive3D(
310 create3DPolyPolygonFillPrimitives(
311 r3DPolyPolygonVector
,
314 aSdr3DObjectAttribute
,
315 aSimplifiedFillAttribute
,
316 attribute::FillGradientAttribute())));
321 } // end of namespace
323 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */