xref: /AOO41X/main/drawinglayer/source/primitive3d/sdrdecompositiontools3d.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_drawinglayer.hxx"
26 
27 #include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx>
28 #include <basegfx/polygon/b3dpolygon.hxx>
29 #include <drawinglayer/attribute/strokeattribute.hxx>
30 #include <drawinglayer/primitive3d/baseprimitive3d.hxx>
31 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
32 #include <basegfx/polygon/b3dpolypolygon.hxx>
33 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
34 #include <vcl/vclenum.hxx>
35 #include <drawinglayer/attribute/fillgraphicattribute.hxx>
36 #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
37 #include <vcl/bmpacc.hxx>
38 #include <basegfx/polygon/b3dpolypolygontools.hxx>
39 #include <drawinglayer/primitive3d/textureprimitive3d.hxx>
40 #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx>
41 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
42 #include <drawinglayer/primitive3d/shadowprimitive3d.hxx>
43 #include <basegfx/range/b2drange.hxx>
44 #include <drawinglayer/attribute/sdrlineattribute.hxx>
45 #include <drawinglayer/attribute/sdrobjectattribute3d.hxx>
46 #include <drawinglayer/attribute/sdrfillattribute.hxx>
47 #include <drawinglayer/attribute/sdrshadowattribute.hxx>
48 #include <drawinglayer/primitive3d/hiddengeometryprimitive3d.hxx>
49 
50 //////////////////////////////////////////////////////////////////////////////
51 
52 namespace drawinglayer
53 {
54     namespace primitive3d
55     {
56         basegfx::B3DRange getRangeFrom3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill)
57         {
58             basegfx::B3DRange aRetval;
59 
60             for(sal_uInt32 a(0); a < rFill.size(); a++)
61             {
62                 aRetval.expand(basegfx::tools::getRange(rFill[a]));
63             }
64 
65             return aRetval;
66         }
67 
68         void applyNormalsKindSphereTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill, const basegfx::B3DRange& rRange)
69         {
70             // create sphere normals
71             const basegfx::B3DPoint aCenter(rRange.getCenter());
72 
73             for(sal_uInt32 a(0); a < rFill.size(); a++)
74             {
75                 rFill[a] = basegfx::tools::applyDefaultNormalsSphere(rFill[a], aCenter);
76             }
77         }
78 
79         void applyNormalsKindFlatTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill)
80         {
81             for(sal_uInt32 a(0); a < rFill.size(); a++)
82             {
83                 rFill[a].clearNormals();
84             }
85         }
86 
87         void applyNormalsInvertTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill)
88         {
89             // invert normals
90             for(sal_uInt32 a(0); a < rFill.size(); a++)
91             {
92                 rFill[a] = basegfx::tools::invertNormals(rFill[a]);
93             }
94         }
95 
96         void applyTextureTo3DGeometry(
97             ::com::sun::star::drawing::TextureProjectionMode eModeX,
98             ::com::sun::star::drawing::TextureProjectionMode eModeY,
99             ::std::vector< basegfx::B3DPolyPolygon >& rFill,
100             const basegfx::B3DRange& rRange,
101             const basegfx::B2DVector& rTextureSize)
102         {
103             sal_uInt32 a;
104 
105             // handle texture coordinates X
106             const bool bParallelX(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == eModeX);
107             const bool bSphereX(!bParallelX && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == eModeX));
108 
109             // handle texture coordinates Y
110             const bool bParallelY(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == eModeY);
111             const bool bSphereY(!bParallelY && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == eModeY));
112 
113             if(bParallelX || bParallelY)
114             {
115                 // apply parallel texture coordinates in X and/or Y
116                 for(a = 0; a < rFill.size(); a++)
117                 {
118                     rFill[a] = basegfx::tools::applyDefaultTextureCoordinatesParallel(rFill[a], rRange, bParallelX, bParallelY);
119                 }
120             }
121 
122             if(bSphereX || bSphereY)
123             {
124                 // apply spherical texture coordinates in X and/or Y
125                 const basegfx::B3DPoint aCenter(rRange.getCenter());
126 
127                 for(a = 0; a < rFill.size(); a++)
128                 {
129                     rFill[a] = basegfx::tools::applyDefaultTextureCoordinatesSphere(rFill[a], aCenter, bSphereX, bSphereY);
130                 }
131             }
132 
133             // transform texture coordinates to texture size
134             basegfx::B2DHomMatrix aTexMatrix;
135             aTexMatrix.scale(rTextureSize.getX(), rTextureSize.getY());
136 
137             for(a = 0; a < rFill.size(); a++)
138             {
139                 rFill[a].transformTextureCoordiantes(aTexMatrix);
140             }
141         }
142 
143         Primitive3DSequence create3DPolyPolygonLinePrimitives(
144             const basegfx::B3DPolyPolygon& rUnitPolyPolygon,
145             const basegfx::B3DHomMatrix& rObjectTransform,
146             const attribute::SdrLineAttribute& rLine)
147         {
148             // prepare fully scaled polyPolygon
149             basegfx::B3DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon);
150             aScaledPolyPolygon.transform(rObjectTransform);
151 
152             // create line and stroke attribute
153             const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin(), rLine.getCap());
154             const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen());
155 
156             // create primitives
157             Primitive3DSequence aRetval(aScaledPolyPolygon.count());
158 
159             for(sal_uInt32 a(0L); a < aScaledPolyPolygon.count(); a++)
160             {
161                 const Primitive3DReference xRef(new PolygonStrokePrimitive3D(aScaledPolyPolygon.getB3DPolygon(a), aLineAttribute, aStrokeAttribute));
162                 aRetval[a] = xRef;
163             }
164 
165             if(0.0 != rLine.getTransparence())
166             {
167                 // create UnifiedTransparenceTexturePrimitive3D, add created primitives and exchange
168                 const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rLine.getTransparence(), aRetval));
169                 aRetval = Primitive3DSequence(&xRef, 1L);
170             }
171 
172             return aRetval;
173         }
174 
175         Primitive3DSequence create3DPolyPolygonFillPrimitives(
176             const ::std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector,
177             const basegfx::B3DHomMatrix& rObjectTransform,
178             const basegfx::B2DVector& rTextureSize,
179             const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute,
180             const attribute::SdrFillAttribute& rFill,
181             const attribute::FillGradientAttribute& rFillGradient)
182         {
183             Primitive3DSequence aRetval;
184 
185             if(r3DPolyPolygonVector.size())
186             {
187                 // create list of simple fill primitives
188                 aRetval.realloc(r3DPolyPolygonVector.size());
189 
190                 for(sal_uInt32 a(0L); a < r3DPolyPolygonVector.size(); a++)
191                 {
192                     // get scaled PolyPolygon
193                     basegfx::B3DPolyPolygon aScaledPolyPolygon(r3DPolyPolygonVector[a]);
194                     aScaledPolyPolygon.transform(rObjectTransform);
195 
196                     if(aScaledPolyPolygon.areNormalsUsed())
197                     {
198                         aScaledPolyPolygon.transformNormals(rObjectTransform);
199                     }
200 
201                     const Primitive3DReference xRef(new PolyPolygonMaterialPrimitive3D(
202                         aScaledPolyPolygon,
203                         aSdr3DObjectAttribute.getMaterial(),
204                         aSdr3DObjectAttribute.getDoubleSided()));
205                     aRetval[a] = xRef;
206                 }
207 
208                 // look for and evtl. build texture sub-group primitive
209                 if(!rFill.getGradient().isDefault()
210                     || !rFill.getHatch().isDefault()
211                     || !rFill.getFillGraphic().isDefault())
212                 {
213                     bool bModulate(::com::sun::star::drawing::TextureMode_MODULATE == aSdr3DObjectAttribute.getTextureMode());
214                     bool bFilter(aSdr3DObjectAttribute.getTextureFilter());
215                     BasePrimitive3D* pNewTexturePrimitive3D = 0;
216 
217                     if(!rFill.getGradient().isDefault())
218                     {
219                         // create gradientTexture3D with sublist, add to local aRetval
220                         pNewTexturePrimitive3D = new GradientTexturePrimitive3D(
221                             rFill.getGradient(),
222                             aRetval,
223                             rTextureSize,
224                             bModulate,
225                             bFilter);
226                     }
227                     else if(!rFill.getHatch().isDefault())
228                     {
229                         // create hatchTexture3D with sublist, add to local aRetval
230                         pNewTexturePrimitive3D = new HatchTexturePrimitive3D(
231                             rFill.getHatch(),
232                             aRetval,
233                             rTextureSize,
234                             bModulate,
235                             bFilter);
236                     }
237                     else // if(!rFill.getFillGraphic().isDefault())
238                     {
239                         // create bitmapTexture3D with sublist, add to local aRetval
240                         const basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY());
241 
242                         pNewTexturePrimitive3D = new BitmapTexturePrimitive3D(
243                             rFill.getFillGraphic().createFillGraphicAttribute(aTexRange),
244                             aRetval,
245                             rTextureSize,
246                             bModulate,
247                             bFilter);
248                     }
249 
250                     // exchange aRetval content with texture group
251                     const Primitive3DReference xRef(pNewTexturePrimitive3D);
252                     aRetval = Primitive3DSequence(&xRef, 1L);
253 
254                     if(::com::sun::star::drawing::TextureKind2_LUMINANCE == aSdr3DObjectAttribute.getTextureKind())
255                     {
256                         // use modified color primitive to force textures to gray
257                         const basegfx::BColorModifier aBColorModifier(basegfx::BColor(), 0.0, basegfx::BCOLORMODIFYMODE_GRAY);
258                         const Primitive3DReference xRef2(new ModifiedColorPrimitive3D(aRetval, aBColorModifier));
259                         aRetval = Primitive3DSequence(&xRef2, 1L);
260                     }
261                 }
262 
263                 if(0.0 != rFill.getTransparence())
264                 {
265                     // create UnifiedTransparenceTexturePrimitive3D with sublist and exchange
266                     const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rFill.getTransparence(), aRetval));
267                     aRetval = Primitive3DSequence(&xRef, 1L);
268                 }
269                 else if(!rFillGradient.isDefault())
270                 {
271                     // create TransparenceTexturePrimitive3D with sublist and exchange
272                     const Primitive3DReference xRef(new TransparenceTexturePrimitive3D(rFillGradient, aRetval, rTextureSize));
273                     aRetval = Primitive3DSequence(&xRef, 1L);
274                 }
275             }
276 
277             return aRetval;
278         }
279 
280         Primitive3DSequence createShadowPrimitive3D(
281             const Primitive3DSequence& rSource,
282             const attribute::SdrShadowAttribute& rShadow,
283             bool bShadow3D)
284         {
285             // create Shadow primitives. Uses already created primitives
286             if(rSource.hasElements() && !basegfx::fTools::moreOrEqual(rShadow.getTransparence(), 1.0))
287             {
288                 // prepare new list for shadow geometry
289                 basegfx::B2DHomMatrix aShadowOffset;
290                 aShadowOffset.set(0, 2, rShadow.getOffset().getX());
291                 aShadowOffset.set(1, 2, rShadow.getOffset().getY());
292 
293                 // create shadow primitive and add primitives
294                 const Primitive3DReference xRef(new ShadowPrimitive3D(aShadowOffset, rShadow.getColor(), rShadow.getTransparence(), bShadow3D, rSource));
295                 return Primitive3DSequence(&xRef, 1L);
296             }
297             else
298             {
299                 return Primitive3DSequence();
300             }
301         }
302 
303         Primitive3DSequence createHiddenGeometryPrimitives3D(
304             const ::std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector,
305             const basegfx::B3DHomMatrix& rObjectTransform,
306             const basegfx::B2DVector& rTextureSize,
307             const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute)
308         {
309             // create hidden sub-geometry which can be used for HitTest
310             // and BoundRect calculations, but will not be visualized
311             const attribute::SdrFillAttribute aSimplifiedFillAttribute(
312                 0.0,
313                 basegfx::BColor(),
314                 attribute::FillGradientAttribute(),
315                 attribute::FillHatchAttribute(),
316                 attribute::SdrFillGraphicAttribute());
317 
318             const Primitive3DReference aHidden(
319                 new HiddenGeometryPrimitive3D(
320                     create3DPolyPolygonFillPrimitives(
321                         r3DPolyPolygonVector,
322                         rObjectTransform,
323                         rTextureSize,
324                         aSdr3DObjectAttribute,
325                         aSimplifiedFillAttribute,
326                         attribute::FillGradientAttribute())));
327 
328             return Primitive3DSequence(&aHidden, 1);
329         }
330 
331     } // end of namespace primitive3d
332 } // end of namespace drawinglayer
333 
334 //////////////////////////////////////////////////////////////////////////////
335 // eof
336