1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <drawinglayer/processor3d/defaultprocessor3d.hxx> 32*cdf0e10cSrcweir #include <drawinglayer/primitive3d/textureprimitive3d.hxx> 33*cdf0e10cSrcweir #include <drawinglayer/texture/texture.hxx> 34*cdf0e10cSrcweir #include <drawinglayer/texture/texture3d.hxx> 35*cdf0e10cSrcweir #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx> 36*cdf0e10cSrcweir #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx> 37*cdf0e10cSrcweir #include <drawinglayer/primitive3d/polygonprimitive3d.hxx> 38*cdf0e10cSrcweir #include <basegfx/polygon/b3dpolygontools.hxx> 39*cdf0e10cSrcweir #include <drawinglayer/attribute/materialattribute3d.hxx> 40*cdf0e10cSrcweir #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx> 41*cdf0e10cSrcweir #include <basegfx/polygon/b3dpolypolygontools.hxx> 42*cdf0e10cSrcweir #include <com/sun/star/drawing/ShadeMode.hpp> 43*cdf0e10cSrcweir #include <drawinglayer/primitive3d/transformprimitive3d.hxx> 44*cdf0e10cSrcweir #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> 45*cdf0e10cSrcweir #include <vcl/bitmapex.hxx> 46*cdf0e10cSrcweir #include <drawinglayer/attribute/sdrsceneattribute3d.hxx> 47*cdf0e10cSrcweir #include <drawinglayer/attribute/sdrlightingattribute3d.hxx> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir using namespace com::sun::star; 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir namespace drawinglayer 56*cdf0e10cSrcweir { 57*cdf0e10cSrcweir namespace processor3d 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir void DefaultProcessor3D::impRenderGradientTexturePrimitive3D(const primitive3d::GradientTexturePrimitive3D& rPrimitive, bool bTransparence) 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir if(rSubSequence.hasElements()) 64*cdf0e10cSrcweir { 65*cdf0e10cSrcweir // rescue values 66*cdf0e10cSrcweir const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); 67*cdf0e10cSrcweir const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); 68*cdf0e10cSrcweir const bool bOldSimpleTextureActive(getSimpleTextureActive()); 69*cdf0e10cSrcweir boost::shared_ptr< texture::GeoTexSvx > pOldTex = (bTransparence) ? mpTransparenceGeoTexSvx : mpGeoTexSvx; 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir // create texture 72*cdf0e10cSrcweir const attribute::FillGradientAttribute& rFillGradient = rPrimitive.getGradient(); 73*cdf0e10cSrcweir const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY()); 74*cdf0e10cSrcweir const attribute::GradientStyle aGradientStyle(rFillGradient.getStyle()); 75*cdf0e10cSrcweir sal_uInt32 nSteps(rFillGradient.getSteps()); 76*cdf0e10cSrcweir const basegfx::BColor aStart(rFillGradient.getStartColor()); 77*cdf0e10cSrcweir const basegfx::BColor aEnd(rFillGradient.getEndColor()); 78*cdf0e10cSrcweir const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5)); 79*cdf0e10cSrcweir boost::shared_ptr< texture::GeoTexSvx > pNewTex; 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir if(nMaxSteps) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir // there IS a color distance 84*cdf0e10cSrcweir if(nSteps == 0L) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir nSteps = nMaxSteps; 87*cdf0e10cSrcweir } 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir if(nSteps < 2L) 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir nSteps = 2L; 92*cdf0e10cSrcweir } 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir if(nSteps > nMaxSteps) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir nSteps = nMaxSteps; 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir switch(aGradientStyle) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_LINEAR: 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir pNewTex.reset(new texture::GeoTexSvxGradientLinear(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getAngle())); 104*cdf0e10cSrcweir break; 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_AXIAL: 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir pNewTex.reset(new texture::GeoTexSvxGradientAxial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getAngle())); 109*cdf0e10cSrcweir break; 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_RADIAL: 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir pNewTex.reset(new texture::GeoTexSvxGradientRadial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY())); 114*cdf0e10cSrcweir break; 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_ELLIPTICAL: 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir pNewTex.reset(new texture::GeoTexSvxGradientElliptical(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle())); 119*cdf0e10cSrcweir break; 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_SQUARE: 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir pNewTex.reset(new texture::GeoTexSvxGradientSquare(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle())); 124*cdf0e10cSrcweir break; 125*cdf0e10cSrcweir } 126*cdf0e10cSrcweir case attribute::GRADIENTSTYLE_RECT: 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir pNewTex.reset(new texture::GeoTexSvxGradientRect(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), rFillGradient.getAngle())); 129*cdf0e10cSrcweir break; 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir mbSimpleTextureActive = false; 134*cdf0e10cSrcweir } 135*cdf0e10cSrcweir else 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir // no color distance -> same color, use simple texture 138*cdf0e10cSrcweir pNewTex.reset(new texture::GeoTexSvxMono(aStart, 1.0 - aStart.luminance())); 139*cdf0e10cSrcweir mbSimpleTextureActive = true; 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir // set created texture 143*cdf0e10cSrcweir if(bTransparence) 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir mpTransparenceGeoTexSvx = pNewTex; 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir else 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir mpGeoTexSvx = pNewTex; 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir // process sub-list 153*cdf0e10cSrcweir process(rSubSequence); 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir // restore values 156*cdf0e10cSrcweir mbModulate = bOldModulate; 157*cdf0e10cSrcweir mbFilter = bOldFilter; 158*cdf0e10cSrcweir mbSimpleTextureActive = bOldSimpleTextureActive; 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir if(bTransparence) 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir mpTransparenceGeoTexSvx = pOldTex; 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir else 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir mpGeoTexSvx = pOldTex; 167*cdf0e10cSrcweir } 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir void DefaultProcessor3D::impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D& rPrimitive) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir if(rSubSequence.hasElements()) 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir // rescue values 178*cdf0e10cSrcweir const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); 179*cdf0e10cSrcweir const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); 180*cdf0e10cSrcweir boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx; 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir // calculate logic pixel size in object coordinates. Create transformation view 183*cdf0e10cSrcweir // to object by inverting ObjectToView 184*cdf0e10cSrcweir basegfx::B3DHomMatrix aInvObjectToView(getViewInformation3D().getObjectToView()); 185*cdf0e10cSrcweir aInvObjectToView.invert(); 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir // back-project discrete coordinates to object coordinates and extract 188*cdf0e10cSrcweir // maximum distance 189*cdf0e10cSrcweir const basegfx::B3DPoint aZero(aInvObjectToView * basegfx::B3DPoint(0.0, 0.0, 0.0)); 190*cdf0e10cSrcweir const basegfx::B3DPoint aOne(aInvObjectToView * basegfx::B3DPoint(1.0, 1.0, 1.0)); 191*cdf0e10cSrcweir const basegfx::B3DVector aLogicPixel(aOne - aZero); 192*cdf0e10cSrcweir double fLogicPixelSizeWorld(::std::max(::std::max(fabs(aLogicPixel.getX()), fabs(aLogicPixel.getY())), fabs(aLogicPixel.getZ()))); 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir // calculate logic pixel size in texture coordinates 195*cdf0e10cSrcweir const double fLogicTexSizeX(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getX()); 196*cdf0e10cSrcweir const double fLogicTexSizeY(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getY()); 197*cdf0e10cSrcweir const double fLogicTexSize(fLogicTexSizeX > fLogicTexSizeY ? fLogicTexSizeX : fLogicTexSizeY); 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir // create texture and set 200*cdf0e10cSrcweir mpGeoTexSvx.reset(new texture::GeoTexSvxMultiHatch(rPrimitive, fLogicTexSize)); 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir // process sub-list 203*cdf0e10cSrcweir process(rSubSequence); 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir // restore values 206*cdf0e10cSrcweir mbModulate = bOldModulate; 207*cdf0e10cSrcweir mbFilter = bOldFilter; 208*cdf0e10cSrcweir mpGeoTexSvx = pOldTex; 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir void DefaultProcessor3D::impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D& rPrimitive) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir if(rSubSequence.hasElements()) 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir // rescue values 219*cdf0e10cSrcweir const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); 220*cdf0e10cSrcweir const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); 221*cdf0e10cSrcweir boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx; 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir // create texture 224*cdf0e10cSrcweir const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPrimitive.getFillBitmapAttribute(); 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir if(rFillBitmapAttribute.getTiling()) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir mpGeoTexSvx.reset(new texture::GeoTexSvxBitmapTiled( 229*cdf0e10cSrcweir rFillBitmapAttribute.getBitmapEx().GetBitmap(), 230*cdf0e10cSrcweir rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(), 231*cdf0e10cSrcweir rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize())); 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir else 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir mpGeoTexSvx.reset(new texture::GeoTexSvxBitmap( 236*cdf0e10cSrcweir rFillBitmapAttribute.getBitmapEx().GetBitmap(), 237*cdf0e10cSrcweir rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(), 238*cdf0e10cSrcweir rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize())); 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir // process sub-list 242*cdf0e10cSrcweir process(rSubSequence); 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir // restore values 245*cdf0e10cSrcweir mbModulate = bOldModulate; 246*cdf0e10cSrcweir mbFilter = bOldFilter; 247*cdf0e10cSrcweir mpGeoTexSvx = pOldTex; 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir void DefaultProcessor3D::impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate) 252*cdf0e10cSrcweir { 253*cdf0e10cSrcweir const primitive3d::Primitive3DSequence& rSubSequence = rModifiedCandidate.getChildren(); 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir if(rSubSequence.hasElements()) 256*cdf0e10cSrcweir { 257*cdf0e10cSrcweir // put modifier on stack 258*cdf0e10cSrcweir maBColorModifierStack.push(rModifiedCandidate.getColorModifier()); 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir // process sub-list 261*cdf0e10cSrcweir process(rModifiedCandidate.getChildren()); 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir // remove modifier from stack 264*cdf0e10cSrcweir maBColorModifierStack.pop(); 265*cdf0e10cSrcweir } 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir void DefaultProcessor3D::impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir basegfx::B3DPolygon aHairline(rPrimitive.getB3DPolygon()); 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir if(aHairline.count()) 273*cdf0e10cSrcweir { 274*cdf0e10cSrcweir // hairlines need no extra data, clear it 275*cdf0e10cSrcweir aHairline.clearTextureCoordinates(); 276*cdf0e10cSrcweir aHairline.clearNormals(); 277*cdf0e10cSrcweir aHairline.clearBColors(); 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir // transform to device coordinates (-1.0 .. 1.0) and check for visibility 280*cdf0e10cSrcweir aHairline.transform(getViewInformation3D().getObjectToView()); 281*cdf0e10cSrcweir const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aHairline)); 282*cdf0e10cSrcweir const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY()); 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir if(a2DRange.overlaps(maRasterRange)) 285*cdf0e10cSrcweir { 286*cdf0e10cSrcweir const attribute::MaterialAttribute3D aMaterial(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor())); 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir rasterconvertB3DPolygon(aMaterial, aHairline); 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir } 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir void DefaultProcessor3D::impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive) 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir basegfx::B3DPolyPolygon aFill(rPrimitive.getB3DPolyPolygon()); 296*cdf0e10cSrcweir basegfx::BColor aObjectColor(rPrimitive.getMaterial().getColor()); 297*cdf0e10cSrcweir bool bPaintIt(aFill.count()); 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir // #i98295# get ShadeMode. Correct early when only flat is possible due to missing normals 300*cdf0e10cSrcweir const ::com::sun::star::drawing::ShadeMode aShadeMode( 301*cdf0e10cSrcweir aFill.areNormalsUsed() ? 302*cdf0e10cSrcweir getSdrSceneAttribute().getShadeMode() : ::com::sun::star::drawing::ShadeMode_FLAT); 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir if(bPaintIt) 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir // get rid of texture coordinates if there is no texture 307*cdf0e10cSrcweir if(aFill.areTextureCoordinatesUsed() && !getGeoTexSvx().get() && !getTransparenceGeoTexSvx().get()) 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir aFill.clearTextureCoordinates(); 310*cdf0e10cSrcweir } 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir // #i98295# get rid of normals and color early when not needed 313*cdf0e10cSrcweir if(::com::sun::star::drawing::ShadeMode_FLAT == aShadeMode) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir aFill.clearNormals(); 316*cdf0e10cSrcweir aFill.clearBColors(); 317*cdf0e10cSrcweir } 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir // transform to device coordinates (-1.0 .. 1.0) and check for visibility 320*cdf0e10cSrcweir aFill.transform(getViewInformation3D().getObjectToView()); 321*cdf0e10cSrcweir const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aFill)); 322*cdf0e10cSrcweir const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY()); 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir bPaintIt = a2DRange.overlaps(maRasterRange); 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir // check if it shall be painted regarding hiding of normals (backface culling) 328*cdf0e10cSrcweir if(bPaintIt && !rPrimitive.getDoubleSided()) 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir // get plane normal of polygon in view coordinates (with ZBuffer values), 331*cdf0e10cSrcweir // left-handed coordinate system 332*cdf0e10cSrcweir const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal()); 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir if(aPlaneNormal.getZ() > 0.0) 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir bPaintIt = false; 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir if(bPaintIt) 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir // prepare ObjectToEye in NormalTransform 343*cdf0e10cSrcweir basegfx::B3DHomMatrix aNormalTransform(getViewInformation3D().getOrientation() * getViewInformation3D().getObjectTransformation()); 344*cdf0e10cSrcweir 345*cdf0e10cSrcweir if(getSdrSceneAttribute().getTwoSidedLighting()) 346*cdf0e10cSrcweir { 347*cdf0e10cSrcweir // get plane normal of polygon in view coordinates (with ZBuffer values), 348*cdf0e10cSrcweir // left-handed coordinate system 349*cdf0e10cSrcweir const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal()); 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir if(aPlaneNormal.getZ() > 0.0) 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir // mirror normals 354*cdf0e10cSrcweir aNormalTransform.scale(-1.0, -1.0, -1.0); 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir switch(aShadeMode) 359*cdf0e10cSrcweir { 360*cdf0e10cSrcweir case ::com::sun::star::drawing::ShadeMode_PHONG: 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir // phong shading. Transform normals to eye coor 363*cdf0e10cSrcweir aFill.transformNormals(aNormalTransform); 364*cdf0e10cSrcweir break; 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir case ::com::sun::star::drawing::ShadeMode_SMOOTH: 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir // gouraud shading. Transform normals to eye coor 369*cdf0e10cSrcweir aFill.transformNormals(aNormalTransform); 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir // prepare color model parameters, evtl. use blend color 372*cdf0e10cSrcweir const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor()); 373*cdf0e10cSrcweir const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular()); 374*cdf0e10cSrcweir const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission()); 375*cdf0e10cSrcweir const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity()); 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir // solve color model for each normal vector, set colors at points. Clear normals. 378*cdf0e10cSrcweir for(sal_uInt32 a(0L); a < aFill.count(); a++) 379*cdf0e10cSrcweir { 380*cdf0e10cSrcweir basegfx::B3DPolygon aPartFill(aFill.getB3DPolygon(a)); 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir for(sal_uInt32 b(0L); b < aPartFill.count(); b++) 383*cdf0e10cSrcweir { 384*cdf0e10cSrcweir // solve color model. Transform normal to eye coor 385*cdf0e10cSrcweir const basegfx::B3DVector aNormal(aPartFill.getNormal(b)); 386*cdf0e10cSrcweir const basegfx::BColor aSolvedColor(getSdrLightingAttribute().solveColorModel(aNormal, aColor, rSpecular, rEmission, nSpecularIntensity)); 387*cdf0e10cSrcweir aPartFill.setBColor(b, aSolvedColor); 388*cdf0e10cSrcweir } 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir // clear normals on this part polygon and write it back 391*cdf0e10cSrcweir aPartFill.clearNormals(); 392*cdf0e10cSrcweir aFill.setB3DPolygon(a, aPartFill); 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir break; 395*cdf0e10cSrcweir } 396*cdf0e10cSrcweir case ::com::sun::star::drawing::ShadeMode_FLAT: 397*cdf0e10cSrcweir { 398*cdf0e10cSrcweir // flat shading. Get plane vector in eye coordinates 399*cdf0e10cSrcweir const basegfx::B3DVector aPlaneEyeNormal(aNormalTransform * rPrimitive.getB3DPolyPolygon().getB3DPolygon(0L).getNormal()); 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir // prepare color model parameters, evtl. use blend color 402*cdf0e10cSrcweir const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor()); 403*cdf0e10cSrcweir const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular()); 404*cdf0e10cSrcweir const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission()); 405*cdf0e10cSrcweir const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity()); 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir // solve color model for plane vector and use that color for whole plane 408*cdf0e10cSrcweir aObjectColor = getSdrLightingAttribute().solveColorModel(aPlaneEyeNormal, aColor, rSpecular, rEmission, nSpecularIntensity); 409*cdf0e10cSrcweir break; 410*cdf0e10cSrcweir } 411*cdf0e10cSrcweir default: // case ::com::sun::star::drawing::ShadeMode_DRAFT: 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir // draft, just use object color which is already set. Delete all other infos 414*cdf0e10cSrcweir aFill.clearNormals(); 415*cdf0e10cSrcweir aFill.clearBColors(); 416*cdf0e10cSrcweir break; 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir } 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir // draw it to ZBuffer 421*cdf0e10cSrcweir const attribute::MaterialAttribute3D aMaterial( 422*cdf0e10cSrcweir maBColorModifierStack.getModifiedColor(aObjectColor), 423*cdf0e10cSrcweir rPrimitive.getMaterial().getSpecular(), 424*cdf0e10cSrcweir rPrimitive.getMaterial().getEmission(), 425*cdf0e10cSrcweir rPrimitive.getMaterial().getSpecularIntensity()); 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir rasterconvertB3DPolyPolygon(aMaterial, aFill); 428*cdf0e10cSrcweir } 429*cdf0e10cSrcweir } 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir void DefaultProcessor3D::impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D& rTransformCandidate) 432*cdf0e10cSrcweir { 433*cdf0e10cSrcweir // transform group. Remember current transformations 434*cdf0e10cSrcweir const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D()); 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir // create new transformation; add new object transform from right side 437*cdf0e10cSrcweir const geometry::ViewInformation3D aNewViewInformation3D( 438*cdf0e10cSrcweir aLastViewInformation3D.getObjectTransformation() * rTransformCandidate.getTransformation(), 439*cdf0e10cSrcweir aLastViewInformation3D.getOrientation(), 440*cdf0e10cSrcweir aLastViewInformation3D.getProjection(), 441*cdf0e10cSrcweir aLastViewInformation3D.getDeviceToView(), 442*cdf0e10cSrcweir aLastViewInformation3D.getViewTime(), 443*cdf0e10cSrcweir aLastViewInformation3D.getExtendedInformationSequence()); 444*cdf0e10cSrcweir updateViewInformation(aNewViewInformation3D); 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir // let break down recursively 447*cdf0e10cSrcweir process(rTransformCandidate.getChildren()); 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir // restore transformations 450*cdf0e10cSrcweir updateViewInformation(aLastViewInformation3D); 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir void DefaultProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive) 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch 456*cdf0e10cSrcweir switch(rBasePrimitive.getPrimitive3DID()) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir case PRIMITIVE3D_ID_GRADIENTTEXTUREPRIMITIVE3D : 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir // GradientTexturePrimitive3D 461*cdf0e10cSrcweir const primitive3d::GradientTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::GradientTexturePrimitive3D& >(rBasePrimitive); 462*cdf0e10cSrcweir impRenderGradientTexturePrimitive3D(rPrimitive, false); 463*cdf0e10cSrcweir break; 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D : 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir // HatchTexturePrimitive3D 468*cdf0e10cSrcweir static bool bDoHatchDecomposition(false); 469*cdf0e10cSrcweir 470*cdf0e10cSrcweir if(bDoHatchDecomposition) 471*cdf0e10cSrcweir { 472*cdf0e10cSrcweir // let break down 473*cdf0e10cSrcweir process(rBasePrimitive.get3DDecomposition(getViewInformation3D())); 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir else 476*cdf0e10cSrcweir { 477*cdf0e10cSrcweir // hatchTexturePrimitive3D 478*cdf0e10cSrcweir const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rBasePrimitive); 479*cdf0e10cSrcweir impRenderHatchTexturePrimitive3D(rPrimitive); 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir break; 482*cdf0e10cSrcweir } 483*cdf0e10cSrcweir case PRIMITIVE3D_ID_BITMAPTEXTUREPRIMITIVE3D : 484*cdf0e10cSrcweir { 485*cdf0e10cSrcweir // BitmapTexturePrimitive3D 486*cdf0e10cSrcweir const primitive3d::BitmapTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::BitmapTexturePrimitive3D& >(rBasePrimitive); 487*cdf0e10cSrcweir impRenderBitmapTexturePrimitive3D(rPrimitive); 488*cdf0e10cSrcweir break; 489*cdf0e10cSrcweir } 490*cdf0e10cSrcweir case PRIMITIVE3D_ID_TRANSPARENCETEXTUREPRIMITIVE3D : 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir // TransparenceTexturePrimitive3D 493*cdf0e10cSrcweir const primitive3d::TransparenceTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::TransparenceTexturePrimitive3D& >(rBasePrimitive); 494*cdf0e10cSrcweir mnTransparenceCounter++; 495*cdf0e10cSrcweir impRenderGradientTexturePrimitive3D(rPrimitive, true); 496*cdf0e10cSrcweir mnTransparenceCounter--; 497*cdf0e10cSrcweir break; 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir case PRIMITIVE3D_ID_MODIFIEDCOLORPRIMITIVE3D : 500*cdf0e10cSrcweir { 501*cdf0e10cSrcweir // ModifiedColorPrimitive3D 502*cdf0e10cSrcweir // Force output to unified color. 503*cdf0e10cSrcweir const primitive3d::ModifiedColorPrimitive3D& rPrimitive = static_cast< const primitive3d::ModifiedColorPrimitive3D& >(rBasePrimitive); 504*cdf0e10cSrcweir impRenderModifiedColorPrimitive3D(rPrimitive); 505*cdf0e10cSrcweir break; 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir // directdraw of PolygonHairlinePrimitive3D 510*cdf0e10cSrcweir const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rBasePrimitive); 511*cdf0e10cSrcweir impRenderPolygonHairlinePrimitive3D(rPrimitive); 512*cdf0e10cSrcweir break; 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : 515*cdf0e10cSrcweir { 516*cdf0e10cSrcweir // directdraw of PolyPolygonMaterialPrimitive3D 517*cdf0e10cSrcweir const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rBasePrimitive); 518*cdf0e10cSrcweir impRenderPolyPolygonMaterialPrimitive3D(rPrimitive); 519*cdf0e10cSrcweir break; 520*cdf0e10cSrcweir } 521*cdf0e10cSrcweir case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : 522*cdf0e10cSrcweir { 523*cdf0e10cSrcweir // transform group (TransformPrimitive3D) 524*cdf0e10cSrcweir impRenderTransformPrimitive3D(static_cast< const primitive3d::TransformPrimitive3D& >(rBasePrimitive)); 525*cdf0e10cSrcweir break; 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir default: 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir // process recursively 530*cdf0e10cSrcweir process(rBasePrimitive.get3DDecomposition(getViewInformation3D())); 531*cdf0e10cSrcweir break; 532*cdf0e10cSrcweir } 533*cdf0e10cSrcweir } 534*cdf0e10cSrcweir } 535*cdf0e10cSrcweir 536*cdf0e10cSrcweir DefaultProcessor3D::DefaultProcessor3D( 537*cdf0e10cSrcweir const geometry::ViewInformation3D& rViewInformation, 538*cdf0e10cSrcweir const attribute::SdrSceneAttribute& rSdrSceneAttribute, 539*cdf0e10cSrcweir const attribute::SdrLightingAttribute& rSdrLightingAttribute) 540*cdf0e10cSrcweir : BaseProcessor3D(rViewInformation), 541*cdf0e10cSrcweir mrSdrSceneAttribute(rSdrSceneAttribute), 542*cdf0e10cSrcweir mrSdrLightingAttribute(rSdrLightingAttribute), 543*cdf0e10cSrcweir maRasterRange(), 544*cdf0e10cSrcweir maBColorModifierStack(), 545*cdf0e10cSrcweir mpGeoTexSvx(), 546*cdf0e10cSrcweir mpTransparenceGeoTexSvx(), 547*cdf0e10cSrcweir maDrawinglayerOpt(), 548*cdf0e10cSrcweir mnTransparenceCounter(0), 549*cdf0e10cSrcweir mbModulate(false), 550*cdf0e10cSrcweir mbFilter(false), 551*cdf0e10cSrcweir mbSimpleTextureActive(false) 552*cdf0e10cSrcweir { 553*cdf0e10cSrcweir // a derivation has to set maRasterRange which is used in the basic render methods. 554*cdf0e10cSrcweir // Setting to default here ([0.0 .. 1.0] in X,Y) to avoid problems 555*cdf0e10cSrcweir maRasterRange.expand(basegfx::B2DTuple(0.0, 0.0)); 556*cdf0e10cSrcweir maRasterRange.expand(basegfx::B2DTuple(1.0, 1.0)); 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir DefaultProcessor3D::~DefaultProcessor3D() 560*cdf0e10cSrcweir { 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir } // end of namespace processor3d 563*cdf0e10cSrcweir } // end of namespace drawinglayer 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 566*cdf0e10cSrcweir // eof 567