1464702f4SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3464702f4SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4464702f4SAndrew Rist * or more contributor license agreements. See the NOTICE file 5464702f4SAndrew Rist * distributed with this work for additional information 6464702f4SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7464702f4SAndrew Rist * to you under the Apache License, Version 2.0 (the 8464702f4SAndrew Rist * "License"); you may not use this file except in compliance 9464702f4SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11464702f4SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13464702f4SAndrew Rist * Unless required by applicable law or agreed to in writing, 14464702f4SAndrew Rist * software distributed under the License is distributed on an 15464702f4SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16464702f4SAndrew Rist * KIND, either express or implied. See the License for the 17464702f4SAndrew Rist * specific language governing permissions and limitations 18464702f4SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20464702f4SAndrew Rist *************************************************************/ 21464702f4SAndrew Rist 22464702f4SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <drawinglayer/processor3d/defaultprocessor3d.hxx> 28cdf0e10cSrcweir #include <drawinglayer/primitive3d/textureprimitive3d.hxx> 29cdf0e10cSrcweir #include <drawinglayer/texture/texture.hxx> 30cdf0e10cSrcweir #include <drawinglayer/texture/texture3d.hxx> 31cdf0e10cSrcweir #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx> 32cdf0e10cSrcweir #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx> 33cdf0e10cSrcweir #include <drawinglayer/primitive3d/polygonprimitive3d.hxx> 34cdf0e10cSrcweir #include <basegfx/polygon/b3dpolygontools.hxx> 35cdf0e10cSrcweir #include <drawinglayer/attribute/materialattribute3d.hxx> 36cdf0e10cSrcweir #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx> 37cdf0e10cSrcweir #include <basegfx/polygon/b3dpolypolygontools.hxx> 38cdf0e10cSrcweir #include <com/sun/star/drawing/ShadeMode.hpp> 39cdf0e10cSrcweir #include <drawinglayer/primitive3d/transformprimitive3d.hxx> 40cdf0e10cSrcweir #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx> 41cdf0e10cSrcweir #include <vcl/bitmapex.hxx> 42cdf0e10cSrcweir #include <drawinglayer/attribute/sdrsceneattribute3d.hxx> 43cdf0e10cSrcweir #include <drawinglayer/attribute/sdrlightingattribute3d.hxx> 44035a2f44SArmin Le Grand #include <vcl/graph.hxx> 45035a2f44SArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx> 46cdf0e10cSrcweir 47cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 48cdf0e10cSrcweir 49cdf0e10cSrcweir using namespace com::sun::star; 50cdf0e10cSrcweir 51cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 52cdf0e10cSrcweir 53cdf0e10cSrcweir namespace drawinglayer 54cdf0e10cSrcweir { 55cdf0e10cSrcweir namespace processor3d 56cdf0e10cSrcweir { impRenderGradientTexturePrimitive3D(const primitive3d::GradientTexturePrimitive3D & rPrimitive,bool bTransparence)57cdf0e10cSrcweir void DefaultProcessor3D::impRenderGradientTexturePrimitive3D(const primitive3d::GradientTexturePrimitive3D& rPrimitive, bool bTransparence) 58cdf0e10cSrcweir { 59cdf0e10cSrcweir const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); 60cdf0e10cSrcweir 61cdf0e10cSrcweir if(rSubSequence.hasElements()) 62cdf0e10cSrcweir { 63cdf0e10cSrcweir // rescue values 64cdf0e10cSrcweir const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); 65cdf0e10cSrcweir const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); 66cdf0e10cSrcweir const bool bOldSimpleTextureActive(getSimpleTextureActive()); 67cdf0e10cSrcweir boost::shared_ptr< texture::GeoTexSvx > pOldTex = (bTransparence) ? mpTransparenceGeoTexSvx : mpGeoTexSvx; 68cdf0e10cSrcweir 69cdf0e10cSrcweir // create texture 70cdf0e10cSrcweir const attribute::FillGradientAttribute& rFillGradient = rPrimitive.getGradient(); 71cdf0e10cSrcweir const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY()); 72cdf0e10cSrcweir const attribute::GradientStyle aGradientStyle(rFillGradient.getStyle()); 73cdf0e10cSrcweir sal_uInt32 nSteps(rFillGradient.getSteps()); 74cdf0e10cSrcweir const basegfx::BColor aStart(rFillGradient.getStartColor()); 75cdf0e10cSrcweir const basegfx::BColor aEnd(rFillGradient.getEndColor()); 76cdf0e10cSrcweir const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5)); 77cdf0e10cSrcweir boost::shared_ptr< texture::GeoTexSvx > pNewTex; 78cdf0e10cSrcweir 79cdf0e10cSrcweir if(nMaxSteps) 80cdf0e10cSrcweir { 81cdf0e10cSrcweir // there IS a color distance 82cdf0e10cSrcweir if(nSteps == 0L) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir nSteps = nMaxSteps; 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir if(nSteps < 2L) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir nSteps = 2L; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir if(nSteps > nMaxSteps) 93cdf0e10cSrcweir { 94cdf0e10cSrcweir nSteps = nMaxSteps; 95cdf0e10cSrcweir } 96cdf0e10cSrcweir 97cdf0e10cSrcweir switch(aGradientStyle) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir case attribute::GRADIENTSTYLE_LINEAR: 100cdf0e10cSrcweir { 101*64b14621SArmin Le Grand pNewTex.reset( 102*64b14621SArmin Le Grand new texture::GeoTexSvxGradientLinear( 103*64b14621SArmin Le Grand aOutlineRange, 104*64b14621SArmin Le Grand aOutlineRange, 105*64b14621SArmin Le Grand aStart, 106*64b14621SArmin Le Grand aEnd, 107*64b14621SArmin Le Grand nSteps, 108*64b14621SArmin Le Grand rFillGradient.getBorder(), 109*64b14621SArmin Le Grand rFillGradient.getAngle())); 110cdf0e10cSrcweir break; 111cdf0e10cSrcweir } 112cdf0e10cSrcweir case attribute::GRADIENTSTYLE_AXIAL: 113cdf0e10cSrcweir { 114*64b14621SArmin Le Grand pNewTex.reset( 115*64b14621SArmin Le Grand new texture::GeoTexSvxGradientAxial( 116*64b14621SArmin Le Grand aOutlineRange, 117*64b14621SArmin Le Grand aOutlineRange, 118*64b14621SArmin Le Grand aStart, 119*64b14621SArmin Le Grand aEnd, 120*64b14621SArmin Le Grand nSteps, 121*64b14621SArmin Le Grand rFillGradient.getBorder(), 122*64b14621SArmin Le Grand rFillGradient.getAngle())); 123cdf0e10cSrcweir break; 124cdf0e10cSrcweir } 125cdf0e10cSrcweir case attribute::GRADIENTSTYLE_RADIAL: 126cdf0e10cSrcweir { 127*64b14621SArmin Le Grand pNewTex.reset( 128*64b14621SArmin Le Grand new texture::GeoTexSvxGradientRadial( 129*64b14621SArmin Le Grand aOutlineRange, 130*64b14621SArmin Le Grand aStart, 131*64b14621SArmin Le Grand aEnd, 132*64b14621SArmin Le Grand nSteps, 133*64b14621SArmin Le Grand rFillGradient.getBorder(), 134*64b14621SArmin Le Grand rFillGradient.getOffsetX(), 135*64b14621SArmin Le Grand rFillGradient.getOffsetY())); 136cdf0e10cSrcweir break; 137cdf0e10cSrcweir } 138cdf0e10cSrcweir case attribute::GRADIENTSTYLE_ELLIPTICAL: 139cdf0e10cSrcweir { 140*64b14621SArmin Le Grand pNewTex.reset( 141*64b14621SArmin Le Grand new texture::GeoTexSvxGradientElliptical( 142*64b14621SArmin Le Grand aOutlineRange, 143*64b14621SArmin Le Grand aStart, 144*64b14621SArmin Le Grand aEnd, 145*64b14621SArmin Le Grand nSteps, 146*64b14621SArmin Le Grand rFillGradient.getBorder(), 147*64b14621SArmin Le Grand rFillGradient.getOffsetX(), 148*64b14621SArmin Le Grand rFillGradient.getOffsetY(), 149*64b14621SArmin Le Grand rFillGradient.getAngle())); 150cdf0e10cSrcweir break; 151cdf0e10cSrcweir } 152cdf0e10cSrcweir case attribute::GRADIENTSTYLE_SQUARE: 153cdf0e10cSrcweir { 154*64b14621SArmin Le Grand pNewTex.reset( 155*64b14621SArmin Le Grand new texture::GeoTexSvxGradientSquare( 156*64b14621SArmin Le Grand aOutlineRange, 157*64b14621SArmin Le Grand aStart, 158*64b14621SArmin Le Grand aEnd, 159*64b14621SArmin Le Grand nSteps, 160*64b14621SArmin Le Grand rFillGradient.getBorder(), 161*64b14621SArmin Le Grand rFillGradient.getOffsetX(), 162*64b14621SArmin Le Grand rFillGradient.getOffsetY(), 163*64b14621SArmin Le Grand rFillGradient.getAngle())); 164cdf0e10cSrcweir break; 165cdf0e10cSrcweir } 166cdf0e10cSrcweir case attribute::GRADIENTSTYLE_RECT: 167cdf0e10cSrcweir { 168*64b14621SArmin Le Grand pNewTex.reset( 169*64b14621SArmin Le Grand new texture::GeoTexSvxGradientRect( 170*64b14621SArmin Le Grand aOutlineRange, 171*64b14621SArmin Le Grand aStart, 172*64b14621SArmin Le Grand aEnd, 173*64b14621SArmin Le Grand nSteps, 174*64b14621SArmin Le Grand rFillGradient.getBorder(), 175*64b14621SArmin Le Grand rFillGradient.getOffsetX(), 176*64b14621SArmin Le Grand rFillGradient.getOffsetY(), 177*64b14621SArmin Le Grand rFillGradient.getAngle())); 178cdf0e10cSrcweir break; 179cdf0e10cSrcweir } 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir mbSimpleTextureActive = false; 183cdf0e10cSrcweir } 184cdf0e10cSrcweir else 185cdf0e10cSrcweir { 186cdf0e10cSrcweir // no color distance -> same color, use simple texture 187cdf0e10cSrcweir pNewTex.reset(new texture::GeoTexSvxMono(aStart, 1.0 - aStart.luminance())); 188cdf0e10cSrcweir mbSimpleTextureActive = true; 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir // set created texture 192cdf0e10cSrcweir if(bTransparence) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir mpTransparenceGeoTexSvx = pNewTex; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir else 197cdf0e10cSrcweir { 198cdf0e10cSrcweir mpGeoTexSvx = pNewTex; 199cdf0e10cSrcweir } 200cdf0e10cSrcweir 201cdf0e10cSrcweir // process sub-list 202cdf0e10cSrcweir process(rSubSequence); 203cdf0e10cSrcweir 204cdf0e10cSrcweir // restore values 205cdf0e10cSrcweir mbModulate = bOldModulate; 206cdf0e10cSrcweir mbFilter = bOldFilter; 207cdf0e10cSrcweir mbSimpleTextureActive = bOldSimpleTextureActive; 208cdf0e10cSrcweir 209cdf0e10cSrcweir if(bTransparence) 210cdf0e10cSrcweir { 211cdf0e10cSrcweir mpTransparenceGeoTexSvx = pOldTex; 212cdf0e10cSrcweir } 213cdf0e10cSrcweir else 214cdf0e10cSrcweir { 215cdf0e10cSrcweir mpGeoTexSvx = pOldTex; 216cdf0e10cSrcweir } 217cdf0e10cSrcweir } 218cdf0e10cSrcweir } 219cdf0e10cSrcweir impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D & rPrimitive)220cdf0e10cSrcweir void DefaultProcessor3D::impRenderHatchTexturePrimitive3D(const primitive3d::HatchTexturePrimitive3D& rPrimitive) 221cdf0e10cSrcweir { 222cdf0e10cSrcweir const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); 223cdf0e10cSrcweir 224cdf0e10cSrcweir if(rSubSequence.hasElements()) 225cdf0e10cSrcweir { 226cdf0e10cSrcweir // rescue values 227cdf0e10cSrcweir const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); 228cdf0e10cSrcweir const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); 229cdf0e10cSrcweir boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx; 230cdf0e10cSrcweir 231cdf0e10cSrcweir // calculate logic pixel size in object coordinates. Create transformation view 232cdf0e10cSrcweir // to object by inverting ObjectToView 233cdf0e10cSrcweir basegfx::B3DHomMatrix aInvObjectToView(getViewInformation3D().getObjectToView()); 234cdf0e10cSrcweir aInvObjectToView.invert(); 235cdf0e10cSrcweir 236cdf0e10cSrcweir // back-project discrete coordinates to object coordinates and extract 237cdf0e10cSrcweir // maximum distance 238cdf0e10cSrcweir const basegfx::B3DPoint aZero(aInvObjectToView * basegfx::B3DPoint(0.0, 0.0, 0.0)); 239cdf0e10cSrcweir const basegfx::B3DPoint aOne(aInvObjectToView * basegfx::B3DPoint(1.0, 1.0, 1.0)); 240cdf0e10cSrcweir const basegfx::B3DVector aLogicPixel(aOne - aZero); 241cdf0e10cSrcweir double fLogicPixelSizeWorld(::std::max(::std::max(fabs(aLogicPixel.getX()), fabs(aLogicPixel.getY())), fabs(aLogicPixel.getZ()))); 242cdf0e10cSrcweir 243cdf0e10cSrcweir // calculate logic pixel size in texture coordinates 244cdf0e10cSrcweir const double fLogicTexSizeX(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getX()); 245cdf0e10cSrcweir const double fLogicTexSizeY(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getY()); 246cdf0e10cSrcweir const double fLogicTexSize(fLogicTexSizeX > fLogicTexSizeY ? fLogicTexSizeX : fLogicTexSizeY); 247cdf0e10cSrcweir 248cdf0e10cSrcweir // create texture and set 249cdf0e10cSrcweir mpGeoTexSvx.reset(new texture::GeoTexSvxMultiHatch(rPrimitive, fLogicTexSize)); 250cdf0e10cSrcweir 251cdf0e10cSrcweir // process sub-list 252cdf0e10cSrcweir process(rSubSequence); 253cdf0e10cSrcweir 254cdf0e10cSrcweir // restore values 255cdf0e10cSrcweir mbModulate = bOldModulate; 256cdf0e10cSrcweir mbFilter = bOldFilter; 257cdf0e10cSrcweir mpGeoTexSvx = pOldTex; 258cdf0e10cSrcweir } 259cdf0e10cSrcweir } 260cdf0e10cSrcweir impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D & rPrimitive)261cdf0e10cSrcweir void DefaultProcessor3D::impRenderBitmapTexturePrimitive3D(const primitive3d::BitmapTexturePrimitive3D& rPrimitive) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir const primitive3d::Primitive3DSequence& rSubSequence = rPrimitive.getChildren(); 264cdf0e10cSrcweir 265cdf0e10cSrcweir if(rSubSequence.hasElements()) 266cdf0e10cSrcweir { 267cdf0e10cSrcweir // rescue values 268cdf0e10cSrcweir const bool bOldModulate(getModulate()); mbModulate = rPrimitive.getModulate(); 269cdf0e10cSrcweir const bool bOldFilter(getFilter()); mbFilter = rPrimitive.getFilter(); 270cdf0e10cSrcweir boost::shared_ptr< texture::GeoTexSvx > pOldTex = mpGeoTexSvx; 271cdf0e10cSrcweir 272cdf0e10cSrcweir // create texture 273035a2f44SArmin Le Grand const attribute::FillGraphicAttribute& rFillGraphicAttribute = rPrimitive.getFillGraphicAttribute(); 274cdf0e10cSrcweir 275035a2f44SArmin Le Grand // #121194# For 3D texture we will use the BitmapRex representation 276035a2f44SArmin Le Grand const BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx()); 277035a2f44SArmin Le Grand 278035a2f44SArmin Le Grand // create range scaled by texture size 279035a2f44SArmin Le Grand basegfx::B2DRange aGraphicRange(rFillGraphicAttribute.getGraphicRange()); 280035a2f44SArmin Le Grand 281035a2f44SArmin Le Grand aGraphicRange.transform( 282035a2f44SArmin Le Grand basegfx::tools::createScaleB2DHomMatrix( 283035a2f44SArmin Le Grand rPrimitive.getTextureSize())); 284035a2f44SArmin Le Grand 285035a2f44SArmin Le Grand if(rFillGraphicAttribute.getTiling()) 286cdf0e10cSrcweir { 287035a2f44SArmin Le Grand mpGeoTexSvx.reset( 288035a2f44SArmin Le Grand new texture::GeoTexSvxBitmapExTiled( 289035a2f44SArmin Le Grand aBitmapEx, 290035a2f44SArmin Le Grand aGraphicRange, 291035a2f44SArmin Le Grand rFillGraphicAttribute.getOffsetX(), 292035a2f44SArmin Le Grand rFillGraphicAttribute.getOffsetY())); 293cdf0e10cSrcweir } 294cdf0e10cSrcweir else 295cdf0e10cSrcweir { 296035a2f44SArmin Le Grand mpGeoTexSvx.reset( 297035a2f44SArmin Le Grand new texture::GeoTexSvxBitmapEx( 298035a2f44SArmin Le Grand aBitmapEx, 299035a2f44SArmin Le Grand aGraphicRange)); 300cdf0e10cSrcweir } 301cdf0e10cSrcweir 302cdf0e10cSrcweir // process sub-list 303cdf0e10cSrcweir process(rSubSequence); 304cdf0e10cSrcweir 305cdf0e10cSrcweir // restore values 306cdf0e10cSrcweir mbModulate = bOldModulate; 307cdf0e10cSrcweir mbFilter = bOldFilter; 308cdf0e10cSrcweir mpGeoTexSvx = pOldTex; 309cdf0e10cSrcweir } 310cdf0e10cSrcweir } 311cdf0e10cSrcweir impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D & rModifiedCandidate)312cdf0e10cSrcweir void DefaultProcessor3D::impRenderModifiedColorPrimitive3D(const primitive3d::ModifiedColorPrimitive3D& rModifiedCandidate) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir const primitive3d::Primitive3DSequence& rSubSequence = rModifiedCandidate.getChildren(); 315cdf0e10cSrcweir 316cdf0e10cSrcweir if(rSubSequence.hasElements()) 317cdf0e10cSrcweir { 318cdf0e10cSrcweir // put modifier on stack 319cdf0e10cSrcweir maBColorModifierStack.push(rModifiedCandidate.getColorModifier()); 320cdf0e10cSrcweir 321cdf0e10cSrcweir // process sub-list 322cdf0e10cSrcweir process(rModifiedCandidate.getChildren()); 323cdf0e10cSrcweir 324cdf0e10cSrcweir // remove modifier from stack 325cdf0e10cSrcweir maBColorModifierStack.pop(); 326cdf0e10cSrcweir } 327cdf0e10cSrcweir } 328cdf0e10cSrcweir impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D & rPrimitive)329cdf0e10cSrcweir void DefaultProcessor3D::impRenderPolygonHairlinePrimitive3D(const primitive3d::PolygonHairlinePrimitive3D& rPrimitive) 330cdf0e10cSrcweir { 331cdf0e10cSrcweir basegfx::B3DPolygon aHairline(rPrimitive.getB3DPolygon()); 332cdf0e10cSrcweir 333cdf0e10cSrcweir if(aHairline.count()) 334cdf0e10cSrcweir { 335cdf0e10cSrcweir // hairlines need no extra data, clear it 336cdf0e10cSrcweir aHairline.clearTextureCoordinates(); 337cdf0e10cSrcweir aHairline.clearNormals(); 338cdf0e10cSrcweir aHairline.clearBColors(); 339cdf0e10cSrcweir 340cdf0e10cSrcweir // transform to device coordinates (-1.0 .. 1.0) and check for visibility 341cdf0e10cSrcweir aHairline.transform(getViewInformation3D().getObjectToView()); 342cdf0e10cSrcweir const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aHairline)); 343cdf0e10cSrcweir const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY()); 344cdf0e10cSrcweir 345cdf0e10cSrcweir if(a2DRange.overlaps(maRasterRange)) 346cdf0e10cSrcweir { 347cdf0e10cSrcweir const attribute::MaterialAttribute3D aMaterial(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor())); 348cdf0e10cSrcweir 349cdf0e10cSrcweir rasterconvertB3DPolygon(aMaterial, aHairline); 350cdf0e10cSrcweir } 351cdf0e10cSrcweir } 352cdf0e10cSrcweir } 353cdf0e10cSrcweir impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D & rPrimitive)354cdf0e10cSrcweir void DefaultProcessor3D::impRenderPolyPolygonMaterialPrimitive3D(const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive) 355cdf0e10cSrcweir { 356cdf0e10cSrcweir basegfx::B3DPolyPolygon aFill(rPrimitive.getB3DPolyPolygon()); 357cdf0e10cSrcweir basegfx::BColor aObjectColor(rPrimitive.getMaterial().getColor()); 358cdf0e10cSrcweir bool bPaintIt(aFill.count()); 359cdf0e10cSrcweir 360cdf0e10cSrcweir // #i98295# get ShadeMode. Correct early when only flat is possible due to missing normals 361cdf0e10cSrcweir const ::com::sun::star::drawing::ShadeMode aShadeMode( 362cdf0e10cSrcweir aFill.areNormalsUsed() ? 363cdf0e10cSrcweir getSdrSceneAttribute().getShadeMode() : ::com::sun::star::drawing::ShadeMode_FLAT); 364cdf0e10cSrcweir 365cdf0e10cSrcweir if(bPaintIt) 366cdf0e10cSrcweir { 367cdf0e10cSrcweir // get rid of texture coordinates if there is no texture 368cdf0e10cSrcweir if(aFill.areTextureCoordinatesUsed() && !getGeoTexSvx().get() && !getTransparenceGeoTexSvx().get()) 369cdf0e10cSrcweir { 370cdf0e10cSrcweir aFill.clearTextureCoordinates(); 371cdf0e10cSrcweir } 372cdf0e10cSrcweir 373cdf0e10cSrcweir // #i98295# get rid of normals and color early when not needed 374cdf0e10cSrcweir if(::com::sun::star::drawing::ShadeMode_FLAT == aShadeMode) 375cdf0e10cSrcweir { 376cdf0e10cSrcweir aFill.clearNormals(); 377cdf0e10cSrcweir aFill.clearBColors(); 378cdf0e10cSrcweir } 379cdf0e10cSrcweir 380cdf0e10cSrcweir // transform to device coordinates (-1.0 .. 1.0) and check for visibility 381cdf0e10cSrcweir aFill.transform(getViewInformation3D().getObjectToView()); 382cdf0e10cSrcweir const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aFill)); 383cdf0e10cSrcweir const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY()); 384cdf0e10cSrcweir 385cdf0e10cSrcweir bPaintIt = a2DRange.overlaps(maRasterRange); 386cdf0e10cSrcweir } 387cdf0e10cSrcweir 388cdf0e10cSrcweir // check if it shall be painted regarding hiding of normals (backface culling) 389cdf0e10cSrcweir if(bPaintIt && !rPrimitive.getDoubleSided()) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir // get plane normal of polygon in view coordinates (with ZBuffer values), 392cdf0e10cSrcweir // left-handed coordinate system 393cdf0e10cSrcweir const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal()); 394cdf0e10cSrcweir 395cdf0e10cSrcweir if(aPlaneNormal.getZ() > 0.0) 396cdf0e10cSrcweir { 397cdf0e10cSrcweir bPaintIt = false; 398cdf0e10cSrcweir } 399cdf0e10cSrcweir } 400cdf0e10cSrcweir 401cdf0e10cSrcweir if(bPaintIt) 402cdf0e10cSrcweir { 403cdf0e10cSrcweir // prepare ObjectToEye in NormalTransform 404cdf0e10cSrcweir basegfx::B3DHomMatrix aNormalTransform(getViewInformation3D().getOrientation() * getViewInformation3D().getObjectTransformation()); 405cdf0e10cSrcweir 406cdf0e10cSrcweir if(getSdrSceneAttribute().getTwoSidedLighting()) 407cdf0e10cSrcweir { 408cdf0e10cSrcweir // get plane normal of polygon in view coordinates (with ZBuffer values), 409cdf0e10cSrcweir // left-handed coordinate system 410cdf0e10cSrcweir const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal()); 411cdf0e10cSrcweir 412cdf0e10cSrcweir if(aPlaneNormal.getZ() > 0.0) 413cdf0e10cSrcweir { 414cdf0e10cSrcweir // mirror normals 415cdf0e10cSrcweir aNormalTransform.scale(-1.0, -1.0, -1.0); 416cdf0e10cSrcweir } 417cdf0e10cSrcweir } 418cdf0e10cSrcweir 419cdf0e10cSrcweir switch(aShadeMode) 420cdf0e10cSrcweir { 421cdf0e10cSrcweir case ::com::sun::star::drawing::ShadeMode_PHONG: 422cdf0e10cSrcweir { 423cdf0e10cSrcweir // phong shading. Transform normals to eye coor 424cdf0e10cSrcweir aFill.transformNormals(aNormalTransform); 425cdf0e10cSrcweir break; 426cdf0e10cSrcweir } 427cdf0e10cSrcweir case ::com::sun::star::drawing::ShadeMode_SMOOTH: 428cdf0e10cSrcweir { 429cdf0e10cSrcweir // gouraud shading. Transform normals to eye coor 430cdf0e10cSrcweir aFill.transformNormals(aNormalTransform); 431cdf0e10cSrcweir 432cdf0e10cSrcweir // prepare color model parameters, evtl. use blend color 433cdf0e10cSrcweir const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor()); 434cdf0e10cSrcweir const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular()); 435cdf0e10cSrcweir const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission()); 436cdf0e10cSrcweir const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity()); 437cdf0e10cSrcweir 438cdf0e10cSrcweir // solve color model for each normal vector, set colors at points. Clear normals. 439cdf0e10cSrcweir for(sal_uInt32 a(0L); a < aFill.count(); a++) 440cdf0e10cSrcweir { 441cdf0e10cSrcweir basegfx::B3DPolygon aPartFill(aFill.getB3DPolygon(a)); 442cdf0e10cSrcweir 443cdf0e10cSrcweir for(sal_uInt32 b(0L); b < aPartFill.count(); b++) 444cdf0e10cSrcweir { 445cdf0e10cSrcweir // solve color model. Transform normal to eye coor 446cdf0e10cSrcweir const basegfx::B3DVector aNormal(aPartFill.getNormal(b)); 447cdf0e10cSrcweir const basegfx::BColor aSolvedColor(getSdrLightingAttribute().solveColorModel(aNormal, aColor, rSpecular, rEmission, nSpecularIntensity)); 448cdf0e10cSrcweir aPartFill.setBColor(b, aSolvedColor); 449cdf0e10cSrcweir } 450cdf0e10cSrcweir 451cdf0e10cSrcweir // clear normals on this part polygon and write it back 452cdf0e10cSrcweir aPartFill.clearNormals(); 453cdf0e10cSrcweir aFill.setB3DPolygon(a, aPartFill); 454cdf0e10cSrcweir } 455cdf0e10cSrcweir break; 456cdf0e10cSrcweir } 457cdf0e10cSrcweir case ::com::sun::star::drawing::ShadeMode_FLAT: 458cdf0e10cSrcweir { 459cdf0e10cSrcweir // flat shading. Get plane vector in eye coordinates 460cdf0e10cSrcweir const basegfx::B3DVector aPlaneEyeNormal(aNormalTransform * rPrimitive.getB3DPolyPolygon().getB3DPolygon(0L).getNormal()); 461cdf0e10cSrcweir 462cdf0e10cSrcweir // prepare color model parameters, evtl. use blend color 463cdf0e10cSrcweir const basegfx::BColor aColor(getModulate() ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor()); 464cdf0e10cSrcweir const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular()); 465cdf0e10cSrcweir const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission()); 466cdf0e10cSrcweir const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity()); 467cdf0e10cSrcweir 468cdf0e10cSrcweir // solve color model for plane vector and use that color for whole plane 469cdf0e10cSrcweir aObjectColor = getSdrLightingAttribute().solveColorModel(aPlaneEyeNormal, aColor, rSpecular, rEmission, nSpecularIntensity); 470cdf0e10cSrcweir break; 471cdf0e10cSrcweir } 472cdf0e10cSrcweir default: // case ::com::sun::star::drawing::ShadeMode_DRAFT: 473cdf0e10cSrcweir { 474cdf0e10cSrcweir // draft, just use object color which is already set. Delete all other infos 475cdf0e10cSrcweir aFill.clearNormals(); 476cdf0e10cSrcweir aFill.clearBColors(); 477cdf0e10cSrcweir break; 478cdf0e10cSrcweir } 479cdf0e10cSrcweir } 480cdf0e10cSrcweir 481cdf0e10cSrcweir // draw it to ZBuffer 482cdf0e10cSrcweir const attribute::MaterialAttribute3D aMaterial( 483cdf0e10cSrcweir maBColorModifierStack.getModifiedColor(aObjectColor), 484cdf0e10cSrcweir rPrimitive.getMaterial().getSpecular(), 485cdf0e10cSrcweir rPrimitive.getMaterial().getEmission(), 486cdf0e10cSrcweir rPrimitive.getMaterial().getSpecularIntensity()); 487cdf0e10cSrcweir 488cdf0e10cSrcweir rasterconvertB3DPolyPolygon(aMaterial, aFill); 489cdf0e10cSrcweir } 490cdf0e10cSrcweir } 491cdf0e10cSrcweir impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D & rTransformCandidate)492cdf0e10cSrcweir void DefaultProcessor3D::impRenderTransformPrimitive3D(const primitive3d::TransformPrimitive3D& rTransformCandidate) 493cdf0e10cSrcweir { 494cdf0e10cSrcweir // transform group. Remember current transformations 495cdf0e10cSrcweir const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D()); 496cdf0e10cSrcweir 497cdf0e10cSrcweir // create new transformation; add new object transform from right side 498cdf0e10cSrcweir const geometry::ViewInformation3D aNewViewInformation3D( 499cdf0e10cSrcweir aLastViewInformation3D.getObjectTransformation() * rTransformCandidate.getTransformation(), 500cdf0e10cSrcweir aLastViewInformation3D.getOrientation(), 501cdf0e10cSrcweir aLastViewInformation3D.getProjection(), 502cdf0e10cSrcweir aLastViewInformation3D.getDeviceToView(), 503cdf0e10cSrcweir aLastViewInformation3D.getViewTime(), 504cdf0e10cSrcweir aLastViewInformation3D.getExtendedInformationSequence()); 505cdf0e10cSrcweir updateViewInformation(aNewViewInformation3D); 506cdf0e10cSrcweir 507cdf0e10cSrcweir // let break down recursively 508cdf0e10cSrcweir process(rTransformCandidate.getChildren()); 509cdf0e10cSrcweir 510cdf0e10cSrcweir // restore transformations 511cdf0e10cSrcweir updateViewInformation(aLastViewInformation3D); 512cdf0e10cSrcweir } 513cdf0e10cSrcweir processBasePrimitive3D(const primitive3d::BasePrimitive3D & rBasePrimitive)514cdf0e10cSrcweir void DefaultProcessor3D::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rBasePrimitive) 515cdf0e10cSrcweir { 516cdf0e10cSrcweir // it is a BasePrimitive3D implementation, use getPrimitive3DID() call for switch 517cdf0e10cSrcweir switch(rBasePrimitive.getPrimitive3DID()) 518cdf0e10cSrcweir { 519cdf0e10cSrcweir case PRIMITIVE3D_ID_GRADIENTTEXTUREPRIMITIVE3D : 520cdf0e10cSrcweir { 521cdf0e10cSrcweir // GradientTexturePrimitive3D 522cdf0e10cSrcweir const primitive3d::GradientTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::GradientTexturePrimitive3D& >(rBasePrimitive); 523cdf0e10cSrcweir impRenderGradientTexturePrimitive3D(rPrimitive, false); 524cdf0e10cSrcweir break; 525cdf0e10cSrcweir } 526cdf0e10cSrcweir case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D : 527cdf0e10cSrcweir { 528cdf0e10cSrcweir // HatchTexturePrimitive3D 529cdf0e10cSrcweir static bool bDoHatchDecomposition(false); 530cdf0e10cSrcweir 531cdf0e10cSrcweir if(bDoHatchDecomposition) 532cdf0e10cSrcweir { 533cdf0e10cSrcweir // let break down 534cdf0e10cSrcweir process(rBasePrimitive.get3DDecomposition(getViewInformation3D())); 535cdf0e10cSrcweir } 536cdf0e10cSrcweir else 537cdf0e10cSrcweir { 538cdf0e10cSrcweir // hatchTexturePrimitive3D 539cdf0e10cSrcweir const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rBasePrimitive); 540cdf0e10cSrcweir impRenderHatchTexturePrimitive3D(rPrimitive); 541cdf0e10cSrcweir } 542cdf0e10cSrcweir break; 543cdf0e10cSrcweir } 544cdf0e10cSrcweir case PRIMITIVE3D_ID_BITMAPTEXTUREPRIMITIVE3D : 545cdf0e10cSrcweir { 546cdf0e10cSrcweir // BitmapTexturePrimitive3D 547cdf0e10cSrcweir const primitive3d::BitmapTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::BitmapTexturePrimitive3D& >(rBasePrimitive); 548cdf0e10cSrcweir impRenderBitmapTexturePrimitive3D(rPrimitive); 549cdf0e10cSrcweir break; 550cdf0e10cSrcweir } 551cdf0e10cSrcweir case PRIMITIVE3D_ID_TRANSPARENCETEXTUREPRIMITIVE3D : 552cdf0e10cSrcweir { 553cdf0e10cSrcweir // TransparenceTexturePrimitive3D 554cdf0e10cSrcweir const primitive3d::TransparenceTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::TransparenceTexturePrimitive3D& >(rBasePrimitive); 555cdf0e10cSrcweir mnTransparenceCounter++; 556cdf0e10cSrcweir impRenderGradientTexturePrimitive3D(rPrimitive, true); 557cdf0e10cSrcweir mnTransparenceCounter--; 558cdf0e10cSrcweir break; 559cdf0e10cSrcweir } 560cdf0e10cSrcweir case PRIMITIVE3D_ID_MODIFIEDCOLORPRIMITIVE3D : 561cdf0e10cSrcweir { 562cdf0e10cSrcweir // ModifiedColorPrimitive3D 563cdf0e10cSrcweir // Force output to unified color. 564cdf0e10cSrcweir const primitive3d::ModifiedColorPrimitive3D& rPrimitive = static_cast< const primitive3d::ModifiedColorPrimitive3D& >(rBasePrimitive); 565cdf0e10cSrcweir impRenderModifiedColorPrimitive3D(rPrimitive); 566cdf0e10cSrcweir break; 567cdf0e10cSrcweir } 568cdf0e10cSrcweir case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D : 569cdf0e10cSrcweir { 570cdf0e10cSrcweir // directdraw of PolygonHairlinePrimitive3D 571cdf0e10cSrcweir const primitive3d::PolygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::PolygonHairlinePrimitive3D& >(rBasePrimitive); 572cdf0e10cSrcweir impRenderPolygonHairlinePrimitive3D(rPrimitive); 573cdf0e10cSrcweir break; 574cdf0e10cSrcweir } 575cdf0e10cSrcweir case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D : 576cdf0e10cSrcweir { 577cdf0e10cSrcweir // directdraw of PolyPolygonMaterialPrimitive3D 578cdf0e10cSrcweir const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rBasePrimitive); 579cdf0e10cSrcweir impRenderPolyPolygonMaterialPrimitive3D(rPrimitive); 580cdf0e10cSrcweir break; 581cdf0e10cSrcweir } 582cdf0e10cSrcweir case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D : 583cdf0e10cSrcweir { 584cdf0e10cSrcweir // transform group (TransformPrimitive3D) 585cdf0e10cSrcweir impRenderTransformPrimitive3D(static_cast< const primitive3d::TransformPrimitive3D& >(rBasePrimitive)); 586cdf0e10cSrcweir break; 587cdf0e10cSrcweir } 588cdf0e10cSrcweir default: 589cdf0e10cSrcweir { 590cdf0e10cSrcweir // process recursively 591cdf0e10cSrcweir process(rBasePrimitive.get3DDecomposition(getViewInformation3D())); 592cdf0e10cSrcweir break; 593cdf0e10cSrcweir } 594cdf0e10cSrcweir } 595cdf0e10cSrcweir } 596cdf0e10cSrcweir DefaultProcessor3D(const geometry::ViewInformation3D & rViewInformation,const attribute::SdrSceneAttribute & rSdrSceneAttribute,const attribute::SdrLightingAttribute & rSdrLightingAttribute)597cdf0e10cSrcweir DefaultProcessor3D::DefaultProcessor3D( 598cdf0e10cSrcweir const geometry::ViewInformation3D& rViewInformation, 599cdf0e10cSrcweir const attribute::SdrSceneAttribute& rSdrSceneAttribute, 600cdf0e10cSrcweir const attribute::SdrLightingAttribute& rSdrLightingAttribute) 601cdf0e10cSrcweir : BaseProcessor3D(rViewInformation), 602cdf0e10cSrcweir mrSdrSceneAttribute(rSdrSceneAttribute), 603cdf0e10cSrcweir mrSdrLightingAttribute(rSdrLightingAttribute), 604cdf0e10cSrcweir maRasterRange(), 605cdf0e10cSrcweir maBColorModifierStack(), 606cdf0e10cSrcweir mpGeoTexSvx(), 607cdf0e10cSrcweir mpTransparenceGeoTexSvx(), 608cdf0e10cSrcweir maDrawinglayerOpt(), 609cdf0e10cSrcweir mnTransparenceCounter(0), 610cdf0e10cSrcweir mbModulate(false), 611cdf0e10cSrcweir mbFilter(false), 612cdf0e10cSrcweir mbSimpleTextureActive(false) 613cdf0e10cSrcweir { 614cdf0e10cSrcweir // a derivation has to set maRasterRange which is used in the basic render methods. 615cdf0e10cSrcweir // Setting to default here ([0.0 .. 1.0] in X,Y) to avoid problems 616cdf0e10cSrcweir maRasterRange.expand(basegfx::B2DTuple(0.0, 0.0)); 617cdf0e10cSrcweir maRasterRange.expand(basegfx::B2DTuple(1.0, 1.0)); 618cdf0e10cSrcweir } 619cdf0e10cSrcweir ~DefaultProcessor3D()620cdf0e10cSrcweir DefaultProcessor3D::~DefaultProcessor3D() 621cdf0e10cSrcweir { 622cdf0e10cSrcweir } 623cdf0e10cSrcweir } // end of namespace processor3d 624cdf0e10cSrcweir } // end of namespace drawinglayer 625cdf0e10cSrcweir 626cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 627cdf0e10cSrcweir // eof 628