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 { getRangeFrom3DGeometry(::std::vector<basegfx::B3DPolyPolygon> & rFill)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 applyNormalsKindSphereTo3DGeometry(::std::vector<basegfx::B3DPolyPolygon> & rFill,const basegfx::B3DRange & rRange)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 applyNormalsKindFlatTo3DGeometry(::std::vector<basegfx::B3DPolyPolygon> & rFill)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 applyNormalsInvertTo3DGeometry(::std::vector<basegfx::B3DPolyPolygon> & rFill)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 applyTextureTo3DGeometry(::com::sun::star::drawing::TextureProjectionMode eModeX,::com::sun::star::drawing::TextureProjectionMode eModeY,::std::vector<basegfx::B3DPolyPolygon> & rFill,const basegfx::B3DRange & rRange,const basegfx::B2DVector & rTextureSize)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 create3DPolyPolygonLinePrimitives(const basegfx::B3DPolyPolygon & rUnitPolyPolygon,const basegfx::B3DHomMatrix & rObjectTransform,const attribute::SdrLineAttribute & rLine)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 create3DPolyPolygonFillPrimitives(const::std::vector<basegfx::B3DPolyPolygon> & r3DPolyPolygonVector,const basegfx::B3DHomMatrix & rObjectTransform,const basegfx::B2DVector & rTextureSize,const attribute::Sdr3DObjectAttribute & aSdr3DObjectAttribute,const attribute::SdrFillAttribute & rFill,const attribute::FillGradientAttribute & rFillGradient)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::BColorModifierSharedPtr aBColorModifier( 258 new basegfx::BColorModifier_gray()); 259 const Primitive3DReference xRef2( 260 new ModifiedColorPrimitive3D( 261 aRetval, 262 aBColorModifier)); 263 264 aRetval = Primitive3DSequence(&xRef2, 1L); 265 } 266 } 267 268 if(0.0 != rFill.getTransparence()) 269 { 270 // create UnifiedTransparenceTexturePrimitive3D with sublist and exchange 271 const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rFill.getTransparence(), aRetval)); 272 aRetval = Primitive3DSequence(&xRef, 1L); 273 } 274 else if(!rFillGradient.isDefault()) 275 { 276 // create TransparenceTexturePrimitive3D with sublist and exchange 277 const Primitive3DReference xRef(new TransparenceTexturePrimitive3D(rFillGradient, aRetval, rTextureSize)); 278 aRetval = Primitive3DSequence(&xRef, 1L); 279 } 280 } 281 282 return aRetval; 283 } 284 createShadowPrimitive3D(const Primitive3DSequence & rSource,const attribute::SdrShadowAttribute & rShadow,bool bShadow3D)285 Primitive3DSequence createShadowPrimitive3D( 286 const Primitive3DSequence& rSource, 287 const attribute::SdrShadowAttribute& rShadow, 288 bool bShadow3D) 289 { 290 // create Shadow primitives. Uses already created primitives 291 if(rSource.hasElements() && !basegfx::fTools::moreOrEqual(rShadow.getTransparence(), 1.0)) 292 { 293 // prepare new list for shadow geometry 294 basegfx::B2DHomMatrix aShadowOffset; 295 aShadowOffset.set(0, 2, rShadow.getOffset().getX()); 296 aShadowOffset.set(1, 2, rShadow.getOffset().getY()); 297 298 // create shadow primitive and add primitives 299 const Primitive3DReference xRef(new ShadowPrimitive3D(aShadowOffset, rShadow.getColor(), rShadow.getTransparence(), bShadow3D, rSource)); 300 return Primitive3DSequence(&xRef, 1L); 301 } 302 else 303 { 304 return Primitive3DSequence(); 305 } 306 } 307 createHiddenGeometryPrimitives3D(const::std::vector<basegfx::B3DPolyPolygon> & r3DPolyPolygonVector,const basegfx::B3DHomMatrix & rObjectTransform,const basegfx::B2DVector & rTextureSize,const attribute::Sdr3DObjectAttribute & aSdr3DObjectAttribute)308 Primitive3DSequence createHiddenGeometryPrimitives3D( 309 const ::std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector, 310 const basegfx::B3DHomMatrix& rObjectTransform, 311 const basegfx::B2DVector& rTextureSize, 312 const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute) 313 { 314 // create hidden sub-geometry which can be used for HitTest 315 // and BoundRect calculations, but will not be visualized 316 const attribute::SdrFillAttribute aSimplifiedFillAttribute( 317 0.0, 318 basegfx::BColor(), 319 attribute::FillGradientAttribute(), 320 attribute::FillHatchAttribute(), 321 attribute::SdrFillGraphicAttribute()); 322 323 const Primitive3DReference aHidden( 324 new HiddenGeometryPrimitive3D( 325 create3DPolyPolygonFillPrimitives( 326 r3DPolyPolygonVector, 327 rObjectTransform, 328 rTextureSize, 329 aSdr3DObjectAttribute, 330 aSimplifiedFillAttribute, 331 attribute::FillGradientAttribute()))); 332 333 return Primitive3DSequence(&aHidden, 1); 334 } 335 336 } // end of namespace primitive3d 337 } // end of namespace drawinglayer 338 339 ////////////////////////////////////////////////////////////////////////////// 340 // eof 341