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/fillbitmapattribute.hxx> 36 #include <drawinglayer/attribute/sdrfillbitmapattribute.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()); 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.getBitmap().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.getBitmap().isDefault()) 238 { 239 // create bitmapTexture3D with sublist, add to local aRetval 240 basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY()); 241 242 pNewTexturePrimitive3D = new BitmapTexturePrimitive3D( 243 rFill.getBitmap().getFillBitmapAttribute(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::SdrFillBitmapAttribute()); 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