LCOV - code coverage report
Current view: top level - drawinglayer/source/primitive3d - sdrextrudeprimitive3d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 73 201 36.3 %
Date: 2012-08-25 Functions: 10 10 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 98 452 21.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx>
      30                 :            : #include <basegfx/matrix/b2dhommatrix.hxx>
      31                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      32                 :            : #include <basegfx/polygon/b3dpolypolygontools.hxx>
      33                 :            : #include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx>
      34                 :            : #include <basegfx/tools/canvastools.hxx>
      35                 :            : #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
      36                 :            : #include <drawinglayer/geometry/viewinformation3d.hxx>
      37                 :            : #include <drawinglayer/attribute/sdrfillattribute.hxx>
      38                 :            : #include <drawinglayer/attribute/sdrlineattribute.hxx>
      39                 :            : #include <drawinglayer/attribute/sdrshadowattribute.hxx>
      40                 :            : 
      41                 :            : //////////////////////////////////////////////////////////////////////////////
      42                 :            : 
      43                 :            : using namespace com::sun::star;
      44                 :            : 
      45                 :            : //////////////////////////////////////////////////////////////////////////////
      46                 :            : 
      47                 :            : namespace drawinglayer
      48                 :            : {
      49                 :            :     namespace primitive3d
      50                 :            :     {
      51                 :         24 :         Primitive3DSequence SdrExtrudePrimitive3D::create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const
      52                 :            :         {
      53                 :         24 :             Primitive3DSequence aRetval;
      54                 :            : 
      55                 :            :             // get slices
      56         [ +  - ]:         24 :             const Slice3DVector& rSliceVector = getSlices();
      57                 :            : 
      58         [ +  - ]:         24 :             if(!rSliceVector.empty())
      59                 :            :             {
      60                 :            :                 sal_uInt32 a;
      61                 :            : 
      62                 :            :                 // decide what to create
      63 [ +  - ][ +  - ]:         24 :                 const ::com::sun::star::drawing::NormalsKind eNormalsKind(getSdr3DObjectAttribute().getNormalsKind());
                 [ +  - ]
      64                 :         24 :                 const bool bCreateNormals(::com::sun::star::drawing::NormalsKind_SPECIFIC == eNormalsKind);
      65 [ +  - ][ +  - ]:         24 :                 const bool bCreateTextureCoordiantesX(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionX());
                 [ +  - ]
      66 [ +  - ][ +  - ]:         24 :                 const bool bCreateTextureCoordiantesY(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC == getSdr3DObjectAttribute().getTextureProjectionY());
                 [ +  - ]
      67         [ +  - ]:         24 :                 basegfx::B2DHomMatrix aTexTransform;
      68                 :            : 
      69 [ +  - ][ +  - ]:         24 :                 if(!getSdrLFSAttribute().getFill().isDefault() && (bCreateTextureCoordiantesX || bCreateTextureCoordiantesY))
         [ +  - ][ -  + ]
                 [ -  + ]
      70                 :            :                 {
      71         [ #  # ]:          0 :                     const basegfx::B2DPolygon aFirstPolygon(maCorrectedPolyPolygon.getB2DPolygon(0L));
      72         [ #  # ]:          0 :                     const double fFrontLength(basegfx::tools::getLength(aFirstPolygon));
      73         [ #  # ]:          0 :                     const double fFrontArea(basegfx::tools::getArea(aFirstPolygon));
      74                 :          0 :                     const double fSqrtFrontArea(sqrt(fFrontArea));
      75         [ #  # ]:          0 :                     double fRelativeTextureWidth = basegfx::fTools::equalZero(fSqrtFrontArea) ? 1.0 : fFrontLength / fSqrtFrontArea;
      76                 :          0 :                     fRelativeTextureWidth = (double)((sal_uInt32)(fRelativeTextureWidth - 0.5));
      77                 :            : 
      78         [ #  # ]:          0 :                     if(fRelativeTextureWidth < 1.0)
      79                 :            :                     {
      80                 :          0 :                         fRelativeTextureWidth = 1.0;
      81                 :            :                     }
      82                 :            : 
      83         [ #  # ]:          0 :                     aTexTransform.translate(-0.5, -0.5);
      84         [ #  # ]:          0 :                     aTexTransform.scale(-1.0, -1.0);
      85         [ #  # ]:          0 :                     aTexTransform.translate(0.5, 0.5);
      86 [ #  # ][ #  # ]:          0 :                     aTexTransform.scale(fRelativeTextureWidth, 1.0);
      87                 :            :                 }
      88                 :            : 
      89                 :            :                 // create geometry
      90         [ +  - ]:         24 :                 ::std::vector< basegfx::B3DPolyPolygon > aFill;
      91                 :            :                 extractPlanesFromSlice(aFill, rSliceVector,
      92                 :         24 :                     bCreateNormals, getSmoothHorizontalNormals(), getSmoothNormals(), getSmoothLids(), false,
      93 [ +  - ][ -  + ]:         48 :                     0.5, 0.6, bCreateTextureCoordiantesX || bCreateTextureCoordiantesY, aTexTransform);
                 [ +  - ]
      94                 :            : 
      95                 :            :                 // get full range
      96         [ +  - ]:         24 :                 const basegfx::B3DRange aRange(getRangeFrom3DGeometry(aFill));
      97                 :            : 
      98                 :            :                 // normal creation
      99 [ +  - ][ +  - ]:         24 :                 if(!getSdrLFSAttribute().getFill().isDefault())
     100                 :            :                 {
     101         [ -  + ]:         24 :                     if(::com::sun::star::drawing::NormalsKind_SPHERE == eNormalsKind)
     102                 :            :                     {
     103         [ #  # ]:          0 :                         applyNormalsKindSphereTo3DGeometry(aFill, aRange);
     104                 :            :                     }
     105         [ -  + ]:         24 :                     else if(::com::sun::star::drawing::NormalsKind_FLAT == eNormalsKind)
     106                 :            :                     {
     107         [ #  # ]:          0 :                         applyNormalsKindFlatTo3DGeometry(aFill);
     108                 :            :                     }
     109                 :            : 
     110 [ +  - ][ +  - ]:         24 :                     if(getSdr3DObjectAttribute().getNormalsInvert())
         [ +  - ][ -  + ]
     111                 :            :                     {
     112         [ #  # ]:          0 :                         applyNormalsInvertTo3DGeometry(aFill);
     113                 :            :                     }
     114                 :            :                 }
     115                 :            : 
     116                 :            :                 // texture coordinates
     117 [ +  - ][ +  - ]:         24 :                 if(!getSdrLFSAttribute().getFill().isDefault())
     118                 :            :                 {
     119                 :            :                     applyTextureTo3DGeometry(
     120                 :            :                         getSdr3DObjectAttribute().getTextureProjectionX(),
     121                 :            :                         getSdr3DObjectAttribute().getTextureProjectionY(),
     122                 :            :                         aFill,
     123                 :            :                         aRange,
     124 [ +  - ][ +  - ]:         24 :                         getTextureSize());
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     125                 :            :                 }
     126                 :            : 
     127 [ +  - ][ +  - ]:         24 :                 if(!getSdrLFSAttribute().getFill().isDefault())
     128                 :            :                 {
     129                 :            :                     // add fill
     130                 :            :                     aRetval = create3DPolyPolygonFillPrimitives(
     131                 :            :                         aFill,
     132                 :         24 :                         getTransform(),
     133                 :         24 :                         getTextureSize(),
     134                 :            :                         getSdr3DObjectAttribute(),
     135                 :         24 :                         getSdrLFSAttribute().getFill(),
     136   [ +  -  +  - ]:         72 :                         getSdrLFSAttribute().getFillFloatTransGradient());
         [ +  - ][ +  - ]
                 [ +  - ]
     137                 :            :                 }
     138                 :            :                 else
     139                 :            :                 {
     140                 :            :                     // create simplified 3d hit test geometry
     141                 :            :                     aRetval = createHiddenGeometryPrimitives3D(
     142                 :            :                         aFill,
     143                 :          0 :                         getTransform(),
     144                 :          0 :                         getTextureSize(),
     145   [ #  #  #  # ]:          0 :                         getSdr3DObjectAttribute());
         [ #  # ][ #  # ]
                 [ #  # ]
     146                 :            :                 }
     147                 :            : 
     148                 :            :                 // add line
     149 [ +  - ][ -  + ]:         24 :                 if(!getSdrLFSAttribute().getLine().isDefault())
     150                 :            :                 {
     151 [ #  # ][ #  # ]:          0 :                     if(getSdr3DObjectAttribute().getReducedLineGeometry())
         [ #  # ][ #  # ]
     152                 :            :                     {
     153                 :            :                         // create geometric outlines with reduced line geometry for chart.
     154         [ #  # ]:          0 :                         const basegfx::B3DPolyPolygon aVerLine(extractVerticalLinesFromSlice(rSliceVector));
     155         [ #  # ]:          0 :                         const sal_uInt32 nCount(aVerLine.count());
     156         [ #  # ]:          0 :                         basegfx::B3DPolyPolygon aReducedLoops;
     157         [ #  # ]:          0 :                         basegfx::B3DPolyPolygon aNewLineGeometry;
     158                 :            : 
     159                 :            :                         // sort out doubles (front and back planes when no edge rounding is done). Since
     160                 :            :                         // this is a line geometry merged from PolyPolygons, loop over all Polygons
     161         [ #  # ]:          0 :                         for(a = 0; a < nCount; a++)
     162                 :            :                         {
     163         [ #  # ]:          0 :                             const sal_uInt32 nReducedCount(aReducedLoops.count());
     164         [ #  # ]:          0 :                             const basegfx::B3DPolygon aCandidate(aVerLine.getB3DPolygon(a));
     165                 :          0 :                             bool bAdd(true);
     166                 :            : 
     167         [ #  # ]:          0 :                             if(nReducedCount)
     168                 :            :                             {
     169 [ #  # ][ #  # ]:          0 :                                 for(sal_uInt32 b(0); bAdd && b < nReducedCount; b++)
                 [ #  # ]
     170                 :            :                                 {
     171 [ #  # ][ #  # ]:          0 :                                     if(aCandidate == aReducedLoops.getB3DPolygon(b))
         [ #  # ][ #  # ]
     172                 :            :                                     {
     173                 :          0 :                                         bAdd = false;
     174                 :            :                                     }
     175                 :            :                                 }
     176                 :            :                             }
     177                 :            : 
     178         [ #  # ]:          0 :                             if(bAdd)
     179                 :            :                             {
     180         [ #  # ]:          0 :                                 aReducedLoops.append(aCandidate);
     181                 :            :                             }
     182         [ #  # ]:          0 :                         }
     183                 :            : 
     184                 :            :                         // from here work with reduced loops and reduced count without changing them
     185         [ #  # ]:          0 :                         const sal_uInt32 nReducedCount(aReducedLoops.count());
     186                 :            : 
     187         [ #  # ]:          0 :                         if(nReducedCount > 1)
     188                 :            :                         {
     189         [ #  # ]:          0 :                             for(sal_uInt32 b(1); b < nReducedCount; b++)
     190                 :            :                             {
     191                 :            :                                 // get loop pair
     192         [ #  # ]:          0 :                                 const basegfx::B3DPolygon aCandA(aReducedLoops.getB3DPolygon(b - 1));
     193         [ #  # ]:          0 :                                 const basegfx::B3DPolygon aCandB(aReducedLoops.getB3DPolygon(b));
     194                 :            : 
     195                 :            :                                 // for each loop pair create the connection edges
     196                 :            :                                 createReducedOutlines(
     197                 :            :                                     rViewInformation,
     198                 :          0 :                                     getTransform(),
     199                 :            :                                     aCandA,
     200                 :            :                                     aCandB,
     201         [ #  # ]:          0 :                                     aNewLineGeometry);
     202 [ #  # ][ #  # ]:          0 :                             }
     203                 :            :                         }
     204                 :            : 
     205                 :            :                         // add reduced loops themselves
     206         [ #  # ]:          0 :                         aNewLineGeometry.append(aReducedLoops);
     207                 :            : 
     208                 :            :                         // to create vertical edges at non-C1/C2 steady loops, use maCorrectedPolyPolygon
     209                 :            :                         // directly since the 3D Polygons do not suport this.
     210                 :            :                         //
     211                 :            :                         // Unfortunately there is no bezier polygon provided by the chart module; one reason is
     212                 :            :                         // that the API for extrude wants a 3D polygon geometry (for historical reasons, i guess)
     213                 :            :                         // and those have no beziers. Another reason is that he chart module uses self-created
     214                 :            :                         // stuff to create the 2D geometry (in ShapeFactory::createPieSegment), but this geometry
     215                 :            :                         // does not contain bezier infos, either. The only way which is possible for now is to 'detect'
     216                 :            :                         // candidates for vertical edges of pie segments by looking for the angles in the polygon.
     217                 :            :                         //
     218                 :            :                         // This is all not very well designed ATM. Ideally, the ReducedLineGeometry is responsible
     219                 :            :                         // for creating the outer geometry edges (createReducedOutlines), but for special edges
     220                 :            :                         // like the vertical ones for pie center and both start/end, the incarnation with the
     221                 :            :                         // knowledge about that it needs to create those and IS a pie segment -> in this case,
     222                 :            :                         // the chart itself.
     223         [ #  # ]:          0 :                         const sal_uInt32 nPolyCount(maCorrectedPolyPolygon.count());
     224                 :            : 
     225         [ #  # ]:          0 :                         for(sal_uInt32 c(0); c < nPolyCount; c++)
     226                 :            :                         {
     227         [ #  # ]:          0 :                             const basegfx::B2DPolygon aCandidate(maCorrectedPolyPolygon.getB2DPolygon(c));
     228         [ #  # ]:          0 :                             const sal_uInt32 nPointCount(aCandidate.count());
     229                 :            : 
     230         [ #  # ]:          0 :                             if(nPointCount > 2)
     231                 :            :                             {
     232                 :          0 :                                 sal_uInt32 nIndexA(nPointCount);
     233                 :          0 :                                 sal_uInt32 nIndexB(nPointCount);
     234                 :          0 :                                 sal_uInt32 nIndexC(nPointCount);
     235                 :            : 
     236         [ #  # ]:          0 :                                 for(sal_uInt32 d(0); d < nPointCount; d++)
     237                 :            :                                 {
     238                 :          0 :                                     const sal_uInt32 nPrevInd((d + nPointCount - 1) % nPointCount);
     239                 :          0 :                                     const sal_uInt32 nNextInd((d + 1) % nPointCount);
     240         [ #  # ]:          0 :                                     const basegfx::B2DPoint aPoint(aCandidate.getB2DPoint(d));
     241         [ #  # ]:          0 :                                     const basegfx::B2DVector aPrev(aCandidate.getB2DPoint(nPrevInd) - aPoint);
     242         [ #  # ]:          0 :                                     const basegfx::B2DVector aNext(aCandidate.getB2DPoint(nNextInd) - aPoint);
     243         [ #  # ]:          0 :                                     const double fAngle(aPrev.angle(aNext));
     244                 :            : 
     245                 :            :                                     // take each angle which deviates more than 10% from going straight as
     246                 :            :                                     // special edge. This will detect the two outer edges of pie segments,
     247                 :            :                                     // but not always the center one (think about a near 180 degree pie)
     248         [ #  # ]:          0 :                                     if(F_PI - fabs(fAngle) > F_PI * 0.1)
     249                 :            :                                     {
     250         [ #  # ]:          0 :                                         if(nPointCount == nIndexA)
     251                 :            :                                         {
     252                 :          0 :                                             nIndexA = d;
     253                 :            :                                         }
     254         [ #  # ]:          0 :                                         else if(nPointCount == nIndexB)
     255                 :            :                                         {
     256                 :          0 :                                             nIndexB = d;
     257                 :            :                                         }
     258         [ #  # ]:          0 :                                         else if(nPointCount == nIndexC)
     259                 :            :                                         {
     260                 :          0 :                                             nIndexC = d;
     261                 :          0 :                                             d = nPointCount;
     262                 :            :                                         }
     263                 :            :                                     }
     264                 :          0 :                                 }
     265                 :            : 
     266                 :          0 :                                 const bool bIndexAUsed(nIndexA != nPointCount);
     267                 :          0 :                                 const bool bIndexBUsed(nIndexB != nPointCount);
     268                 :          0 :                                 bool bIndexCUsed(nIndexC != nPointCount);
     269                 :            : 
     270         [ #  # ]:          0 :                                 if(bIndexCUsed)
     271                 :            :                                 {
     272                 :            :                                     // already three special edges found, so the center one was already detected
     273                 :            :                                     // and does not need to be searched
     274                 :            :                                 }
     275 [ #  # ][ #  # ]:          0 :                                 else if(bIndexAUsed && bIndexBUsed)
     276                 :            :                                 {
     277                 :            :                                     // outer edges detected (they are approx. 90 degrees), but center one not.
     278                 :            :                                     // Look with the knowledge that it's in-between the two found ones
     279         [ #  # ]:          0 :                                     if(((nIndexA + 2) % nPointCount) == nIndexB)
     280                 :            :                                     {
     281                 :          0 :                                         nIndexC = (nIndexA + 1) % nPointCount;
     282                 :            :                                     }
     283         [ #  # ]:          0 :                                     else if(((nIndexA + nPointCount - 2) % nPointCount) == nIndexB)
     284                 :            :                                     {
     285                 :          0 :                                         nIndexC = (nIndexA + nPointCount - 1) % nPointCount;
     286                 :            :                                     }
     287                 :            : 
     288                 :          0 :                                     bIndexCUsed = (nIndexC != nPointCount);
     289                 :            :                                 }
     290                 :            : 
     291         [ #  # ]:          0 :                                 if(bIndexAUsed)
     292                 :            :                                 {
     293         [ #  # ]:          0 :                                     const basegfx::B2DPoint aPoint(aCandidate.getB2DPoint(nIndexA));
     294                 :          0 :                                     const basegfx::B3DPoint aStart(aPoint.getX(), aPoint.getY(), 0.0);
     295                 :          0 :                                     const basegfx::B3DPoint aEnd(aPoint.getX(), aPoint.getY(), getDepth());
     296         [ #  # ]:          0 :                                     basegfx::B3DPolygon aToBeAdded;
     297                 :            : 
     298         [ #  # ]:          0 :                                     aToBeAdded.append(aStart);
     299         [ #  # ]:          0 :                                     aToBeAdded.append(aEnd);
     300 [ #  # ][ #  # ]:          0 :                                     aNewLineGeometry.append(aToBeAdded);
     301                 :            :                                 }
     302                 :            : 
     303         [ #  # ]:          0 :                                 if(bIndexBUsed)
     304                 :            :                                 {
     305         [ #  # ]:          0 :                                     const basegfx::B2DPoint aPoint(aCandidate.getB2DPoint(nIndexB));
     306                 :          0 :                                     const basegfx::B3DPoint aStart(aPoint.getX(), aPoint.getY(), 0.0);
     307                 :          0 :                                     const basegfx::B3DPoint aEnd(aPoint.getX(), aPoint.getY(), getDepth());
     308         [ #  # ]:          0 :                                     basegfx::B3DPolygon aToBeAdded;
     309                 :            : 
     310         [ #  # ]:          0 :                                     aToBeAdded.append(aStart);
     311         [ #  # ]:          0 :                                     aToBeAdded.append(aEnd);
     312 [ #  # ][ #  # ]:          0 :                                     aNewLineGeometry.append(aToBeAdded);
     313                 :            :                                 }
     314                 :            : 
     315         [ #  # ]:          0 :                                 if(bIndexCUsed)
     316                 :            :                                 {
     317         [ #  # ]:          0 :                                     const basegfx::B2DPoint aPoint(aCandidate.getB2DPoint(nIndexC));
     318                 :          0 :                                     const basegfx::B3DPoint aStart(aPoint.getX(), aPoint.getY(), 0.0);
     319                 :          0 :                                     const basegfx::B3DPoint aEnd(aPoint.getX(), aPoint.getY(), getDepth());
     320         [ #  # ]:          0 :                                     basegfx::B3DPolygon aToBeAdded;
     321                 :            : 
     322         [ #  # ]:          0 :                                     aToBeAdded.append(aStart);
     323         [ #  # ]:          0 :                                     aToBeAdded.append(aEnd);
     324 [ #  # ][ #  # ]:          0 :                                     aNewLineGeometry.append(aToBeAdded);
     325                 :            :                                 }
     326                 :            :                             }
     327         [ #  # ]:          0 :                         }
     328                 :            : 
     329                 :            :                         // append loops themselves
     330         [ #  # ]:          0 :                         aNewLineGeometry.append(aReducedLoops);
     331                 :            : 
     332 [ #  # ][ #  # ]:          0 :                         if(aNewLineGeometry.count())
     333                 :            :                         {
     334                 :            :                             const Primitive3DSequence aLines(create3DPolyPolygonLinePrimitives(
     335         [ #  # ]:          0 :                                 aNewLineGeometry, getTransform(), getSdrLFSAttribute().getLine()));
     336 [ #  # ][ #  # ]:          0 :                             appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aLines);
     337 [ #  # ][ #  # ]:          0 :                         }
                 [ #  # ]
     338                 :            :                     }
     339                 :            :                     else
     340                 :            :                     {
     341                 :            :                         // extract line geometry from slices
     342         [ #  # ]:          0 :                         const basegfx::B3DPolyPolygon aHorLine(extractHorizontalLinesFromSlice(rSliceVector, false));
     343         [ #  # ]:          0 :                         const basegfx::B3DPolyPolygon aVerLine(extractVerticalLinesFromSlice(rSliceVector));
     344                 :            : 
     345                 :            :                         // add horizontal lines
     346                 :            :                         const Primitive3DSequence aHorLines(create3DPolyPolygonLinePrimitives(
     347         [ #  # ]:          0 :                             aHorLine, getTransform(), getSdrLFSAttribute().getLine()));
     348         [ #  # ]:          0 :                         appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aHorLines);
     349                 :            : 
     350                 :            :                         // add vertical lines
     351                 :            :                         const Primitive3DSequence aVerLines(create3DPolyPolygonLinePrimitives(
     352         [ #  # ]:          0 :                             aVerLine, getTransform(), getSdrLFSAttribute().getLine()));
     353 [ #  # ][ #  # ]:          0 :                         appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aVerLines);
         [ #  # ][ #  # ]
                 [ #  # ]
     354                 :            :                     }
     355                 :            :                 }
     356                 :            : 
     357                 :            :                 // add shadow
     358 [ +  - ][ -  + ]:         24 :                 if(!getSdrLFSAttribute().getShadow().isDefault() && aRetval.hasElements())
         [ #  # ][ -  + ]
     359                 :            :                 {
     360                 :            :                     const Primitive3DSequence aShadow(createShadowPrimitive3D(
     361 [ #  # ][ #  # ]:          0 :                         aRetval, getSdrLFSAttribute().getShadow(), getSdr3DObjectAttribute().getShadow3D()));
         [ #  # ][ #  # ]
     362 [ #  # ][ #  # ]:          0 :                     appendPrimitive3DSequenceToPrimitive3DSequence(aRetval, aShadow);
     363         [ +  - ]:         24 :                 }
     364                 :            :             }
     365                 :            : 
     366                 :         24 :             return aRetval;
     367                 :            :         }
     368                 :            : 
     369                 :       3001 :         void SdrExtrudePrimitive3D::impCreateSlices()
     370                 :            :         {
     371                 :            :             // prepare the polygon. No double points, correct orientations and a correct
     372                 :            :             // outmost polygon are needed
     373                 :       3001 :             maCorrectedPolyPolygon = getPolyPolygon();
     374                 :       3001 :             maCorrectedPolyPolygon.removeDoublePoints();
     375         [ +  - ]:       3001 :             maCorrectedPolyPolygon = basegfx::tools::correctOrientations(maCorrectedPolyPolygon);
     376         [ +  - ]:       3001 :             maCorrectedPolyPolygon = basegfx::tools::correctOutmostPolygon(maCorrectedPolyPolygon);
     377                 :            : 
     378                 :            :             // prepare slices as geometry
     379                 :       3001 :             createExtrudeSlices(maSlices, maCorrectedPolyPolygon, getBackScale(), getDiagonal(), getDepth(), getCharacterMode(), getCloseFront(), getCloseBack());
     380                 :       3001 :         }
     381                 :            : 
     382                 :       3305 :         const Slice3DVector& SdrExtrudePrimitive3D::getSlices() const
     383                 :            :         {
     384                 :            :             // This can be made dependent of  getSdrLFSAttribute().getFill() and getSdrLFSAttribute().getLine()
     385                 :            :             // again when no longer geometry is needed for non-visible 3D objects as it is now for chart
     386 [ +  - ][ +  + ]:       3305 :             if(getPolyPolygon().count() && !maSlices.size())
                 [ +  + ]
     387                 :            :             {
     388         [ +  - ]:       3001 :                 ::osl::Mutex m_mutex;
     389 [ +  - ][ +  - ]:       3001 :                 const_cast< SdrExtrudePrimitive3D& >(*this).impCreateSlices();
     390                 :            :             }
     391                 :            : 
     392                 :       3305 :             return maSlices;
     393                 :            :         }
     394                 :            : 
     395                 :       3257 :         SdrExtrudePrimitive3D::SdrExtrudePrimitive3D(
     396                 :            :             const basegfx::B3DHomMatrix& rTransform,
     397                 :            :             const basegfx::B2DVector& rTextureSize,
     398                 :            :             const attribute::SdrLineFillShadowAttribute3D& rSdrLFSAttribute,
     399                 :            :             const attribute::Sdr3DObjectAttribute& rSdr3DObjectAttribute,
     400                 :            :             const basegfx::B2DPolyPolygon& rPolyPolygon,
     401                 :            :             double fDepth,
     402                 :            :             double fDiagonal,
     403                 :            :             double fBackScale,
     404                 :            :             bool bSmoothNormals,
     405                 :            :             bool bSmoothHorizontalNormals,
     406                 :            :             bool bSmoothLids,
     407                 :            :             bool bCharacterMode,
     408                 :            :             bool bCloseFront,
     409                 :            :             bool bCloseBack)
     410                 :            :         :   SdrPrimitive3D(rTransform, rTextureSize, rSdrLFSAttribute, rSdr3DObjectAttribute),
     411                 :            :             maCorrectedPolyPolygon(),
     412                 :            :             maSlices(),
     413                 :            :             maPolyPolygon(rPolyPolygon),
     414                 :            :             mfDepth(fDepth),
     415                 :            :             mfDiagonal(fDiagonal),
     416                 :            :             mfBackScale(fBackScale),
     417                 :            :             mpLastRLGViewInformation(0),
     418                 :            :             mbSmoothNormals(bSmoothNormals),
     419                 :            :             mbSmoothHorizontalNormals(bSmoothHorizontalNormals),
     420                 :            :             mbSmoothLids(bSmoothLids),
     421                 :            :             mbCharacterMode(bCharacterMode),
     422                 :            :             mbCloseFront(bCloseFront),
     423 [ +  - ][ +  - ]:       3257 :             mbCloseBack(bCloseBack)
                 [ +  - ]
     424                 :            :         {
     425                 :            :             // make sure depth is positive
     426         [ -  + ]:       3257 :             if(basegfx::fTools::lessOrEqual(getDepth(), 0.0))
     427                 :            :             {
     428                 :          0 :                 mfDepth = 0.0;
     429                 :            :             }
     430                 :            : 
     431                 :            :             // make sure the percentage value getDiagonal() is between 0.0 and 1.0
     432         [ +  + ]:       3257 :             if(basegfx::fTools::lessOrEqual(getDiagonal(), 0.0))
     433                 :            :             {
     434                 :       1687 :                 mfDiagonal = 0.0;
     435                 :            :             }
     436         [ -  + ]:       1570 :             else if(basegfx::fTools::moreOrEqual(getDiagonal(), 1.0))
     437                 :            :             {
     438                 :          0 :                 mfDiagonal = 1.0;
     439                 :            :             }
     440                 :            : 
     441                 :            :             // no close front/back when polygon is not closed
     442 [ +  - ][ +  - ]:       3257 :             if(getPolyPolygon().count() && !getPolyPolygon().getB2DPolygon(0L).isClosed())
         [ +  - ][ +  - ]
         [ -  + ][ +  - ]
                 [ +  - ]
           [ -  +  #  # ]
     443                 :            :             {
     444                 :          0 :                 mbCloseFront = mbCloseBack = false;
     445                 :            :             }
     446                 :            : 
     447                 :            :             // no edge rounding when not closing
     448 [ -  + ][ #  # ]:       3257 :             if(!getCloseFront() && !getCloseBack())
                 [ -  + ]
     449                 :            :             {
     450                 :          0 :                 mfDiagonal = 0.0;
     451                 :            :             }
     452                 :       3257 :         }
     453                 :            : 
     454 [ +  - ][ +  - ]:       3257 :         SdrExtrudePrimitive3D::~SdrExtrudePrimitive3D()
     455                 :            :         {
     456         [ -  + ]:       3257 :             if(mpLastRLGViewInformation)
     457                 :            :             {
     458 [ #  # ][ #  # ]:          0 :                 delete mpLastRLGViewInformation;
     459                 :            :             }
     460         [ -  + ]:       6514 :         }
     461                 :            : 
     462                 :       1756 :         bool SdrExtrudePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const
     463                 :            :         {
     464         [ +  + ]:       1756 :             if(SdrPrimitive3D::operator==(rPrimitive))
     465                 :            :             {
     466                 :       1721 :                 const SdrExtrudePrimitive3D& rCompare = static_cast< const SdrExtrudePrimitive3D& >(rPrimitive);
     467                 :            : 
     468                 :       1721 :                 return (getPolyPolygon() == rCompare.getPolyPolygon()
     469                 :        256 :                     && getDepth() == rCompare.getDepth()
     470                 :        256 :                     && getDiagonal() == rCompare.getDiagonal()
     471                 :        256 :                     && getBackScale() == rCompare.getBackScale()
     472                 :        256 :                     && getSmoothNormals() == rCompare.getSmoothNormals()
     473                 :        256 :                     && getSmoothHorizontalNormals() == rCompare.getSmoothHorizontalNormals()
     474                 :        256 :                     && getSmoothLids() == rCompare.getSmoothLids()
     475                 :        256 :                     && getCharacterMode() == rCompare.getCharacterMode()
     476                 :        256 :                     && getCloseFront() == rCompare.getCloseFront()
     477 [ +  - ][ +  +  :       3769 :                     && getCloseBack() == rCompare.getCloseBack());
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     478                 :            :             }
     479                 :            : 
     480                 :       1756 :             return false;
     481                 :            :         }
     482                 :            : 
     483                 :       3281 :         basegfx::B3DRange SdrExtrudePrimitive3D::getB3DRange(const geometry::ViewInformation3D& /*rViewInformation*/) const
     484                 :            :         {
     485                 :            :             // use defaut from sdrPrimitive3D which uses transformation expanded by line width/2
     486                 :            :             // The parent implementation which uses the ranges of the decomposition would be more
     487                 :            :             // corrcet, but for historical reasons it is necessary to do the old method: To get
     488                 :            :             // the range of the non-transformed geometry and transform it then. This leads to different
     489                 :            :             // ranges where the new method is more correct, but the need to keep the old behaviour
     490                 :            :             // has priority here.
     491                 :       3281 :             return get3DRangeFromSlices(getSlices());
     492                 :            :         }
     493                 :            : 
     494                 :         48 :         Primitive3DSequence SdrExtrudePrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const
     495                 :            :         {
     496 [ +  - ][ -  + ]:         48 :             if(getSdr3DObjectAttribute().getReducedLineGeometry())
     497                 :            :             {
     498   [ #  #  #  #  :          0 :                 if(!mpLastRLGViewInformation ||
           #  # ][ #  # ]
     499                 :          0 :                     (getBuffered3DDecomposition().hasElements()
     500                 :          0 :                         && *mpLastRLGViewInformation != rViewInformation))
     501                 :            :                 {
     502                 :            :                     // conditions of last local decomposition with reduced lines have changed. Remember
     503                 :            :                     // new one and clear current decompositiopn
     504         [ #  # ]:          0 :                     ::osl::Mutex m_mutex;
     505                 :          0 :                     SdrExtrudePrimitive3D* pThat = const_cast< SdrExtrudePrimitive3D* >(this);
     506 [ #  # ][ #  # ]:          0 :                     pThat->setBuffered3DDecomposition(Primitive3DSequence());
                 [ #  # ]
     507 [ #  # ][ #  # ]:          0 :                     delete pThat->mpLastRLGViewInformation;
     508 [ #  # ][ #  # ]:          0 :                     pThat->mpLastRLGViewInformation = new geometry::ViewInformation3D(rViewInformation);
                 [ #  # ]
     509                 :            :                 }
     510                 :            :             }
     511                 :            : 
     512                 :            :             // no test for buffering needed, call parent
     513                 :         48 :             return SdrPrimitive3D::get3DDecomposition(rViewInformation);
     514                 :            :         }
     515                 :            : 
     516                 :            :         // provide unique ID
     517                 :       3560 :         ImplPrimitrive3DIDBlock(SdrExtrudePrimitive3D, PRIMITIVE3D_ID_SDREXTRUDEPRIMITIVE3D)
     518                 :            : 
     519                 :            :     } // end of namespace primitive3d
     520                 :            : } // end of namespace drawinglayer
     521                 :            : 
     522                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10