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/sdrcubeprimitive3d.hxx> 28 #include <basegfx/polygon/b3dpolypolygontools.hxx> 29 #include <basegfx/polygon/b3dpolygon.hxx> 30 #include <basegfx/matrix/b2dhommatrix.hxx> 31 #include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx> 32 #include <basegfx/tools/canvastools.hxx> 33 #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> 34 #include <drawinglayer/attribute/sdrfillattribute.hxx> 35 #include <drawinglayer/attribute/sdrlineattribute.hxx> 36 #include <drawinglayer/attribute/sdrshadowattribute.hxx> 37 38 ////////////////////////////////////////////////////////////////////////////// 39 40 using namespace com::sun::star; 41 42 ////////////////////////////////////////////////////////////////////////////// 43 44 namespace drawinglayer 45 { 46 namespace primitive3d 47 { create3DDecomposition(const geometry::ViewInformation3D &) const48 Primitive3DSequence SdrCubePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const 49 { 50 const basegfx::B3DRange aUnitRange(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); 51 Primitive3DSequence aRetval; 52 basegfx::B3DPolyPolygon aFill(basegfx::tools::createCubeFillPolyPolygonFromB3DRange(aUnitRange)); 53 54 // normal creation 55 if(!getSdrLFSAttribute().getFill().isDefault()) 56 { 57 if(::com::sun::star::drawing::NormalsKind_SPECIFIC == getSdr3DObjectAttribute().getNormalsKind() 58 || ::com::sun::star::drawing::NormalsKind_SPHERE == getSdr3DObjectAttribute().getNormalsKind()) 59 { 60 // create sphere normals 61 const basegfx::B3DPoint aCenter(basegfx::tools::getRange(aFill).getCenter()); 62 aFill = basegfx::tools::applyDefaultNormalsSphere(aFill, aCenter); 63 } 64 65 if(getSdr3DObjectAttribute().getNormalsInvert()) 66 { 67 // invert normals 68 aFill = basegfx::tools::invertNormals(aFill); 69 } 70 } 71 72 // texture coordinates 73 if(!getSdrLFSAttribute().getFill().isDefault()) 74 { 75 // handle texture coordinates X 76 const bool bParallelX(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == getSdr3DObjectAttribute().getTextureProjectionX()); 77 const bool bObjectSpecificX(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionX()); 78 const bool bSphereX(!bParallelX && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == getSdr3DObjectAttribute().getTextureProjectionX())); 79 80 // handle texture coordinates Y 81 const bool bParallelY(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == getSdr3DObjectAttribute().getTextureProjectionY()); 82 const bool bObjectSpecificY(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionY()); 83 const bool bSphereY(!bParallelY && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == getSdr3DObjectAttribute().getTextureProjectionY())); 84 85 if(bParallelX || bParallelY) 86 { 87 // apply parallel texture coordinates in X and/or Y 88 const basegfx::B3DRange aRange(basegfx::tools::getRange(aFill)); 89 aFill = basegfx::tools::applyDefaultTextureCoordinatesParallel(aFill, aRange, bParallelX, bParallelY); 90 } 91 92 if(bSphereX || bSphereY) 93 { 94 // apply spherical texture coordinates in X and/or Y 95 const basegfx::B3DRange aRange(basegfx::tools::getRange(aFill)); 96 const basegfx::B3DPoint aCenter(aRange.getCenter()); 97 aFill = basegfx::tools::applyDefaultTextureCoordinatesSphere(aFill, aCenter, bSphereX, bSphereY); 98 } 99 100 if(bObjectSpecificX || bObjectSpecificY) 101 { 102 // object-specific 103 for(sal_uInt32 a(0L); a < aFill.count(); a++) 104 { 105 basegfx::B3DPolygon aTmpPoly(aFill.getB3DPolygon(a)); 106 107 if(aTmpPoly.count() >= 4L) 108 { 109 for(sal_uInt32 b(0L); b < 4L; b++) 110 { 111 basegfx::B2DPoint aPoint(aTmpPoly.getTextureCoordinate(b)); 112 113 if(bObjectSpecificX) 114 { 115 aPoint.setX((1L == b || 2L == b) ? 1.0 : 0.0); 116 } 117 118 if(bObjectSpecificY) 119 { 120 aPoint.setY((2L == b || 3L == b) ? 1.0 : 0.0); 121 } 122 123 aTmpPoly.setTextureCoordinate(b, aPoint); 124 } 125 126 aFill.setB3DPolygon(a, aTmpPoly); 127 } 128 } 129 } 130 131 // transform texture coordinates to texture size 132 basegfx::B2DHomMatrix aTexMatrix; 133 aTexMatrix.scale(getTextureSize().getX(), getTextureSize().getY()); 134 aFill.transformTextureCoordiantes(aTexMatrix); 135 } 136 137 // build vector of PolyPolygons 138 ::std::vector< basegfx::B3DPolyPolygon > a3DPolyPolygonVector; 139 140 for(sal_uInt32 a(0L); a < aFill.count(); a++) 141 { 142 a3DPolyPolygonVector.push_back(basegfx::B3DPolyPolygon(aFill.getB3DPolygon(a))); 143 } 144 145 if(!getSdrLFSAttribute().getFill().isDefault()) 146 { 147 // add fill 148 aRetval = create3DPolyPolygonFillPrimitives( 149 a3DPolyPolygonVector, 150 getTransform(), 151 getTextureSize(), 152 getSdr3DObjectAttribute(), 153 getSdrLFSAttribute().getFill(), 154 getSdrLFSAttribute().getFillFloatTransGradient()); 155 } 156 else 157 { 158 // create simplified 3d hit test geometry 159 aRetval = createHiddenGeometryPrimitives3D( 160 a3DPolyPolygonVector, 161 getTransform(), 162 getTextureSize(), 163 getSdr3DObjectAttribute()); 164 } 165 166 // add line 167 if(!getSdrLFSAttribute().getLine().isDefault()) 168 { 169 basegfx::B3DPolyPolygon aLine(basegfx::tools::createCubePolyPolygonFromB3DRange(aUnitRange)); 170 const Primitive3DSequence aLines(create3DPolyPolygonLinePrimitives( 171 aLine, getTransform(), getSdrLFSAttribute().getLine())); 172 appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aLines); 173 } 174 175 // add shadow 176 if(!getSdrLFSAttribute().getShadow().isDefault() && aRetval.hasElements()) 177 { 178 const Primitive3DSequence aShadow(createShadowPrimitive3D( 179 aRetval, getSdrLFSAttribute().getShadow(), getSdr3DObjectAttribute().getShadow3D())); 180 appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aShadow); 181 } 182 183 return aRetval; 184 } 185 SdrCubePrimitive3D(const basegfx::B3DHomMatrix & rTransform,const basegfx::B2DVector & rTextureSize,const attribute::SdrLineFillShadowAttribute3D & rSdrLFSAttribute,const attribute::Sdr3DObjectAttribute & rSdr3DObjectAttribute)186 SdrCubePrimitive3D::SdrCubePrimitive3D( 187 const basegfx::B3DHomMatrix& rTransform, 188 const basegfx::B2DVector& rTextureSize, 189 const attribute::SdrLineFillShadowAttribute3D& rSdrLFSAttribute, 190 const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute) 191 : SdrPrimitive3D(rTransform, rTextureSize, rSdrLFSAttribute, rSdr3DObjectAttribute) 192 { 193 } 194 operator ==(const BasePrimitive3D & rPrimitive) const195 bool SdrCubePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const 196 { 197 return SdrPrimitive3D::operator==(rPrimitive); 198 } 199 getB3DRange(const geometry::ViewInformation3D &) const200 basegfx::B3DRange SdrCubePrimitive3D::getB3DRange(const geometry::ViewInformation3D& /*rViewInformation*/) const 201 { 202 // use defaut from sdrPrimitive3D which uses transformation expanded by line width/2. 203 // The parent implementation which uses the ranges of the decomposition would be more 204 // corrcet, but for historical reasons it is necessary to do the old method: To get 205 // the range of the non-transformed geometry and transform it then. This leads to different 206 // ranges where the new method is more correct, but the need to keep the old behaviour 207 // has priority here. 208 return getStandard3DRange(); 209 } 210 211 // provide unique ID 212 ImplPrimitrive3DIDBlock(SdrCubePrimitive3D, PRIMITIVE3D_ID_SDRCUBEPRIMITIVE3D) 213 214 } // end of namespace primitive3d 215 } // end of namespace drawinglayer 216 217 ////////////////////////////////////////////////////////////////////////////// 218 // eof 219