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/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/bmpacc.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>
42 :
43 :
44 :
45 : namespace drawinglayer
46 : {
47 : namespace primitive3d
48 : {
49 0 : basegfx::B3DRange getRangeFrom3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill)
50 : {
51 0 : basegfx::B3DRange aRetval;
52 :
53 0 : for(sal_uInt32 a(0); a < rFill.size(); a++)
54 : {
55 0 : aRetval.expand(basegfx::tools::getRange(rFill[a]));
56 : }
57 :
58 0 : return aRetval;
59 : }
60 :
61 0 : void applyNormalsKindSphereTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill, const basegfx::B3DRange& rRange)
62 : {
63 : // create sphere normals
64 0 : const basegfx::B3DPoint aCenter(rRange.getCenter());
65 :
66 0 : for(sal_uInt32 a(0); a < rFill.size(); a++)
67 : {
68 0 : rFill[a] = basegfx::tools::applyDefaultNormalsSphere(rFill[a], aCenter);
69 0 : }
70 0 : }
71 :
72 0 : void applyNormalsKindFlatTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill)
73 : {
74 0 : for(sal_uInt32 a(0); a < rFill.size(); a++)
75 : {
76 0 : rFill[a].clearNormals();
77 : }
78 0 : }
79 :
80 0 : void applyNormalsInvertTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill)
81 : {
82 : // invert normals
83 0 : for(sal_uInt32 a(0); a < rFill.size(); a++)
84 : {
85 0 : rFill[a] = basegfx::tools::invertNormals(rFill[a]);
86 : }
87 0 : }
88 :
89 0 : void applyTextureTo3DGeometry(
90 : ::com::sun::star::drawing::TextureProjectionMode eModeX,
91 : ::com::sun::star::drawing::TextureProjectionMode eModeY,
92 : ::std::vector< basegfx::B3DPolyPolygon >& rFill,
93 : const basegfx::B3DRange& rRange,
94 : const basegfx::B2DVector& rTextureSize)
95 : {
96 : sal_uInt32 a;
97 :
98 : // handle texture coordinates X
99 0 : const bool bParallelX(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == eModeX);
100 0 : const bool bSphereX(!bParallelX && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == eModeX));
101 :
102 : // handle texture coordinates Y
103 0 : const bool bParallelY(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == eModeY);
104 0 : const bool bSphereY(!bParallelY && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == eModeY));
105 :
106 0 : if(bParallelX || bParallelY)
107 : {
108 : // apply parallel texture coordinates in X and/or Y
109 0 : for(a = 0; a < rFill.size(); a++)
110 : {
111 0 : rFill[a] = basegfx::tools::applyDefaultTextureCoordinatesParallel(rFill[a], rRange, bParallelX, bParallelY);
112 : }
113 : }
114 :
115 0 : if(bSphereX || bSphereY)
116 : {
117 : // apply spherical texture coordinates in X and/or Y
118 0 : const basegfx::B3DPoint aCenter(rRange.getCenter());
119 :
120 0 : for(a = 0; a < rFill.size(); a++)
121 : {
122 0 : rFill[a] = basegfx::tools::applyDefaultTextureCoordinatesSphere(rFill[a], aCenter, bSphereX, bSphereY);
123 0 : }
124 : }
125 :
126 : // transform texture coordinates to texture size
127 0 : basegfx::B2DHomMatrix aTexMatrix;
128 0 : aTexMatrix.scale(rTextureSize.getX(), rTextureSize.getY());
129 :
130 0 : for(a = 0; a < rFill.size(); a++)
131 : {
132 0 : rFill[a].transformTextureCoordiantes(aTexMatrix);
133 0 : }
134 0 : }
135 :
136 0 : Primitive3DSequence create3DPolyPolygonLinePrimitives(
137 : const basegfx::B3DPolyPolygon& rUnitPolyPolygon,
138 : const basegfx::B3DHomMatrix& rObjectTransform,
139 : const attribute::SdrLineAttribute& rLine)
140 : {
141 : // prepare fully scaled polyPolygon
142 0 : basegfx::B3DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon);
143 0 : aScaledPolyPolygon.transform(rObjectTransform);
144 :
145 : // create line and stroke attribute
146 0 : const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin(), rLine.getCap());
147 0 : const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen());
148 :
149 : // create primitives
150 0 : Primitive3DSequence aRetval(aScaledPolyPolygon.count());
151 :
152 0 : for(sal_uInt32 a(0L); a < aScaledPolyPolygon.count(); a++)
153 : {
154 0 : const Primitive3DReference xRef(new PolygonStrokePrimitive3D(aScaledPolyPolygon.getB3DPolygon(a), aLineAttribute, aStrokeAttribute));
155 0 : aRetval[a] = xRef;
156 0 : }
157 :
158 0 : if(0.0 != rLine.getTransparence())
159 : {
160 : // create UnifiedTransparenceTexturePrimitive3D, add created primitives and exchange
161 0 : const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rLine.getTransparence(), aRetval));
162 0 : aRetval = Primitive3DSequence(&xRef, 1L);
163 : }
164 :
165 0 : return aRetval;
166 : }
167 :
168 0 : Primitive3DSequence create3DPolyPolygonFillPrimitives(
169 : const ::std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector,
170 : const basegfx::B3DHomMatrix& rObjectTransform,
171 : const basegfx::B2DVector& rTextureSize,
172 : const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute,
173 : const attribute::SdrFillAttribute& rFill,
174 : const attribute::FillGradientAttribute& rFillGradient)
175 : {
176 0 : Primitive3DSequence aRetval;
177 :
178 0 : if(r3DPolyPolygonVector.size())
179 : {
180 : // create list of simple fill primitives
181 0 : aRetval.realloc(r3DPolyPolygonVector.size());
182 :
183 0 : for(sal_uInt32 a(0L); a < r3DPolyPolygonVector.size(); a++)
184 : {
185 : // get scaled PolyPolygon
186 0 : basegfx::B3DPolyPolygon aScaledPolyPolygon(r3DPolyPolygonVector[a]);
187 0 : aScaledPolyPolygon.transform(rObjectTransform);
188 :
189 0 : if(aScaledPolyPolygon.areNormalsUsed())
190 : {
191 0 : aScaledPolyPolygon.transformNormals(rObjectTransform);
192 : }
193 :
194 : const Primitive3DReference xRef(new PolyPolygonMaterialPrimitive3D(
195 : aScaledPolyPolygon,
196 : aSdr3DObjectAttribute.getMaterial(),
197 0 : aSdr3DObjectAttribute.getDoubleSided()));
198 0 : aRetval[a] = xRef;
199 0 : }
200 :
201 : // look for and evtl. build texture sub-group primitive
202 0 : if(!rFill.getGradient().isDefault()
203 0 : || !rFill.getHatch().isDefault()
204 0 : || !rFill.getFillGraphic().isDefault())
205 : {
206 0 : bool bModulate(::com::sun::star::drawing::TextureMode_MODULATE == aSdr3DObjectAttribute.getTextureMode());
207 0 : bool bFilter(aSdr3DObjectAttribute.getTextureFilter());
208 0 : BasePrimitive3D* pNewTexturePrimitive3D = 0;
209 :
210 0 : if(!rFill.getGradient().isDefault())
211 : {
212 : // create gradientTexture3D with sublist, add to local aRetval
213 : pNewTexturePrimitive3D = new GradientTexturePrimitive3D(
214 : rFill.getGradient(),
215 : aRetval,
216 : rTextureSize,
217 : bModulate,
218 0 : bFilter);
219 : }
220 0 : else if(!rFill.getHatch().isDefault())
221 : {
222 : // create hatchTexture3D with sublist, add to local aRetval
223 : pNewTexturePrimitive3D = new HatchTexturePrimitive3D(
224 : rFill.getHatch(),
225 : aRetval,
226 : rTextureSize,
227 : bModulate,
228 0 : bFilter);
229 : }
230 : else // if(!rFill.getFillGraphic().isDefault())
231 : {
232 : // create bitmapTexture3D with sublist, add to local aRetval
233 0 : const basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY());
234 :
235 : pNewTexturePrimitive3D = new BitmapTexturePrimitive3D(
236 0 : rFill.getFillGraphic().createFillGraphicAttribute(aTexRange),
237 : aRetval,
238 : rTextureSize,
239 : bModulate,
240 0 : bFilter);
241 : }
242 :
243 : // exchange aRetval content with texture group
244 0 : const Primitive3DReference xRef(pNewTexturePrimitive3D);
245 0 : aRetval = Primitive3DSequence(&xRef, 1L);
246 :
247 0 : if(::com::sun::star::drawing::TextureKind2_LUMINANCE == aSdr3DObjectAttribute.getTextureKind())
248 : {
249 : // use modified color primitive to force textures to gray
250 : const basegfx::BColorModifierSharedPtr aBColorModifier(
251 0 : new basegfx::BColorModifier_gray());
252 : const Primitive3DReference xRef2(
253 : new ModifiedColorPrimitive3D(
254 : aRetval,
255 0 : aBColorModifier));
256 :
257 0 : aRetval = Primitive3DSequence(&xRef2, 1L);
258 0 : }
259 : }
260 :
261 0 : if(0.0 != rFill.getTransparence())
262 : {
263 : // create UnifiedTransparenceTexturePrimitive3D with sublist and exchange
264 0 : const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rFill.getTransparence(), aRetval));
265 0 : aRetval = Primitive3DSequence(&xRef, 1L);
266 : }
267 0 : else if(!rFillGradient.isDefault())
268 : {
269 : // create TransparenceTexturePrimitive3D with sublist and exchange
270 0 : const Primitive3DReference xRef(new TransparenceTexturePrimitive3D(rFillGradient, aRetval, rTextureSize));
271 0 : aRetval = Primitive3DSequence(&xRef, 1L);
272 : }
273 : }
274 :
275 0 : return aRetval;
276 : }
277 :
278 0 : Primitive3DSequence createShadowPrimitive3D(
279 : const Primitive3DSequence& rSource,
280 : const attribute::SdrShadowAttribute& rShadow,
281 : bool bShadow3D)
282 : {
283 : // create Shadow primitives. Uses already created primitives
284 0 : if(rSource.hasElements() && !basegfx::fTools::moreOrEqual(rShadow.getTransparence(), 1.0))
285 : {
286 : // prepare new list for shadow geometry
287 0 : basegfx::B2DHomMatrix aShadowOffset;
288 0 : aShadowOffset.set(0, 2, rShadow.getOffset().getX());
289 0 : aShadowOffset.set(1, 2, rShadow.getOffset().getY());
290 :
291 : // create shadow primitive and add primitives
292 0 : const Primitive3DReference xRef(new ShadowPrimitive3D(aShadowOffset, rShadow.getColor(), rShadow.getTransparence(), bShadow3D, rSource));
293 0 : return Primitive3DSequence(&xRef, 1L);
294 : }
295 : else
296 : {
297 0 : return Primitive3DSequence();
298 : }
299 : }
300 :
301 0 : Primitive3DSequence createHiddenGeometryPrimitives3D(
302 : const ::std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector,
303 : const basegfx::B3DHomMatrix& rObjectTransform,
304 : const basegfx::B2DVector& rTextureSize,
305 : const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute)
306 : {
307 : // create hidden sub-geometry which can be used for HitTest
308 : // and BoundRect calculations, but will not be visualized
309 : const attribute::SdrFillAttribute aSimplifiedFillAttribute(
310 : 0.0,
311 : basegfx::BColor(),
312 : attribute::FillGradientAttribute(),
313 : attribute::FillHatchAttribute(),
314 0 : attribute::SdrFillGraphicAttribute());
315 :
316 : const Primitive3DReference aHidden(
317 : new HiddenGeometryPrimitive3D(
318 : create3DPolyPolygonFillPrimitives(
319 : r3DPolyPolygonVector,
320 : rObjectTransform,
321 : rTextureSize,
322 : aSdr3DObjectAttribute,
323 : aSimplifiedFillAttribute,
324 0 : attribute::FillGradientAttribute())));
325 :
326 0 : return Primitive3DSequence(&aHidden, 1);
327 : }
328 :
329 : } // end of namespace primitive3d
330 : } // end of namespace drawinglayer
331 :
332 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|