LCOV - code coverage report
Current view: top level - drawinglayer/source/primitive3d - sdrextrudelathetools3d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 213 451 47.2 %
Date: 2012-08-25 Functions: 7 13 53.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 242 994 24.3 %

           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/sdrextrudelathetools3d.hxx>
      30                 :            : #include <basegfx/polygon/b2dpolypolygon.hxx>
      31                 :            : #include <basegfx/range/b2drange.hxx>
      32                 :            : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      33                 :            : #include <basegfx/matrix/b2dhommatrix.hxx>
      34                 :            : #include <basegfx/point/b3dpoint.hxx>
      35                 :            : #include <basegfx/polygon/b3dpolygon.hxx>
      36                 :            : #include <basegfx/polygon/b3dpolygontools.hxx>
      37                 :            : #include <basegfx/polygon/b3dpolypolygontools.hxx>
      38                 :            : #include <basegfx/range/b3drange.hxx>
      39                 :            : #include <basegfx/matrix/b3dhommatrix.hxx>
      40                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      41                 :            : #include <drawinglayer/geometry/viewinformation3d.hxx>
      42                 :            : #include <numeric>
      43                 :            : 
      44                 :            : //////////////////////////////////////////////////////////////////////////////
      45                 :            : // decompositon helpers for extrude/lathe (rotation) objects
      46                 :            : 
      47                 :            : namespace
      48                 :            : {
      49                 :            :     //////////////////////////////////////////////////////////////////////////////
      50                 :            :     // common helpers
      51                 :            : 
      52                 :          0 :     basegfx::B2DPolyPolygon impScalePolyPolygonOnCenter(
      53                 :            :         const basegfx::B2DPolyPolygon& rSource,
      54                 :            :         double fScale)
      55                 :            :     {
      56                 :          0 :         basegfx::B2DPolyPolygon aRetval(rSource);
      57                 :            : 
      58         [ #  # ]:          0 :         if(!basegfx::fTools::equalZero(fScale))
      59                 :            :         {
      60         [ #  # ]:          0 :             const basegfx::B2DRange aRange(basegfx::tools::getRange(rSource));
      61         [ #  # ]:          0 :             const basegfx::B2DPoint aCenter(aRange.getCenter());
      62         [ #  # ]:          0 :             basegfx::B2DHomMatrix aTrans;
      63                 :            : 
      64         [ #  # ]:          0 :             aTrans.translate(-aCenter.getX(), -aCenter.getY());
      65         [ #  # ]:          0 :             aTrans.scale(fScale, fScale);
      66         [ #  # ]:          0 :             aTrans.translate(aCenter.getX(), aCenter.getY());
      67 [ #  # ][ #  # ]:          0 :             aRetval.transform(aTrans);
      68                 :            :         }
      69                 :            : 
      70                 :          0 :         return aRetval;
      71                 :            :     }
      72                 :            : 
      73                 :       6002 :     void impGetOuterPolyPolygon(
      74                 :            :         basegfx::B2DPolyPolygon& rPolygon,
      75                 :            :         basegfx::B2DPolyPolygon& rOuterPolyPolygon,
      76                 :            :         double fOffset,
      77                 :            :         bool bCharacterMode)
      78                 :            :     {
      79                 :       6002 :         rOuterPolyPolygon = rPolygon;
      80                 :            : 
      81         [ +  + ]:       6002 :         if(basegfx::fTools::more(fOffset, 0.0))
      82                 :            :         {
      83         [ +  - ]:       3002 :             if(bCharacterMode)
      84                 :            :             {
      85                 :            :                 // grow the outside polygon and scale all polygons to original size. This is done
      86                 :            :                 // to avoid a shrink which potentially would lead to self-intersections, but changes
      87                 :            :                 // the original polygon -> not a precision step, so e.g. not usable for charts
      88         [ +  - ]:       3002 :                 const basegfx::B2DRange aRange(basegfx::tools::getRange(rPolygon));
      89 [ +  - ][ +  - ]:       3002 :                 rPolygon = basegfx::tools::growInNormalDirection(rPolygon, fOffset);
                 [ +  - ]
      90         [ +  - ]:       3002 :                 const basegfx::B2DRange aGrownRange(basegfx::tools::getRange(rPolygon));
      91 [ +  - ][ -  + ]:       3002 :                 const double fScaleX(basegfx::fTools::equalZero(aGrownRange.getWidth()) ? 1.0 : aRange.getWidth() / aGrownRange.getWidth());
         [ +  - ][ +  - ]
      92 [ +  - ][ -  + ]:       3002 :                 const double fScaleY(basegfx::fTools::equalZero(aGrownRange.getHeight())? 1.0 : aRange.getHeight() / aGrownRange.getHeight());
         [ +  - ][ +  - ]
      93         [ +  - ]:       3002 :                 basegfx::B2DHomMatrix aScaleTrans;
      94                 :            : 
      95 [ +  - ][ +  - ]:       3002 :                 aScaleTrans.translate(-aGrownRange.getMinX(), -aGrownRange.getMinY());
                 [ +  - ]
      96         [ +  - ]:       3002 :                 aScaleTrans.scale(fScaleX, fScaleY);
      97 [ +  - ][ +  - ]:       3002 :                 aScaleTrans.translate(aRange.getMinX(), aRange.getMinY());
                 [ +  - ]
      98         [ +  - ]:       3002 :                 rPolygon.transform(aScaleTrans);
      99 [ +  - ][ +  - ]:       3002 :                 rOuterPolyPolygon.transform(aScaleTrans);
     100                 :            :             }
     101                 :            :             else
     102                 :            :             {
     103                 :            :                 // use more precision, shrink the outer polygons. Since this may lead to self-intersections,
     104                 :            :                 // some kind of correction should be applied here after that step
     105         [ #  # ]:          0 :                 rOuterPolyPolygon = basegfx::tools::growInNormalDirection(rPolygon, -fOffset);
     106                 :          0 :                 basegfx::tools::correctGrowShrinkPolygonPair(rPolygon, rOuterPolyPolygon);
     107                 :            :             }
     108                 :            :         }
     109                 :       6002 :     }
     110                 :            : 
     111                 :         24 :     void impAddInBetweenFill(
     112                 :            :         basegfx::B3DPolyPolygon& rTarget,
     113                 :            :         const basegfx::B3DPolyPolygon& rPolA,
     114                 :            :         const basegfx::B3DPolyPolygon& rPolB,
     115                 :            :         double fTexVerStart,
     116                 :            :         double fTexVerStop,
     117                 :            :         bool bCreateNormals,
     118                 :            :         bool bCreateTextureCoordinates)
     119                 :            :     {
     120                 :            :         OSL_ENSURE(rPolA.count() == rPolB.count(), "impAddInBetweenFill: unequally sized polygons (!)");
     121                 :         24 :         const sal_uInt32 nPolygonCount(rPolA.count());
     122                 :            : 
     123         [ +  + ]:         48 :         for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     124                 :            :         {
     125         [ +  - ]:         24 :             const basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     126         [ +  - ]:         24 :             const basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     127                 :            :             OSL_ENSURE(aSubA.count() == aSubB.count(), "impAddInBetweenFill: unequally sized polygons (!)");
     128         [ +  - ]:         24 :             const sal_uInt32 nPointCount(aSubA.count());
     129                 :            : 
     130         [ +  - ]:         24 :             if(nPointCount)
     131                 :            :             {
     132 [ +  - ][ +  - ]:         24 :                 const sal_uInt32 nEdgeCount(aSubA.isClosed() ? nPointCount : nPointCount - 1L);
     133                 :         24 :                 double fTexHorMultiplicatorA(0.0), fTexHorMultiplicatorB(0.0);
     134                 :         24 :                 double fPolygonPosA(0.0), fPolygonPosB(0.0);
     135                 :            : 
     136         [ -  + ]:         24 :                 if(bCreateTextureCoordinates)
     137                 :            :                 {
     138         [ #  # ]:          0 :                     const double fPolygonLengthA(basegfx::tools::getLength(aSubA));
     139         [ #  # ]:          0 :                     fTexHorMultiplicatorA = basegfx::fTools::equalZero(fPolygonLengthA) ? 1.0 : 1.0 / fPolygonLengthA;
     140                 :            : 
     141         [ #  # ]:          0 :                     const double fPolygonLengthB(basegfx::tools::getLength(aSubB));
     142         [ #  # ]:          0 :                     fTexHorMultiplicatorB = basegfx::fTools::equalZero(fPolygonLengthB) ? 1.0 : 1.0 / fPolygonLengthB;
     143                 :            :                 }
     144                 :            : 
     145         [ +  + ]:        120 :                 for(sal_uInt32 b(0L); b < nEdgeCount; b++)
     146                 :            :                 {
     147                 :         96 :                     const sal_uInt32 nIndexA(b);
     148                 :         96 :                     const sal_uInt32 nIndexB((b + 1L) % nPointCount);
     149                 :            : 
     150         [ +  - ]:         96 :                     const basegfx::B3DPoint aStartA(aSubA.getB3DPoint(nIndexA));
     151         [ +  - ]:         96 :                     const basegfx::B3DPoint aEndA(aSubA.getB3DPoint(nIndexB));
     152         [ +  - ]:         96 :                     const basegfx::B3DPoint aStartB(aSubB.getB3DPoint(nIndexA));
     153         [ +  - ]:         96 :                     const basegfx::B3DPoint aEndB(aSubB.getB3DPoint(nIndexB));
     154                 :            : 
     155         [ +  - ]:         96 :                     basegfx::B3DPolygon aNew;
     156         [ +  - ]:         96 :                     aNew.setClosed(true);
     157                 :            : 
     158         [ +  - ]:         96 :                     aNew.append(aStartA);
     159         [ +  - ]:         96 :                     aNew.append(aStartB);
     160         [ +  - ]:         96 :                     aNew.append(aEndB);
     161         [ +  - ]:         96 :                     aNew.append(aEndA);
     162                 :            : 
     163         [ +  - ]:         96 :                     if(bCreateNormals)
     164                 :            :                     {
     165 [ +  - ][ +  - ]:         96 :                         aNew.setNormal(0L, aSubA.getNormal(nIndexA));
     166 [ +  - ][ +  - ]:         96 :                         aNew.setNormal(1L, aSubB.getNormal(nIndexA));
     167 [ +  - ][ +  - ]:         96 :                         aNew.setNormal(2L, aSubB.getNormal(nIndexB));
     168 [ +  - ][ +  - ]:         96 :                         aNew.setNormal(3L, aSubA.getNormal(nIndexB));
     169                 :            :                     }
     170                 :            : 
     171         [ -  + ]:         96 :                     if(bCreateTextureCoordinates)
     172                 :            :                     {
     173                 :          0 :                         const double fRelTexAL(fPolygonPosA * fTexHorMultiplicatorA);
     174         [ #  # ]:          0 :                         const double fEdgeLengthA(basegfx::B3DVector(aEndA - aStartA).getLength());
     175                 :          0 :                         fPolygonPosA += fEdgeLengthA;
     176                 :          0 :                         const double fRelTexAR(fPolygonPosA * fTexHorMultiplicatorA);
     177                 :            : 
     178                 :          0 :                         const double fRelTexBL(fPolygonPosB * fTexHorMultiplicatorB);
     179         [ #  # ]:          0 :                         const double fEdgeLengthB(basegfx::B3DVector(aEndB - aStartB).getLength());
     180                 :          0 :                         fPolygonPosB += fEdgeLengthB;
     181                 :          0 :                         const double fRelTexBR(fPolygonPosB * fTexHorMultiplicatorB);
     182                 :            : 
     183         [ #  # ]:          0 :                         aNew.setTextureCoordinate(0L, basegfx::B2DPoint(fRelTexAL, fTexVerStart));
     184         [ #  # ]:          0 :                         aNew.setTextureCoordinate(1L, basegfx::B2DPoint(fRelTexBL, fTexVerStop));
     185         [ #  # ]:          0 :                         aNew.setTextureCoordinate(2L, basegfx::B2DPoint(fRelTexBR, fTexVerStop));
     186         [ #  # ]:          0 :                         aNew.setTextureCoordinate(3L, basegfx::B2DPoint(fRelTexAR, fTexVerStart));
     187                 :            :                     }
     188                 :            : 
     189         [ +  - ]:         96 :                     rTarget.append(aNew);
     190         [ +  - ]:         96 :                 }
     191                 :            :             }
     192 [ +  - ][ +  - ]:         24 :         }
     193                 :         24 :     }
     194                 :            : 
     195                 :         48 :     void impSetNormal(
     196                 :            :         basegfx::B3DPolyPolygon& rCandidate,
     197                 :            :         const basegfx::B3DVector& rNormal)
     198                 :            :     {
     199         [ +  + ]:         96 :         for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
     200                 :            :         {
     201         [ +  - ]:         48 :             basegfx::B3DPolygon aSub(rCandidate.getB3DPolygon(a));
     202                 :            : 
     203 [ +  - ][ +  + ]:        240 :             for(sal_uInt32 b(0L); b < aSub.count(); b++)
     204                 :            :             {
     205         [ +  - ]:        192 :                 aSub.setNormal(b, rNormal);
     206                 :            :             }
     207                 :            : 
     208         [ +  - ]:         48 :             rCandidate.setB3DPolygon(a, aSub);
     209         [ +  - ]:         48 :         }
     210                 :         48 :     }
     211                 :            : 
     212                 :         24 :     void impCreateInBetweenNormals(
     213                 :            :         basegfx::B3DPolyPolygon& rPolA,
     214                 :            :         basegfx::B3DPolyPolygon& rPolB,
     215                 :            :         bool bSmoothHorizontalNormals)
     216                 :            :     {
     217                 :            :         OSL_ENSURE(rPolA.count() == rPolB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     218                 :            : 
     219         [ +  + ]:         48 :         for(sal_uInt32 a(0L); a < rPolA.count(); a++)
     220                 :            :         {
     221         [ +  - ]:         24 :             basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     222         [ +  - ]:         24 :             basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     223                 :            :             OSL_ENSURE(aSubA.count() == aSubB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     224         [ +  - ]:         24 :             const sal_uInt32 nPointCount(aSubA.count());
     225                 :            : 
     226         [ +  - ]:         24 :             if(nPointCount)
     227                 :            :             {
     228         [ +  - ]:         24 :                 basegfx::B3DPoint aPrevA(aSubA.getB3DPoint(nPointCount - 1L));
     229         [ +  - ]:         24 :                 basegfx::B3DPoint aCurrA(aSubA.getB3DPoint(0L));
     230         [ +  - ]:         24 :                 const bool bClosed(aSubA.isClosed());
     231                 :            : 
     232         [ +  + ]:        120 :                 for(sal_uInt32 b(0L); b < nPointCount; b++)
     233                 :            :                 {
     234                 :         96 :                     const sal_uInt32 nIndNext((b + 1L) % nPointCount);
     235         [ +  - ]:         96 :                     const basegfx::B3DPoint aNextA(aSubA.getB3DPoint(nIndNext));
     236         [ +  - ]:         96 :                     const basegfx::B3DPoint aCurrB(aSubB.getB3DPoint(b));
     237                 :            : 
     238                 :            :                     // vector to back
     239                 :         96 :                     basegfx::B3DVector aDepth(aCurrB - aCurrA);
     240         [ +  - ]:         96 :                     aDepth.normalize();
     241                 :            : 
     242 [ +  - ][ -  + ]:         96 :                     if(aDepth.equalZero())
     243                 :            :                     {
     244                 :            :                         // no difference, try to get depth from next point
     245         [ #  # ]:          0 :                         const basegfx::B3DPoint aNextB(aSubB.getB3DPoint(nIndNext));
     246                 :          0 :                         aDepth = aNextB - aNextA;
     247         [ #  # ]:          0 :                         aDepth.normalize();
     248                 :            :                     }
     249                 :            : 
     250                 :            :                     // vector to left (correct for non-closed lines)
     251 [ -  + ][ #  # ]:         96 :                     const bool bFirstAndNotClosed(!bClosed && 0L == b);
     252         [ -  + ]:         96 :                     basegfx::B3DVector aLeft(bFirstAndNotClosed ? aCurrA - aNextA : aPrevA - aCurrA);
     253         [ +  - ]:         96 :                     aLeft.normalize();
     254                 :            : 
     255                 :            :                     // create left normal
     256         [ +  - ]:         96 :                     const basegfx::B3DVector aNormalLeft(aDepth.getPerpendicular(aLeft));
     257                 :            : 
     258         [ +  - ]:         96 :                     if(bSmoothHorizontalNormals)
     259                 :            :                     {
     260                 :            :                         // vector to right (correct for non-closed lines)
     261 [ -  + ][ #  # ]:         96 :                         const bool bLastAndNotClosed(!bClosed && b + 1L == nPointCount);
     262         [ -  + ]:         96 :                         basegfx::B3DVector aRight(bLastAndNotClosed ? aCurrA - aPrevA : aNextA - aCurrA);
     263         [ +  - ]:         96 :                         aRight.normalize();
     264                 :            : 
     265                 :            :                         // create right normal
     266         [ +  - ]:         96 :                         const basegfx::B3DVector aNormalRight(aRight.getPerpendicular(aDepth));
     267                 :            : 
     268                 :            :                         // create smoothed in-between normal
     269                 :         96 :                         basegfx::B3DVector aNewNormal(aNormalLeft + aNormalRight);
     270         [ +  - ]:         96 :                         aNewNormal.normalize();
     271                 :            : 
     272                 :            :                         // set as new normal at polygons
     273         [ +  - ]:         96 :                         aSubA.setNormal(b, aNewNormal);
     274         [ +  - ]:         96 :                         aSubB.setNormal(b, aNewNormal);
     275                 :            :                     }
     276                 :            :                     else
     277                 :            :                     {
     278                 :            :                         // set aNormalLeft as new normal at polygons
     279         [ #  # ]:          0 :                         aSubA.setNormal(b, aNormalLeft);
     280         [ #  # ]:          0 :                         aSubB.setNormal(b, aNormalLeft);
     281                 :            :                     }
     282                 :            : 
     283                 :            :                     // prepare next step
     284         [ +  - ]:         96 :                     aPrevA = aCurrA;
     285         [ +  - ]:         96 :                     aCurrA = aNextA;
     286                 :         96 :                 }
     287                 :            : 
     288         [ +  - ]:         24 :                 rPolA.setB3DPolygon(a, aSubA);
     289         [ +  - ]:         24 :                 rPolB.setB3DPolygon(a, aSubB);
     290                 :            :             }
     291 [ +  - ][ +  - ]:         24 :         }
     292                 :         24 :     }
     293                 :            : 
     294                 :         48 :     void impMixNormals(
     295                 :            :         basegfx::B3DPolyPolygon& rPolA,
     296                 :            :         const basegfx::B3DPolyPolygon& rPolB,
     297                 :            :         double fWeightA)
     298                 :            :     {
     299                 :         48 :         const double fWeightB(1.0 - fWeightA);
     300                 :            :         OSL_ENSURE(rPolA.count() == rPolB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     301                 :            : 
     302         [ +  + ]:         96 :         for(sal_uInt32 a(0L); a < rPolA.count(); a++)
     303                 :            :         {
     304         [ +  - ]:         48 :             basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     305         [ +  - ]:         48 :             const basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     306                 :            :             OSL_ENSURE(aSubA.count() == aSubB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     307         [ +  - ]:         48 :             const sal_uInt32 nPointCount(aSubA.count());
     308                 :            : 
     309         [ +  + ]:        240 :             for(sal_uInt32 b(0L); b < nPointCount; b++)
     310                 :            :             {
     311         [ +  - ]:        192 :                 const basegfx::B3DVector aVA(aSubA.getNormal(b) * fWeightA);
     312         [ +  - ]:        192 :                 const basegfx::B3DVector aVB(aSubB.getNormal(b) * fWeightB);
     313                 :        192 :                 basegfx::B3DVector aVNew(aVA + aVB);
     314         [ +  - ]:        192 :                 aVNew.normalize();
     315         [ +  - ]:        192 :                 aSubA.setNormal(b, aVNew);
     316                 :        192 :             }
     317                 :            : 
     318         [ +  - ]:         48 :             rPolA.setB3DPolygon(a, aSubA);
     319 [ +  - ][ +  - ]:         48 :         }
     320                 :         48 :     }
     321                 :            : 
     322                 :          0 :     bool impHasCutWith(const basegfx::B2DPolygon& rPoly, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd)
     323                 :            :     {
     324                 :            :         // polygon is closed, one of the points is a member
     325                 :          0 :         const sal_uInt32 nPointCount(rPoly.count());
     326                 :            : 
     327         [ #  # ]:          0 :         if(nPointCount)
     328                 :            :         {
     329         [ #  # ]:          0 :             basegfx::B2DPoint aCurrent(rPoly.getB2DPoint(0));
     330                 :          0 :             const basegfx::B2DVector aVector(rEnd - rStart);
     331                 :            : 
     332         [ #  # ]:          0 :             for(sal_uInt32 a(0); a < nPointCount; a++)
     333                 :            :             {
     334                 :          0 :                 const sal_uInt32 nNextIndex((a + 1) % nPointCount);
     335         [ #  # ]:          0 :                 const basegfx::B2DPoint aNext(rPoly.getB2DPoint(nNextIndex));
     336                 :          0 :                 const basegfx::B2DVector aEdgeVector(aNext - aCurrent);
     337                 :            : 
     338         [ #  # ]:          0 :                 if(basegfx::tools::findCut(
     339                 :            :                     rStart, aVector,
     340         [ #  # ]:          0 :                     aCurrent, aEdgeVector))
     341                 :            :                 {
     342                 :          0 :                     return true;
     343                 :            :                 }
     344                 :            : 
     345         [ #  # ]:          0 :                 aCurrent = aNext;
     346 [ #  # ][ #  # ]:          0 :             }
                 [ #  # ]
     347                 :            :         }
     348                 :            : 
     349                 :          0 :         return false;
     350                 :            :     }
     351                 :            : } // end of anonymous namespace
     352                 :            : 
     353                 :            : //////////////////////////////////////////////////////////////////////////////
     354                 :            : 
     355                 :            : namespace drawinglayer
     356                 :            : {
     357                 :            :     namespace primitive3d
     358                 :            :     {
     359                 :          0 :         void createLatheSlices(
     360                 :            :             Slice3DVector& rSliceVector,
     361                 :            :             const basegfx::B2DPolyPolygon& rSource,
     362                 :            :             double fBackScale,
     363                 :            :             double fDiagonal,
     364                 :            :             double fRotation,
     365                 :            :             sal_uInt32 nSteps,
     366                 :            :             bool bCharacterMode,
     367                 :            :             bool bCloseFront,
     368                 :            :             bool bCloseBack)
     369                 :            :         {
     370 [ #  # ][ #  # ]:          0 :             if(basegfx::fTools::equalZero(fRotation) || 0L == nSteps)
                 [ #  # ]
     371                 :            :             {
     372                 :            :                 // no rotation or no steps, just one plane
     373 [ #  # ][ #  # ]:          0 :                 rSliceVector.push_back(Slice3D(rSource, basegfx::B3DHomMatrix()));
                 [ #  # ]
     374                 :            :             }
     375                 :            :             else
     376                 :            :             {
     377                 :          0 :                 const bool bBackScale(!basegfx::fTools::equal(fBackScale, 1.0));
     378 [ #  # ][ #  # ]:          0 :                 const bool bClosedRotation(!bBackScale && basegfx::fTools::equal(fRotation, F_2PI));
                 [ #  # ]
     379         [ #  # ]:          0 :                 basegfx::B2DPolyPolygon aFront(rSource);
     380         [ #  # ]:          0 :                 basegfx::B2DPolyPolygon aBack(rSource);
     381         [ #  # ]:          0 :                 basegfx::B3DHomMatrix aTransformBack;
     382         [ #  # ]:          0 :                 basegfx::B2DPolyPolygon aOuterBack;
     383                 :            : 
     384         [ #  # ]:          0 :                 if(bClosedRotation)
     385                 :            :                 {
     386                 :          0 :                     bCloseFront = bCloseBack = false;
     387                 :            :                 }
     388                 :            : 
     389         [ #  # ]:          0 :                 if(bBackScale)
     390                 :            :                 {
     391                 :            :                     // avoid null zoom
     392         [ #  # ]:          0 :                     if(basegfx::fTools::equalZero(fBackScale))
     393                 :            :                     {
     394                 :          0 :                         fBackScale = 0.000001;
     395                 :            :                     }
     396                 :            : 
     397                 :            :                     // back is scaled compared to front, create scaled version
     398 [ #  # ][ #  # ]:          0 :                     aBack = impScalePolyPolygonOnCenter(aBack, fBackScale);
                 [ #  # ]
     399                 :            :                 }
     400                 :            : 
     401 [ #  # ][ #  # ]:          0 :                 if(bCloseFront || bCloseBack)
     402                 :            :                 {
     403         [ #  # ]:          0 :                     const basegfx::B2DRange aBaseRange(basegfx::tools::getRange(aFront));
     404         [ #  # ]:          0 :                     const double fOuterLength(aBaseRange.getMaxX() * fRotation);
     405         [ #  # ]:          0 :                     const double fInnerLength(aBaseRange.getMinX() * fRotation);
     406                 :          0 :                     const double fAverageLength((fOuterLength + fInnerLength) * 0.5);
     407                 :            : 
     408         [ #  # ]:          0 :                     if(bCloseFront)
     409                 :            :                     {
     410                 :          0 :                         const double fOffsetLen((fAverageLength / 12.0) * fDiagonal);
     411         [ #  # ]:          0 :                         basegfx::B2DPolyPolygon aOuterFront;
     412         [ #  # ]:          0 :                         impGetOuterPolyPolygon(aFront, aOuterFront, fOffsetLen, bCharacterMode);
     413         [ #  # ]:          0 :                         basegfx::B3DHomMatrix aTransform;
     414         [ #  # ]:          0 :                         aTransform.translate(0.0, 0.0, fOffsetLen);
     415 [ #  # ][ #  # ]:          0 :                         rSliceVector.push_back(Slice3D(aOuterFront, aTransform, SLICETYPE3D_FRONTCAP));
         [ #  # ][ #  # ]
                 [ #  # ]
     416                 :            :                     }
     417                 :            : 
     418         [ #  # ]:          0 :                     if(bCloseBack)
     419                 :            :                     {
     420                 :          0 :                         const double fOffsetLen((fAverageLength / 12.0) * fDiagonal);
     421         [ #  # ]:          0 :                         impGetOuterPolyPolygon(aBack, aOuterBack, fOffsetLen, bCharacterMode);
     422         [ #  # ]:          0 :                         aTransformBack.translate(0.0, 0.0, -fOffsetLen);
     423         [ #  # ]:          0 :                         aTransformBack.rotate(0.0, fRotation, 0.0);
     424                 :            :                     }
     425                 :            :                 }
     426                 :            : 
     427                 :            :                 // add start polygon (a = 0L)
     428         [ #  # ]:          0 :                 if(!bClosedRotation)
     429                 :            :                 {
     430 [ #  # ][ #  # ]:          0 :                     rSliceVector.push_back(Slice3D(aFront, basegfx::B3DHomMatrix()));
         [ #  # ][ #  # ]
                 [ #  # ]
     431                 :            :                 }
     432                 :            : 
     433                 :            :                 // create segments (a + 1 .. nSteps)
     434                 :          0 :                 const double fStepSize(1.0 / (double)nSteps);
     435                 :            : 
     436         [ #  # ]:          0 :                 for(sal_uInt32 a(0L); a < nSteps; a++)
     437                 :            :                 {
     438                 :          0 :                     const double fStep((double)(a + 1L) * fStepSize);
     439 [ #  # ][ #  # ]:          0 :                     basegfx::B2DPolyPolygon aNewPoly(bBackScale ? basegfx::tools::interpolate(aFront, aBack, fStep) : aFront);
                 [ #  # ]
     440         [ #  # ]:          0 :                     basegfx::B3DHomMatrix aNewMat;
     441         [ #  # ]:          0 :                     aNewMat.rotate(0.0, fRotation * fStep, 0.0);
     442 [ #  # ][ #  # ]:          0 :                     rSliceVector.push_back(Slice3D(aNewPoly, aNewMat));
                 [ #  # ]
     443 [ #  # ][ #  # ]:          0 :                 }
     444                 :            : 
     445         [ #  # ]:          0 :                 if(bCloseBack)
     446                 :            :                 {
     447 [ #  # ][ #  # ]:          0 :                     rSliceVector.push_back(Slice3D(aOuterBack, aTransformBack, SLICETYPE3D_BACKCAP));
                 [ #  # ]
     448 [ #  # ][ #  # ]:          0 :                 }
         [ #  # ][ #  # ]
     449                 :            :             }
     450                 :          0 :         }
     451                 :            : 
     452                 :       3001 :         void createExtrudeSlices(
     453                 :            :             Slice3DVector& rSliceVector,
     454                 :            :             const basegfx::B2DPolyPolygon& rSource,
     455                 :            :             double fBackScale,
     456                 :            :             double fDiagonal,
     457                 :            :             double fDepth,
     458                 :            :             bool bCharacterMode,
     459                 :            :             bool bCloseFront,
     460                 :            :             bool bCloseBack)
     461                 :            :         {
     462         [ -  + ]:       3001 :             if(basegfx::fTools::equalZero(fDepth))
     463                 :            :             {
     464                 :            :                 // no depth, just one plane
     465 [ #  # ][ #  # ]:          0 :                 rSliceVector.push_back(Slice3D(rSource, basegfx::B3DHomMatrix()));
                 [ #  # ]
     466                 :            :             }
     467                 :            :             else
     468                 :            :             {
     469                 :            :                 // there is depth, create Polygons for front,back and their default depth positions
     470         [ +  - ]:       3001 :                 basegfx::B2DPolyPolygon aFront(rSource);
     471         [ +  - ]:       3001 :                 basegfx::B2DPolyPolygon aBack(rSource);
     472                 :       3001 :                 const bool bBackScale(!basegfx::fTools::equal(fBackScale, 1.0));
     473                 :       3001 :                 double fZFront(fDepth); // default depth for aFront
     474                 :       3001 :                 double fZBack(0.0); // default depth for aBack
     475         [ +  - ]:       3001 :                 basegfx::B2DPolyPolygon aOuterBack;
     476                 :            : 
     477         [ -  + ]:       3001 :                 if(bBackScale)
     478                 :            :                 {
     479                 :            :                     // avoid null zoom
     480         [ #  # ]:          0 :                     if(basegfx::fTools::equalZero(fBackScale))
     481                 :            :                     {
     482                 :          0 :                         fBackScale = 0.000001;
     483                 :            :                     }
     484                 :            : 
     485                 :            :                     // aFront is scaled compared to aBack, create scaled version
     486 [ #  # ][ #  # ]:          0 :                     aFront = impScalePolyPolygonOnCenter(aFront, fBackScale);
                 [ #  # ]
     487                 :            :                 }
     488                 :            : 
     489         [ +  - ]:       3001 :                 if(bCloseFront)
     490                 :            :                 {
     491                 :       3001 :                     const double fOffset(fDepth * fDiagonal * 0.5);
     492                 :       3001 :                     fZFront = fDepth - fOffset;
     493         [ +  - ]:       3001 :                     basegfx::B2DPolyPolygon aOuterFront;
     494         [ +  - ]:       3001 :                     impGetOuterPolyPolygon(aFront, aOuterFront, fOffset, bCharacterMode);
     495         [ +  - ]:       3001 :                     basegfx::B3DHomMatrix aTransformFront;
     496         [ +  - ]:       3001 :                     aTransformFront.translate(0.0, 0.0, fDepth);
     497 [ +  - ][ +  - ]:       3001 :                     rSliceVector.push_back(Slice3D(aOuterFront, aTransformFront, SLICETYPE3D_FRONTCAP));
         [ +  - ][ +  - ]
                 [ +  - ]
     498                 :            :                 }
     499                 :            : 
     500         [ +  - ]:       3001 :                 if(bCloseBack)
     501                 :            :                 {
     502                 :       3001 :                     const double fOffset(fDepth * fDiagonal * 0.5);
     503                 :       3001 :                     fZBack = fOffset;
     504         [ +  - ]:       3001 :                     impGetOuterPolyPolygon(aBack, aOuterBack, fOffset, bCharacterMode);
     505                 :            :                 }
     506                 :            : 
     507                 :            :                 // add front and back polygons at evtl. changed depths
     508                 :            :                 {
     509 [ +  - ][ +  - ]:       3001 :                     basegfx::B3DHomMatrix aTransformA, aTransformB;
     510                 :            : 
     511         [ +  - ]:       3001 :                     aTransformA.translate(0.0, 0.0, fZFront);
     512 [ +  - ][ +  - ]:       3001 :                     rSliceVector.push_back(Slice3D(aFront, aTransformA));
                 [ +  - ]
     513                 :            : 
     514         [ +  - ]:       3001 :                     aTransformB.translate(0.0, 0.0, fZBack);
     515 [ +  - ][ +  - ]:       3001 :                     rSliceVector.push_back(Slice3D(aBack, aTransformB));
         [ +  - ][ +  - ]
                 [ +  - ]
     516                 :            :                 }
     517                 :            : 
     518         [ +  - ]:       3001 :                 if(bCloseBack)
     519                 :            :                 {
     520 [ +  - ][ +  - ]:       3001 :                     rSliceVector.push_back(Slice3D(aOuterBack, basegfx::B3DHomMatrix(), SLICETYPE3D_BACKCAP));
         [ +  - ][ +  - ]
                 [ +  - ]
     521 [ +  - ][ +  - ]:       3001 :                 }
                 [ +  - ]
     522                 :            :             }
     523                 :       3001 :         }
     524                 :            : 
     525                 :          0 :         basegfx::B3DPolyPolygon extractHorizontalLinesFromSlice(const Slice3DVector& rSliceVector, bool bCloseHorLines)
     526                 :            :         {
     527                 :          0 :             basegfx::B3DPolyPolygon aRetval;
     528                 :          0 :             const sal_uInt32 nNumSlices(rSliceVector.size());
     529                 :            : 
     530         [ #  # ]:          0 :             if(nNumSlices)
     531                 :            :             {
     532 [ #  # ][ #  # ]:          0 :                 const sal_uInt32 nSlideSubPolygonCount(rSliceVector[0].getB3DPolyPolygon().count());
     533                 :            : 
     534         [ #  # ]:          0 :                 for(sal_uInt32 b(0); b < nSlideSubPolygonCount; b++)
     535                 :            :                 {
     536 [ #  # ][ #  # ]:          0 :                     const sal_uInt32 nSubPolygonPointCount(rSliceVector[0].getB3DPolyPolygon().getB3DPolygon(b).count());
         [ #  # ][ #  # ]
     537                 :            : 
     538         [ #  # ]:          0 :                     for(sal_uInt32 c(0); c < nSubPolygonPointCount; c++)
     539                 :            :                     {
     540         [ #  # ]:          0 :                         basegfx::B3DPolygon aNew;
     541                 :            : 
     542         [ #  # ]:          0 :                         for(sal_uInt32 d(0); d < nNumSlices; d++)
     543                 :            :                         {
     544                 :            :                             OSL_ENSURE(nSlideSubPolygonCount == rSliceVector[d].getB3DPolyPolygon().count(),
     545                 :            :                                 "Slice PolyPolygon with different Polygon count (!)");
     546                 :            :                             OSL_ENSURE(nSubPolygonPointCount == rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).count(),
     547                 :            :                                 "Slice Polygon with different point count (!)");
     548 [ #  # ][ #  # ]:          0 :                             aNew.append(rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).getB3DPoint(c));
         [ #  # ][ #  # ]
                 [ #  # ]
     549                 :            :                         }
     550                 :            : 
     551         [ #  # ]:          0 :                         aNew.setClosed(bCloseHorLines);
     552         [ #  # ]:          0 :                         aRetval.append(aNew);
     553         [ #  # ]:          0 :                     }
     554                 :            :                 }
     555                 :            :             }
     556                 :            : 
     557                 :          0 :             return aRetval;
     558                 :            :         }
     559                 :            : 
     560                 :          0 :         basegfx::B3DPolyPolygon  extractVerticalLinesFromSlice(const Slice3DVector& rSliceVector)
     561                 :            :         {
     562                 :          0 :             basegfx::B3DPolyPolygon aRetval;
     563                 :          0 :             const sal_uInt32 nNumSlices(rSliceVector.size());
     564                 :            : 
     565         [ #  # ]:          0 :             for(sal_uInt32 a(0L); a < nNumSlices; a++)
     566                 :            :             {
     567 [ #  # ][ #  # ]:          0 :                 aRetval.append(rSliceVector[a].getB3DPolyPolygon());
     568                 :            :             }
     569                 :            : 
     570                 :          0 :             return aRetval;
     571                 :            :         }
     572                 :            : 
     573                 :         24 :         void extractPlanesFromSlice(
     574                 :            :             ::std::vector< basegfx::B3DPolyPolygon >& rFill,
     575                 :            :             const Slice3DVector& rSliceVector,
     576                 :            :             bool bCreateNormals,
     577                 :            :             bool bSmoothHorizontalNormals,
     578                 :            :             bool bSmoothNormals,
     579                 :            :             bool bSmoothLids,
     580                 :            :             bool bClosed,
     581                 :            :             double fSmoothNormalsMix,
     582                 :            :             double fSmoothLidsMix,
     583                 :            :             bool bCreateTextureCoordinates,
     584                 :            :             const basegfx::B2DHomMatrix& rTexTransform)
     585                 :            :         {
     586                 :         24 :             const sal_uInt32 nNumSlices(rSliceVector.size());
     587                 :            : 
     588         [ +  - ]:         24 :             if(nNumSlices)
     589                 :            :             {
     590                 :            :                 // common parameters
     591         [ -  + ]:         24 :                 const sal_uInt32 nLoopCount(bClosed ? nNumSlices : nNumSlices - 1L);
     592         [ +  - ]:         24 :                 basegfx::B3DPolyPolygon aEdgeRounding;
     593                 :            :                 sal_uInt32 a;
     594                 :            : 
     595                 :            :                 // tetxture parameters
     596                 :         24 :                 double fInvTexHeight(1.0);
     597                 :         24 :                 double fTexHeightPos(0.0);
     598                 :         24 :                 double fTexStart(0.0);
     599                 :         24 :                 double fTexStop(1.0);
     600         [ +  - ]:         24 :                 ::std::vector<double> aTexHeightArray;
     601         [ +  - ]:         24 :                 basegfx::B3DRange aTexRangeFront;
     602         [ +  - ]:         24 :                 basegfx::B3DRange aTexRangeBack;
     603                 :            : 
     604         [ -  + ]:         24 :                 if(bCreateTextureCoordinates)
     605                 :            :                 {
     606 [ #  # ][ #  # ]:          0 :                     aTexRangeFront = basegfx::tools::getRange(rSliceVector[0L].getB3DPolyPolygon());
     607 [ #  # ][ #  # ]:          0 :                     aTexRangeBack = basegfx::tools::getRange(rSliceVector[nNumSlices - 1L].getB3DPolyPolygon());
     608                 :            : 
     609 [ #  # ][ #  # ]:          0 :                     if(aTexRangeBack.getDepth() > aTexRangeBack.getWidth())
                 [ #  # ]
     610                 :            :                     {
     611                 :            :                         // last polygon is rotated so that depth is bigger than width, exchange X and Z
     612                 :            :                         // for making applyDefaultTextureCoordinatesParallel use Z instead of X for
     613                 :            :                         // horizontal texture coordinate
     614                 :            :                         aTexRangeBack = basegfx::B3DRange(
     615                 :            :                             aTexRangeBack.getMinZ(), aTexRangeBack.getMinY(), aTexRangeBack.getMinX(),
     616 [ #  # ][ #  # ]:          0 :                             aTexRangeBack.getMaxZ(), aTexRangeBack.getMaxY(), aTexRangeBack.getMaxX());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     617                 :            :                     }
     618                 :            : 
     619 [ #  # ][ #  # ]:          0 :                     basegfx::B3DPoint aCenter(basegfx::tools::getRange(rSliceVector[0L].getB3DPolyPolygon()).getCenter());
                 [ #  # ]
     620                 :            : 
     621         [ #  # ]:          0 :                     for(a = 0L; a < nLoopCount; a++)
     622                 :            :                     {
     623 [ #  # ][ #  # ]:          0 :                         const basegfx::B3DPoint aNextCenter(basegfx::tools::getRange(rSliceVector[(a + 1L) % nNumSlices].getB3DPolyPolygon()).getCenter());
                 [ #  # ]
     624         [ #  # ]:          0 :                         const double fLength(basegfx::B3DVector(aNextCenter - aCenter).getLength());
     625         [ #  # ]:          0 :                         aTexHeightArray.push_back(fLength);
     626         [ #  # ]:          0 :                         aCenter = aNextCenter;
     627                 :          0 :                     }
     628                 :            : 
     629         [ #  # ]:          0 :                     const double fTexHeight(::std::accumulate(aTexHeightArray.begin(), aTexHeightArray.end(), 0.0));
     630                 :            : 
     631         [ #  # ]:          0 :                     if(!basegfx::fTools::equalZero(fTexHeight))
     632                 :            :                     {
     633                 :          0 :                         fInvTexHeight = 1.0 / fTexHeight;
     634                 :          0 :                     }
     635                 :            :                 }
     636                 :            : 
     637         [ +  - ]:         24 :                 if(nLoopCount)
     638                 :            :                 {
     639         [ +  + ]:         96 :                     for(a = 0L; a < nLoopCount; a++)
     640                 :            :                     {
     641         [ +  - ]:         72 :                         const Slice3D& rSliceA(rSliceVector[a]);
     642         [ +  - ]:         72 :                         const Slice3D& rSliceB(rSliceVector[(a + 1L) % nNumSlices]);
     643 [ +  + ][ +  + ]:         72 :                         const bool bAcceptPair(SLICETYPE3D_REGULAR == rSliceA.getSliceType() && SLICETYPE3D_REGULAR == rSliceB.getSliceType());
     644         [ +  - ]:         72 :                         basegfx::B3DPolyPolygon aPolA(rSliceA.getB3DPolyPolygon());
     645         [ +  - ]:         72 :                         basegfx::B3DPolyPolygon aPolB(rSliceB.getB3DPolyPolygon());
     646                 :            : 
     647         [ +  + ]:         72 :                         if(bAcceptPair)
     648                 :            :                         {
     649         [ +  - ]:         24 :                             if(bCreateNormals)
     650                 :            :                             {
     651         [ +  - ]:         24 :                                 impCreateInBetweenNormals(aPolB, aPolA, bSmoothHorizontalNormals);
     652                 :            :                             }
     653                 :            : 
     654                 :            :                             {
     655                 :         24 :                                 const sal_uInt32 nIndPrev((a + nNumSlices - 1L) % nNumSlices);
     656         [ +  - ]:         24 :                                 const Slice3D& rSlicePrev(rSliceVector[nIndPrev]);
     657         [ +  - ]:         24 :                                 basegfx::B3DPolyPolygon aPrev(rSlicePrev.getB3DPolyPolygon());
     658         [ +  - ]:         24 :                                 basegfx::B3DPolyPolygon aPolAA(rSliceA.getB3DPolyPolygon());
     659                 :            : 
     660         [ +  - ]:         24 :                                 if(SLICETYPE3D_FRONTCAP == rSlicePrev.getSliceType())
     661                 :            :                                 {
     662         [ +  - ]:         24 :                                     basegfx::B3DPolyPolygon aFront(rSlicePrev.getB3DPolyPolygon());
     663         [ +  - ]:         24 :                                     const bool bHasSlant(aPolAA != aPrev);
     664                 :            : 
     665         [ -  + ]:         24 :                                     if(bCreateTextureCoordinates)
     666                 :            :                                     {
     667 [ #  # ][ #  # ]:          0 :                                         aFront = basegfx::tools::applyDefaultTextureCoordinatesParallel(aFront, aTexRangeFront);
                 [ #  # ]
     668                 :            :                                     }
     669                 :            : 
     670         [ +  - ]:         24 :                                     if(bCreateNormals)
     671                 :            :                                     {
     672                 :         24 :                                         basegfx::B3DVector aNormal(0.0, 0.0, -1.0);
     673                 :            : 
     674 [ +  - ][ +  - ]:         24 :                                         if(aFront.count())
     675                 :            :                                         {
     676 [ +  - ][ +  - ]:         24 :                                             aNormal = -aFront.getB3DPolygon(0L).getNormal();
                 [ +  - ]
     677                 :            :                                         }
     678                 :            : 
     679         [ +  - ]:         24 :                                         impSetNormal(aFront, aNormal);
     680                 :            : 
     681         [ -  + ]:         24 :                                         if(bHasSlant)
     682                 :            :                                         {
     683         [ #  # ]:          0 :                                             impCreateInBetweenNormals(aPolAA, aPrev, bSmoothHorizontalNormals);
     684                 :            : 
     685         [ #  # ]:          0 :                                             if(bSmoothNormals)
     686                 :            :                                             {
     687                 :            :                                                 // smooth and copy
     688         [ #  # ]:          0 :                                                 impMixNormals(aPolA, aPolAA, fSmoothNormalsMix);
     689         [ #  # ]:          0 :                                                 aPolAA = aPolA;
     690                 :            :                                             }
     691                 :            :                                             else
     692                 :            :                                             {
     693                 :            :                                                 // take over from surface
     694         [ #  # ]:          0 :                                                 aPolAA = aPolA;
     695                 :            :                                             }
     696                 :            : 
     697         [ #  # ]:          0 :                                             if(bSmoothLids)
     698                 :            :                                             {
     699                 :            :                                                 // smooth and copy
     700         [ #  # ]:          0 :                                                 impMixNormals(aFront, aPrev, fSmoothLidsMix);
     701         [ #  # ]:          0 :                                                 aPrev = aFront;
     702                 :            :                                             }
     703                 :            :                                             else
     704                 :            :                                             {
     705                 :            :                                                 // take over from front
     706         [ #  # ]:          0 :                                                 aPrev = aFront;
     707                 :            :                                             }
     708                 :            :                                         }
     709                 :            :                                         else
     710                 :            :                                         {
     711         [ +  - ]:         24 :                                             if(bSmoothNormals)
     712                 :            :                                             {
     713                 :            :                                                 // smooth
     714         [ +  - ]:         24 :                                                 impMixNormals(aPolA, aFront, fSmoothNormalsMix);
     715                 :            :                                             }
     716                 :            : 
     717         [ -  + ]:         24 :                                             if(bSmoothLids)
     718                 :            :                                             {
     719                 :            :                                                 // smooth and copy
     720         [ #  # ]:          0 :                                                 impMixNormals(aFront, aPolA, fSmoothLidsMix);
     721         [ #  # ]:          0 :                                                 aPolA = aFront;
     722                 :            :                                             }
     723                 :         24 :                                         }
     724                 :            :                                     }
     725                 :            : 
     726         [ -  + ]:         24 :                                     if(bHasSlant)
     727                 :            :                                     {
     728         [ #  # ]:          0 :                                         if(bCreateTextureCoordinates)
     729                 :            :                                         {
     730                 :          0 :                                             fTexStart = fTexHeightPos * fInvTexHeight;
     731         [ #  # ]:          0 :                                             fTexStop = (fTexHeightPos - aTexHeightArray[(a + nLoopCount - 1L) % nLoopCount]) * fInvTexHeight;
     732                 :            :                                         }
     733                 :            : 
     734         [ #  # ]:          0 :                                         impAddInBetweenFill(aEdgeRounding, aPolAA, aPrev, fTexStart, fTexStop, bCreateNormals, bCreateTextureCoordinates);
     735                 :            :                                     }
     736                 :            : 
     737         [ +  - ]:         24 :                                     aFront.flip();
     738 [ +  - ][ +  - ]:         24 :                                     rFill.push_back(aFront);
     739                 :            :                                 }
     740                 :            :                                 else
     741                 :            :                                 {
     742 [ #  # ][ #  # ]:          0 :                                     if(bCreateNormals && bSmoothNormals && (nIndPrev != a + 1L))
                 [ #  # ]
     743                 :            :                                     {
     744         [ #  # ]:          0 :                                         impCreateInBetweenNormals(aPolAA, aPrev, bSmoothHorizontalNormals);
     745         [ #  # ]:          0 :                                         impMixNormals(aPolA, aPolAA, 0.5);
     746                 :            :                                     }
     747 [ +  - ][ +  - ]:         24 :                                 }
     748                 :            :                             }
     749                 :            : 
     750                 :            :                             {
     751                 :         24 :                                 const sal_uInt32 nIndNext((a + 2L) % nNumSlices);
     752         [ +  - ]:         24 :                                 const Slice3D& rSliceNext(rSliceVector[nIndNext]);
     753         [ +  - ]:         24 :                                 basegfx::B3DPolyPolygon aNext(rSliceNext.getB3DPolyPolygon());
     754         [ +  - ]:         24 :                                 basegfx::B3DPolyPolygon aPolBB(rSliceB.getB3DPolyPolygon());
     755                 :            : 
     756         [ +  - ]:         24 :                                 if(SLICETYPE3D_BACKCAP == rSliceNext.getSliceType())
     757                 :            :                                 {
     758         [ +  - ]:         24 :                                     basegfx::B3DPolyPolygon aBack(rSliceNext.getB3DPolyPolygon());
     759         [ +  - ]:         24 :                                     const bool bHasSlant(aPolBB != aNext);
     760                 :            : 
     761         [ -  + ]:         24 :                                     if(bCreateTextureCoordinates)
     762                 :            :                                     {
     763 [ #  # ][ #  # ]:          0 :                                         aBack = basegfx::tools::applyDefaultTextureCoordinatesParallel(aBack, aTexRangeBack);
                 [ #  # ]
     764                 :            :                                     }
     765                 :            : 
     766         [ +  - ]:         24 :                                     if(bCreateNormals)
     767                 :            :                                     {
     768 [ +  - ][ +  - ]:         24 :                                         const basegfx::B3DVector aNormal(aBack.count() ? aBack.getB3DPolygon(0L).getNormal() : basegfx::B3DVector(0.0, 0.0, 1.0));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ #  # ]
     769         [ +  - ]:         24 :                                         impSetNormal(aBack, aNormal);
     770                 :            : 
     771         [ -  + ]:         24 :                                         if(bHasSlant)
     772                 :            :                                         {
     773         [ #  # ]:          0 :                                             impCreateInBetweenNormals(aNext, aPolBB, bSmoothHorizontalNormals);
     774                 :            : 
     775         [ #  # ]:          0 :                                             if(bSmoothNormals)
     776                 :            :                                             {
     777                 :            :                                                 // smooth and copy
     778         [ #  # ]:          0 :                                                 impMixNormals(aPolB, aPolBB, fSmoothNormalsMix);
     779         [ #  # ]:          0 :                                                 aPolBB = aPolB;
     780                 :            :                                             }
     781                 :            :                                             else
     782                 :            :                                             {
     783                 :            :                                                 // take over from surface
     784         [ #  # ]:          0 :                                                 aPolBB = aPolB;
     785                 :            :                                             }
     786                 :            : 
     787         [ #  # ]:          0 :                                             if(bSmoothLids)
     788                 :            :                                             {
     789                 :            :                                                 // smooth and copy
     790         [ #  # ]:          0 :                                                 impMixNormals(aBack, aNext, fSmoothLidsMix);
     791         [ #  # ]:          0 :                                                 aNext = aBack;
     792                 :            :                                             }
     793                 :            :                                             else
     794                 :            :                                             {
     795                 :            :                                                 // take over from back
     796         [ #  # ]:          0 :                                                 aNext = aBack;
     797                 :            :                                             }
     798                 :            :                                         }
     799                 :            :                                         else
     800                 :            :                                         {
     801         [ +  - ]:         24 :                                             if(bSmoothNormals)
     802                 :            :                                             {
     803                 :            :                                                 // smooth
     804         [ +  - ]:         24 :                                                 impMixNormals(aPolB, aBack, fSmoothNormalsMix);
     805                 :            :                                             }
     806                 :            : 
     807         [ -  + ]:         24 :                                             if(bSmoothLids)
     808                 :            :                                             {
     809                 :            :                                                 // smooth and copy
     810         [ #  # ]:          0 :                                                 impMixNormals(aBack, aPolB, fSmoothLidsMix);
     811         [ #  # ]:          0 :                                                 aPolB = aBack;
     812                 :            :                                             }
     813                 :         24 :                                         }
     814                 :            :                                     }
     815                 :            : 
     816         [ -  + ]:         24 :                                     if(bHasSlant)
     817                 :            :                                     {
     818         [ #  # ]:          0 :                                         if(bCreateTextureCoordinates)
     819                 :            :                                         {
     820 [ #  # ][ #  # ]:          0 :                                             fTexStart = (fTexHeightPos + aTexHeightArray[a] + aTexHeightArray[(a + 1L) % nLoopCount]) * fInvTexHeight;
     821         [ #  # ]:          0 :                                             fTexStop = (fTexHeightPos + aTexHeightArray[a]) * fInvTexHeight;
     822                 :            :                                         }
     823                 :            : 
     824         [ #  # ]:          0 :                                         impAddInBetweenFill(aEdgeRounding, aNext, aPolBB, fTexStart, fTexStop, bCreateNormals, bCreateTextureCoordinates);
     825                 :            :                                     }
     826                 :            : 
     827 [ +  - ][ +  - ]:         24 :                                     rFill.push_back(aBack);
     828                 :            :                                 }
     829                 :            :                                 else
     830                 :            :                                 {
     831 [ #  # ][ #  # ]:          0 :                                     if(bCreateNormals && bSmoothNormals && (nIndNext != a))
                 [ #  # ]
     832                 :            :                                     {
     833         [ #  # ]:          0 :                                         impCreateInBetweenNormals(aNext, aPolBB, bSmoothHorizontalNormals);
     834         [ #  # ]:          0 :                                         impMixNormals(aPolB, aPolBB, 0.5);
     835                 :            :                                     }
     836 [ +  - ][ +  - ]:         24 :                                 }
     837                 :            :                             }
     838                 :            : 
     839         [ -  + ]:         24 :                             if(bCreateTextureCoordinates)
     840                 :            :                             {
     841         [ #  # ]:          0 :                                 fTexStart = (fTexHeightPos + aTexHeightArray[a]) * fInvTexHeight;
     842                 :          0 :                                 fTexStop = fTexHeightPos * fInvTexHeight;
     843                 :            :                             }
     844                 :            : 
     845         [ +  - ]:         24 :                             impAddInBetweenFill(aEdgeRounding, aPolB, aPolA, fTexStart, fTexStop, bCreateNormals, bCreateTextureCoordinates);
     846                 :            :                         }
     847                 :            : 
     848         [ -  + ]:         72 :                         if(bCreateTextureCoordinates)
     849                 :            :                         {
     850         [ #  # ]:          0 :                             fTexHeightPos += aTexHeightArray[a];
     851                 :            :                         }
     852 [ +  - ][ +  - ]:         72 :                     }
     853                 :            :                 }
     854                 :            :                 else
     855                 :            :                 {
     856                 :            :                     // no loop, but a single slice (1 == nNumSlices), create a filling from the single
     857                 :            :                     // front plane
     858         [ #  # ]:          0 :                     const Slice3D& rSlice(rSliceVector[0]);
     859         [ #  # ]:          0 :                     basegfx::B3DPolyPolygon aFront(rSlice.getB3DPolyPolygon());
     860                 :            : 
     861         [ #  # ]:          0 :                     if(bCreateTextureCoordinates)
     862                 :            :                     {
     863 [ #  # ][ #  # ]:          0 :                         aFront = basegfx::tools::applyDefaultTextureCoordinatesParallel(aFront, aTexRangeFront);
                 [ #  # ]
     864                 :            :                     }
     865                 :            : 
     866         [ #  # ]:          0 :                     if(bCreateNormals)
     867                 :            :                     {
     868                 :          0 :                         basegfx::B3DVector aNormal(0.0, 0.0, -1.0);
     869                 :            : 
     870 [ #  # ][ #  # ]:          0 :                         if(aFront.count())
     871                 :            :                         {
     872 [ #  # ][ #  # ]:          0 :                             aNormal = -aFront.getB3DPolygon(0L).getNormal();
                 [ #  # ]
     873                 :            :                         }
     874                 :            : 
     875         [ #  # ]:          0 :                         impSetNormal(aFront, aNormal);
     876                 :            :                     }
     877                 :            : 
     878         [ #  # ]:          0 :                     aFront.flip();
     879 [ #  # ][ #  # ]:          0 :                     rFill.push_back(aFront);
     880                 :            :                 }
     881                 :            : 
     882         [ -  + ]:         24 :                 if(bCreateTextureCoordinates)
     883                 :            :                 {
     884         [ #  # ]:          0 :                     aEdgeRounding.transformTextureCoordiantes(rTexTransform);
     885                 :            :                 }
     886                 :            : 
     887 [ +  - ][ +  + ]:        120 :                 for(a = 0L; a < aEdgeRounding.count(); a++)
     888                 :            :                 {
     889 [ +  - ][ +  - ]:         96 :                     rFill.push_back(basegfx::B3DPolyPolygon(aEdgeRounding.getB3DPolygon(a)));
         [ +  - ][ +  - ]
                 [ +  - ]
     890         [ +  - ]:         24 :                 }
     891                 :            :             }
     892                 :         24 :         }
     893                 :            : 
     894                 :          0 :         void createReducedOutlines(
     895                 :            :             const geometry::ViewInformation3D& rViewInformation,
     896                 :            :             const basegfx::B3DHomMatrix& rObjectTransform,
     897                 :            :             const basegfx::B3DPolygon& rLoopA,
     898                 :            :             const basegfx::B3DPolygon& rLoopB,
     899                 :            :             basegfx::B3DPolyPolygon& rTarget)
     900                 :            :         {
     901                 :          0 :             const sal_uInt32 nPointCount(rLoopA.count());
     902                 :            : 
     903                 :            :             // with idetic polygons there are no outlines
     904         [ #  # ]:          0 :             if(rLoopA != rLoopB)
     905                 :            :             {
     906 [ #  # ][ #  # ]:          0 :                 if(nPointCount && nPointCount == rLoopB.count())
                 [ #  # ]
     907                 :            :                 {
     908 [ #  # ][ #  # ]:          0 :                     const basegfx::B3DHomMatrix aObjectTransform(rViewInformation.getObjectToView() * rObjectTransform);
     909         [ #  # ]:          0 :                     const basegfx::B2DPolygon a2DLoopA(basegfx::tools::createB2DPolygonFromB3DPolygon(rLoopA, aObjectTransform));
     910         [ #  # ]:          0 :                     const basegfx::B2DPolygon a2DLoopB(basegfx::tools::createB2DPolygonFromB3DPolygon(rLoopB, aObjectTransform));
     911 [ #  # ][ #  # ]:          0 :                     const basegfx::B2DPoint a2DCenterA(a2DLoopA.getB2DRange().getCenter());
     912 [ #  # ][ #  # ]:          0 :                     const basegfx::B2DPoint a2DCenterB(a2DLoopB.getB2DRange().getCenter());
     913                 :            : 
     914                 :            :                     // without detectable Y-Axis there are no outlines
     915         [ #  # ]:          0 :                     if(!a2DCenterA.equal(a2DCenterB))
     916                 :            :                     {
     917                 :            :                         // search for outmost left and right inter-loop-edges which do not cut the loops
     918                 :          0 :                         const basegfx::B2DPoint aCommonCenter(basegfx::average(a2DCenterA, a2DCenterB));
     919                 :          0 :                         const basegfx::B2DVector aAxisVector(a2DCenterA - a2DCenterB);
     920                 :          0 :                         double fMaxLeft(0.0);
     921                 :          0 :                         double fMaxRight(0.0);
     922                 :          0 :                         sal_uInt32 nIndexLeft(0);
     923                 :          0 :                         sal_uInt32 nIndexRight(0);
     924                 :            : 
     925         [ #  # ]:          0 :                         for(sal_uInt32 a(0); a < nPointCount; a++)
     926                 :            :                         {
     927         [ #  # ]:          0 :                             const basegfx::B2DPoint aStart(a2DLoopA.getB2DPoint(a));
     928         [ #  # ]:          0 :                             const basegfx::B2DPoint aEnd(a2DLoopB.getB2DPoint(a));
     929                 :          0 :                             const basegfx::B2DPoint aMiddle(basegfx::average(aStart, aEnd));
     930                 :            : 
     931 [ #  # ][ #  # ]:          0 :                             if(!basegfx::tools::isInside(a2DLoopA, aMiddle))
     932                 :            :                             {
     933 [ #  # ][ #  # ]:          0 :                                 if(!basegfx::tools::isInside(a2DLoopB, aMiddle))
     934                 :            :                                 {
     935 [ #  # ][ #  # ]:          0 :                                     if(!impHasCutWith(a2DLoopA, aStart, aEnd))
     936                 :            :                                     {
     937 [ #  # ][ #  # ]:          0 :                                         if(!impHasCutWith(a2DLoopB, aStart, aEnd))
     938                 :            :                                         {
     939                 :          0 :                                             const basegfx::B2DVector aCandidateVector(aMiddle - aCommonCenter);
     940         [ #  # ]:          0 :                                             const double fCross(aCandidateVector.cross(aAxisVector));
     941         [ #  # ]:          0 :                                             const double fDistance(aCandidateVector.getLength());
     942                 :            : 
     943         [ #  # ]:          0 :                                             if(fCross > 0.0)
     944                 :            :                                             {
     945         [ #  # ]:          0 :                                                 if(fDistance > fMaxLeft)
     946                 :            :                                                 {
     947                 :          0 :                                                     fMaxLeft = fDistance;
     948                 :          0 :                                                     nIndexLeft = a;
     949                 :            :                                                 }
     950                 :            :                                             }
     951         [ #  # ]:          0 :                                             else if(fCross < 0.0)
     952                 :            :                                             {
     953         [ #  # ]:          0 :                                                 if(fDistance > fMaxRight)
     954                 :            :                                                 {
     955                 :          0 :                                                     fMaxRight = fDistance;
     956                 :          0 :                                                     nIndexRight = a;
     957                 :            :                                                 }
     958                 :          0 :                                             }
     959                 :            :                                         }
     960                 :            :                                     }
     961                 :            :                                 }
     962                 :            :                             }
     963                 :          0 :                         }
     964                 :            : 
     965         [ #  # ]:          0 :                         if(fMaxLeft != 0.0)
     966                 :            :                         {
     967         [ #  # ]:          0 :                             basegfx::B3DPolygon aToBeAdded;
     968 [ #  # ][ #  # ]:          0 :                             aToBeAdded.append(rLoopA.getB3DPoint(nIndexLeft));
     969 [ #  # ][ #  # ]:          0 :                             aToBeAdded.append(rLoopB.getB3DPoint(nIndexLeft));
     970 [ #  # ][ #  # ]:          0 :                             rTarget.append(aToBeAdded);
     971                 :            :                         }
     972                 :            : 
     973         [ #  # ]:          0 :                         if(fMaxRight != 0.0)
     974                 :            :                         {
     975         [ #  # ]:          0 :                             basegfx::B3DPolygon aToBeAdded;
     976 [ #  # ][ #  # ]:          0 :                             aToBeAdded.append(rLoopA.getB3DPoint(nIndexRight));
     977 [ #  # ][ #  # ]:          0 :                             aToBeAdded.append(rLoopB.getB3DPoint(nIndexRight));
     978 [ #  # ][ #  # ]:          0 :                             rTarget.append(aToBeAdded);
     979                 :          0 :                         }
     980 [ #  # ][ #  # ]:          0 :                     }
                 [ #  # ]
     981                 :            :                 }
     982                 :            :             }
     983                 :          0 :         }
     984                 :            : 
     985                 :            :     } // end of namespace primitive3d
     986                 :            : } // end of namespace drawinglayer
     987                 :            : 
     988                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10