LCOV - code coverage report
Current view: top level - drawinglayer/source/primitive3d - sdrextrudelathetools3d.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 367 456 80.5 %
Date: 2014-11-03 Functions: 11 13 84.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <drawinglayer/primitive3d/sdrextrudelathetools3d.hxx>
      21             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      22             : #include <basegfx/range/b2drange.hxx>
      23             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      24             : #include <basegfx/matrix/b2dhommatrix.hxx>
      25             : #include <basegfx/point/b3dpoint.hxx>
      26             : #include <basegfx/polygon/b3dpolygon.hxx>
      27             : #include <basegfx/polygon/b3dpolygontools.hxx>
      28             : #include <basegfx/polygon/b3dpolypolygontools.hxx>
      29             : #include <basegfx/range/b3drange.hxx>
      30             : #include <basegfx/matrix/b3dhommatrix.hxx>
      31             : #include <basegfx/polygon/b2dpolygontools.hxx>
      32             : #include <drawinglayer/geometry/viewinformation3d.hxx>
      33             : #include <numeric>
      34             : 
      35             : 
      36             : // decompositon helpers for extrude/lathe (rotation) objects
      37             : 
      38             : namespace
      39             : {
      40             : 
      41             :     // common helpers
      42             : 
      43           0 :     basegfx::B2DPolyPolygon impScalePolyPolygonOnCenter(
      44             :         const basegfx::B2DPolyPolygon& rSource,
      45             :         double fScale)
      46             :     {
      47           0 :         basegfx::B2DPolyPolygon aRetval(rSource);
      48             : 
      49           0 :         if(!basegfx::fTools::equalZero(fScale))
      50             :         {
      51           0 :             const basegfx::B2DRange aRange(basegfx::tools::getRange(rSource));
      52           0 :             const basegfx::B2DPoint aCenter(aRange.getCenter());
      53           0 :             basegfx::B2DHomMatrix aTrans;
      54             : 
      55           0 :             aTrans.translate(-aCenter.getX(), -aCenter.getY());
      56           0 :             aTrans.scale(fScale, fScale);
      57           0 :             aTrans.translate(aCenter.getX(), aCenter.getY());
      58           0 :             aRetval.transform(aTrans);
      59             :         }
      60             : 
      61           0 :         return aRetval;
      62             :     }
      63             : 
      64        6522 :     void impGetOuterPolyPolygon(
      65             :         basegfx::B2DPolyPolygon& rPolygon,
      66             :         basegfx::B2DPolyPolygon& rOuterPolyPolygon,
      67             :         double fOffset,
      68             :         bool bCharacterMode)
      69             :     {
      70        6522 :         rOuterPolyPolygon = rPolygon;
      71             : 
      72        6522 :         if(basegfx::fTools::more(fOffset, 0.0))
      73             :         {
      74         126 :             if(bCharacterMode)
      75             :             {
      76             :                 // grow the outside polygon and scale all polygons to original size. This is done
      77             :                 // to avoid a shrink which potentially would lead to self-intersections, but changes
      78             :                 // the original polygon -> not a precision step, so e.g. not usable for charts
      79         126 :                 const basegfx::B2DRange aRange(basegfx::tools::getRange(rPolygon));
      80         126 :                 rPolygon = basegfx::tools::growInNormalDirection(rPolygon, fOffset);
      81         126 :                 const basegfx::B2DRange aGrownRange(basegfx::tools::getRange(rPolygon));
      82         126 :                 const double fScaleX(basegfx::fTools::equalZero(aGrownRange.getWidth()) ? 1.0 : aRange.getWidth() / aGrownRange.getWidth());
      83         126 :                 const double fScaleY(basegfx::fTools::equalZero(aGrownRange.getHeight())? 1.0 : aRange.getHeight() / aGrownRange.getHeight());
      84         126 :                 basegfx::B2DHomMatrix aScaleTrans;
      85             : 
      86         126 :                 aScaleTrans.translate(-aGrownRange.getMinX(), -aGrownRange.getMinY());
      87         126 :                 aScaleTrans.scale(fScaleX, fScaleY);
      88         126 :                 aScaleTrans.translate(aRange.getMinX(), aRange.getMinY());
      89         126 :                 rPolygon.transform(aScaleTrans);
      90         126 :                 rOuterPolyPolygon.transform(aScaleTrans);
      91             :             }
      92             :             else
      93             :             {
      94             :                 // use more precision, shrink the outer polygons. Since this may lead to self-intersections,
      95             :                 // some kind of correction should be applied here after that step
      96           0 :                 rOuterPolyPolygon = basegfx::tools::growInNormalDirection(rPolygon, -fOffset);
      97           0 :                 basegfx::tools::correctGrowShrinkPolygonPair(rPolygon, rOuterPolyPolygon);
      98             :             }
      99             :         }
     100        6522 :     }
     101             : 
     102        6214 :     void impAddInBetweenFill(
     103             :         basegfx::B3DPolyPolygon& rTarget,
     104             :         const basegfx::B3DPolyPolygon& rPolA,
     105             :         const basegfx::B3DPolyPolygon& rPolB,
     106             :         double fTexVerStart,
     107             :         double fTexVerStop,
     108             :         bool bCreateNormals,
     109             :         bool bCreateTextureCoordinates)
     110             :     {
     111             :         OSL_ENSURE(rPolA.count() == rPolB.count(), "impAddInBetweenFill: unequally sized polygons (!)");
     112        6214 :         const sal_uInt32 nPolygonCount(::std::min(rPolA.count(), rPolB.count()));
     113             : 
     114       21644 :         for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     115             :         {
     116       15430 :             const basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     117       30860 :             const basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     118             :             OSL_ENSURE(aSubA.count() == aSubB.count(), "impAddInBetweenFill: unequally sized polygons (!)");
     119       15430 :             const sal_uInt32 nPointCount(::std::min(aSubA.count(), aSubB.count()));
     120             : 
     121       15430 :             if(nPointCount)
     122             :             {
     123       15430 :                 const sal_uInt32 nEdgeCount(aSubA.isClosed() ? nPointCount : nPointCount - 1L);
     124       15430 :                 double fTexHorMultiplicatorA(0.0), fTexHorMultiplicatorB(0.0);
     125       15430 :                 double fPolygonPosA(0.0), fPolygonPosB(0.0);
     126             : 
     127       15430 :                 if(bCreateTextureCoordinates)
     128             :                 {
     129       15376 :                     const double fPolygonLengthA(basegfx::tools::getLength(aSubA));
     130       15376 :                     fTexHorMultiplicatorA = basegfx::fTools::equalZero(fPolygonLengthA) ? 1.0 : 1.0 / fPolygonLengthA;
     131             : 
     132       15376 :                     const double fPolygonLengthB(basegfx::tools::getLength(aSubB));
     133       15376 :                     fTexHorMultiplicatorB = basegfx::fTools::equalZero(fPolygonLengthB) ? 1.0 : 1.0 / fPolygonLengthB;
     134             :                 }
     135             : 
     136       31310 :                 for(sal_uInt32 b(0L); b < nEdgeCount; b++)
     137             :                 {
     138       15880 :                     const sal_uInt32 nIndexA(b);
     139       15880 :                     const sal_uInt32 nIndexB((b + 1L) % nPointCount);
     140             : 
     141       15880 :                     const basegfx::B3DPoint aStartA(aSubA.getB3DPoint(nIndexA));
     142       31760 :                     const basegfx::B3DPoint aEndA(aSubA.getB3DPoint(nIndexB));
     143       31760 :                     const basegfx::B3DPoint aStartB(aSubB.getB3DPoint(nIndexA));
     144       31760 :                     const basegfx::B3DPoint aEndB(aSubB.getB3DPoint(nIndexB));
     145             : 
     146       31760 :                     basegfx::B3DPolygon aNew;
     147       15880 :                     aNew.setClosed(true);
     148             : 
     149       15880 :                     aNew.append(aStartA);
     150       15880 :                     aNew.append(aStartB);
     151       15880 :                     aNew.append(aEndB);
     152       15880 :                     aNew.append(aEndA);
     153             : 
     154       15880 :                     if(bCreateNormals)
     155             :                     {
     156       15880 :                         aNew.setNormal(0L, aSubA.getNormal(nIndexA));
     157       15880 :                         aNew.setNormal(1L, aSubB.getNormal(nIndexA));
     158       15880 :                         aNew.setNormal(2L, aSubB.getNormal(nIndexB));
     159       15880 :                         aNew.setNormal(3L, aSubA.getNormal(nIndexB));
     160             :                     }
     161             : 
     162       15880 :                     if(bCreateTextureCoordinates)
     163             :                     {
     164       15664 :                         const double fRelTexAL(fPolygonPosA * fTexHorMultiplicatorA);
     165       15664 :                         const double fEdgeLengthA(basegfx::B3DVector(aEndA - aStartA).getLength());
     166       15664 :                         fPolygonPosA += fEdgeLengthA;
     167       15664 :                         const double fRelTexAR(fPolygonPosA * fTexHorMultiplicatorA);
     168             : 
     169       15664 :                         const double fRelTexBL(fPolygonPosB * fTexHorMultiplicatorB);
     170       15664 :                         const double fEdgeLengthB(basegfx::B3DVector(aEndB - aStartB).getLength());
     171       15664 :                         fPolygonPosB += fEdgeLengthB;
     172       15664 :                         const double fRelTexBR(fPolygonPosB * fTexHorMultiplicatorB);
     173             : 
     174       15664 :                         aNew.setTextureCoordinate(0L, basegfx::B2DPoint(fRelTexAL, fTexVerStart));
     175       15664 :                         aNew.setTextureCoordinate(1L, basegfx::B2DPoint(fRelTexBL, fTexVerStop));
     176       15664 :                         aNew.setTextureCoordinate(2L, basegfx::B2DPoint(fRelTexBR, fTexVerStop));
     177       15664 :                         aNew.setTextureCoordinate(3L, basegfx::B2DPoint(fRelTexAR, fTexVerStart));
     178             :                     }
     179             : 
     180       15880 :                     rTarget.append(aNew);
     181       15880 :                 }
     182             :             }
     183       15430 :         }
     184        6214 :     }
     185             : 
     186         140 :     void impSetNormal(
     187             :         basegfx::B3DPolyPolygon& rCandidate,
     188             :         const basegfx::B3DVector& rNormal)
     189             :     {
     190         280 :         for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
     191             :         {
     192         140 :             basegfx::B3DPolygon aSub(rCandidate.getB3DPolygon(a));
     193             : 
     194        1180 :             for(sal_uInt32 b(0L); b < aSub.count(); b++)
     195             :             {
     196        1040 :                 aSub.setNormal(b, rNormal);
     197             :             }
     198             : 
     199         140 :             rCandidate.setB3DPolygon(a, aSub);
     200         140 :         }
     201         140 :     }
     202             : 
     203       18502 :     void impCreateInBetweenNormals(
     204             :         basegfx::B3DPolyPolygon& rPolA,
     205             :         basegfx::B3DPolyPolygon& rPolB,
     206             :         bool bSmoothHorizontalNormals)
     207             :     {
     208             :         OSL_ENSURE(rPolA.count() == rPolB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     209       18502 :         const sal_uInt32 nPolygonCount(::std::min(rPolA.count(), rPolB.count()));
     210             : 
     211       64652 :         for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     212             :         {
     213       46150 :             basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     214       92300 :             basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     215             :             OSL_ENSURE(aSubA.count() == aSubB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     216       46150 :             const sal_uInt32 nPointCount(::std::min(aSubA.count(), aSubB.count()));
     217             : 
     218       46150 :             if(nPointCount)
     219             :             {
     220       46150 :                 basegfx::B3DPoint aPrevA(aSubA.getB3DPoint(nPointCount - 1L));
     221       92300 :                 basegfx::B3DPoint aCurrA(aSubA.getB3DPoint(0L));
     222       46150 :                 const bool bClosed(aSubA.isClosed());
     223             : 
     224      138830 :                 for(sal_uInt32 b(0L); b < nPointCount; b++)
     225             :                 {
     226       92680 :                     const sal_uInt32 nIndNext((b + 1L) % nPointCount);
     227       92680 :                     const basegfx::B3DPoint aNextA(aSubA.getB3DPoint(nIndNext));
     228      185360 :                     const basegfx::B3DPoint aCurrB(aSubB.getB3DPoint(b));
     229             : 
     230             :                     // vector to back
     231      185360 :                     basegfx::B3DVector aDepth(aCurrB - aCurrA);
     232       92680 :                     aDepth.normalize();
     233             : 
     234       92680 :                     if(aDepth.equalZero())
     235             :                     {
     236             :                         // no difference, try to get depth from next point
     237       33792 :                         const basegfx::B3DPoint aNextB(aSubB.getB3DPoint(nIndNext));
     238       33792 :                         aDepth = aNextB - aNextA;
     239       33792 :                         aDepth.normalize();
     240             :                     }
     241             : 
     242             :                     // vector to left (correct for non-closed lines)
     243       92680 :                     const bool bFirstAndNotClosed(!bClosed && 0L == b);
     244      185360 :                     basegfx::B3DVector aLeft(bFirstAndNotClosed ? aCurrA - aNextA : aPrevA - aCurrA);
     245       92680 :                     aLeft.normalize();
     246             : 
     247             :                     // create left normal
     248      185360 :                     const basegfx::B3DVector aNormalLeft(aDepth.getPerpendicular(aLeft));
     249             : 
     250       92680 :                     if(bSmoothHorizontalNormals)
     251             :                     {
     252             :                         // vector to right (correct for non-closed lines)
     253       92680 :                         const bool bLastAndNotClosed(!bClosed && b + 1L == nPointCount);
     254       92680 :                         basegfx::B3DVector aRight(bLastAndNotClosed ? aCurrA - aPrevA : aNextA - aCurrA);
     255       92680 :                         aRight.normalize();
     256             : 
     257             :                         // create right normal
     258      185360 :                         const basegfx::B3DVector aNormalRight(aRight.getPerpendicular(aDepth));
     259             : 
     260             :                         // create smoothed in-between normal
     261      185360 :                         basegfx::B3DVector aNewNormal(aNormalLeft + aNormalRight);
     262       92680 :                         aNewNormal.normalize();
     263             : 
     264             :                         // set as new normal at polygons
     265       92680 :                         aSubA.setNormal(b, aNewNormal);
     266      185360 :                         aSubB.setNormal(b, aNewNormal);
     267             :                     }
     268             :                     else
     269             :                     {
     270             :                         // set aNormalLeft as new normal at polygons
     271           0 :                         aSubA.setNormal(b, aNormalLeft);
     272           0 :                         aSubB.setNormal(b, aNormalLeft);
     273             :                     }
     274             : 
     275             :                     // prepare next step
     276       92680 :                     aPrevA = aCurrA;
     277       92680 :                     aCurrA = aNextA;
     278       92680 :                 }
     279             : 
     280       46150 :                 rPolA.setB3DPolygon(a, aSubA);
     281       92300 :                 rPolB.setB3DPolygon(a, aSubB);
     282             :             }
     283       46150 :         }
     284       18502 :     }
     285             : 
     286       12428 :     void impMixNormals(
     287             :         basegfx::B3DPolyPolygon& rPolA,
     288             :         const basegfx::B3DPolyPolygon& rPolB,
     289             :         double fWeightA)
     290             :     {
     291       12428 :         const double fWeightB(1.0 - fWeightA);
     292             :         OSL_ENSURE(rPolA.count() == rPolB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     293       12428 :         const sal_uInt32 nPolygonCount(::std::min(rPolA.count(), rPolB.count()));
     294             : 
     295       43288 :         for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     296             :         {
     297       30860 :             basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     298       61720 :             const basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     299             :             OSL_ENSURE(aSubA.count() == aSubB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     300       30860 :             const sal_uInt32 nPointCount(::std::min(aSubA.count(), aSubB.count()));
     301             : 
     302       93340 :             for(sal_uInt32 b(0L); b < nPointCount; b++)
     303             :             {
     304       62480 :                 const basegfx::B3DVector aVA(aSubA.getNormal(b) * fWeightA);
     305      124960 :                 const basegfx::B3DVector aVB(aSubB.getNormal(b) * fWeightB);
     306      124960 :                 basegfx::B3DVector aVNew(aVA + aVB);
     307       62480 :                 aVNew.normalize();
     308       62480 :                 aSubA.setNormal(b, aVNew);
     309       62480 :             }
     310             : 
     311       30860 :             rPolA.setB3DPolygon(a, aSubA);
     312       30860 :         }
     313       12428 :     }
     314             : 
     315        4536 :     bool impHasCutWith(const basegfx::B2DPolygon& rPoly, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd)
     316             :     {
     317             :         // polygon is closed, one of the points is a member
     318        4536 :         const sal_uInt32 nPointCount(rPoly.count());
     319             : 
     320        4536 :         if(nPointCount)
     321             :         {
     322        4536 :             basegfx::B2DPoint aCurrent(rPoly.getB2DPoint(0));
     323        6944 :             const basegfx::B2DVector aVector(rEnd - rStart);
     324             : 
     325      111084 :             for(sal_uInt32 a(0); a < nPointCount; a++)
     326             :             {
     327      108676 :                 const sal_uInt32 nNextIndex((a + 1) % nPointCount);
     328      108676 :                 const basegfx::B2DPoint aNext(rPoly.getB2DPoint(nNextIndex));
     329      215224 :                 const basegfx::B2DVector aEdgeVector(aNext - aCurrent);
     330             : 
     331      108676 :                 if(basegfx::tools::findCut(
     332             :                     rStart, aVector,
     333      108676 :                     aCurrent, aEdgeVector))
     334             :                 {
     335        2128 :                     return true;
     336             :                 }
     337             : 
     338      106548 :                 aCurrent = aNext;
     339      108956 :             }
     340             :         }
     341             : 
     342        2408 :         return false;
     343             :     }
     344             : } // end of anonymous namespace
     345             : 
     346             : 
     347             : 
     348             : namespace drawinglayer
     349             : {
     350             :     namespace primitive3d
     351             :     {
     352         120 :         void createLatheSlices(
     353             :             Slice3DVector& rSliceVector,
     354             :             const basegfx::B2DPolyPolygon& rSource,
     355             :             double fBackScale,
     356             :             double fDiagonal,
     357             :             double fRotation,
     358             :             sal_uInt32 nSteps,
     359             :             bool bCharacterMode,
     360             :             bool bCloseFront,
     361             :             bool bCloseBack)
     362             :         {
     363         120 :             if(basegfx::fTools::equalZero(fRotation) || 0L == nSteps)
     364             :             {
     365             :                 // no rotation or no steps, just one plane
     366           0 :                 rSliceVector.push_back(Slice3D(rSource, basegfx::B3DHomMatrix()));
     367             :             }
     368             :             else
     369             :             {
     370         120 :                 const bool bBackScale(!basegfx::fTools::equal(fBackScale, 1.0));
     371         120 :                 const bool bClosedRotation(!bBackScale && basegfx::fTools::equal(fRotation, F_2PI));
     372         120 :                 basegfx::B2DPolyPolygon aFront(rSource);
     373         240 :                 basegfx::B2DPolyPolygon aBack(rSource);
     374         240 :                 basegfx::B3DHomMatrix aTransformBack;
     375         240 :                 basegfx::B2DPolyPolygon aOuterBack;
     376             : 
     377         120 :                 if(bClosedRotation)
     378             :                 {
     379         120 :                     bCloseFront = bCloseBack = false;
     380             :                 }
     381             : 
     382         120 :                 if(bBackScale)
     383             :                 {
     384             :                     // avoid null zoom
     385           0 :                     if(basegfx::fTools::equalZero(fBackScale))
     386             :                     {
     387           0 :                         fBackScale = 0.000001;
     388             :                     }
     389             : 
     390             :                     // back is scaled compared to front, create scaled version
     391           0 :                     aBack = impScalePolyPolygonOnCenter(aBack, fBackScale);
     392             :                 }
     393             : 
     394         120 :                 if(bCloseFront || bCloseBack)
     395             :                 {
     396           0 :                     const basegfx::B2DRange aBaseRange(basegfx::tools::getRange(aFront));
     397           0 :                     const double fOuterLength(aBaseRange.getMaxX() * fRotation);
     398           0 :                     const double fInnerLength(aBaseRange.getMinX() * fRotation);
     399           0 :                     const double fAverageLength((fOuterLength + fInnerLength) * 0.5);
     400             : 
     401           0 :                     if(bCloseFront)
     402             :                     {
     403           0 :                         const double fOffsetLen((fAverageLength / 12.0) * fDiagonal);
     404           0 :                         basegfx::B2DPolyPolygon aOuterFront;
     405           0 :                         impGetOuterPolyPolygon(aFront, aOuterFront, fOffsetLen, bCharacterMode);
     406           0 :                         basegfx::B3DHomMatrix aTransform;
     407           0 :                         aTransform.translate(0.0, 0.0, fOffsetLen);
     408           0 :                         rSliceVector.push_back(Slice3D(aOuterFront, aTransform, SLICETYPE3D_FRONTCAP));
     409             :                     }
     410             : 
     411           0 :                     if(bCloseBack)
     412             :                     {
     413           0 :                         const double fOffsetLen((fAverageLength / 12.0) * fDiagonal);
     414           0 :                         impGetOuterPolyPolygon(aBack, aOuterBack, fOffsetLen, bCharacterMode);
     415           0 :                         aTransformBack.translate(0.0, 0.0, -fOffsetLen);
     416           0 :                         aTransformBack.rotate(0.0, fRotation, 0.0);
     417             :                     }
     418             :                 }
     419             : 
     420             :                 // add start polygon (a = 0L)
     421         120 :                 if(!bClosedRotation)
     422             :                 {
     423           0 :                     rSliceVector.push_back(Slice3D(aFront, basegfx::B3DHomMatrix()));
     424             :                 }
     425             : 
     426             :                 // create segments (a + 1 .. nSteps)
     427         120 :                 const double fStepSize(1.0 / (double)nSteps);
     428             : 
     429        3768 :                 for(sal_uInt32 a(0L); a < nSteps; a++)
     430             :                 {
     431        3648 :                     const double fStep((double)(a + 1L) * fStepSize);
     432        3648 :                     basegfx::B2DPolyPolygon aNewPoly(bBackScale ? basegfx::tools::interpolate(aFront, aBack, fStep) : aFront);
     433        7296 :                     basegfx::B3DHomMatrix aNewMat;
     434        3648 :                     aNewMat.rotate(0.0, fRotation * fStep, 0.0);
     435        3648 :                     rSliceVector.push_back(Slice3D(aNewPoly, aNewMat));
     436        3648 :                 }
     437             : 
     438         120 :                 if(bCloseBack)
     439             :                 {
     440           0 :                     rSliceVector.push_back(Slice3D(aOuterBack, aTransformBack, SLICETYPE3D_BACKCAP));
     441         120 :                 }
     442             :             }
     443         120 :         }
     444             : 
     445        3261 :         void createExtrudeSlices(
     446             :             Slice3DVector& rSliceVector,
     447             :             const basegfx::B2DPolyPolygon& rSource,
     448             :             double fBackScale,
     449             :             double fDiagonal,
     450             :             double fDepth,
     451             :             bool bCharacterMode,
     452             :             bool bCloseFront,
     453             :             bool bCloseBack)
     454             :         {
     455        3261 :             if(basegfx::fTools::equalZero(fDepth))
     456             :             {
     457             :                 // no depth, just one plane
     458           0 :                 rSliceVector.push_back(Slice3D(rSource, basegfx::B3DHomMatrix()));
     459             :             }
     460             :             else
     461             :             {
     462             :                 // there is depth, create Polygons for front,back and their default depth positions
     463        3261 :                 basegfx::B2DPolyPolygon aFront(rSource);
     464        6522 :                 basegfx::B2DPolyPolygon aBack(rSource);
     465        3261 :                 const bool bBackScale(!basegfx::fTools::equal(fBackScale, 1.0));
     466        3261 :                 double fZFront(fDepth); // default depth for aFront
     467        3261 :                 double fZBack(0.0); // default depth for aBack
     468        6522 :                 basegfx::B2DPolyPolygon aOuterBack;
     469             : 
     470        3261 :                 if(bBackScale)
     471             :                 {
     472             :                     // avoid null zoom
     473           0 :                     if(basegfx::fTools::equalZero(fBackScale))
     474             :                     {
     475           0 :                         fBackScale = 0.000001;
     476             :                     }
     477             : 
     478             :                     // aFront is scaled compared to aBack, create scaled version
     479           0 :                     aFront = impScalePolyPolygonOnCenter(aFront, fBackScale);
     480             :                 }
     481             : 
     482        3261 :                 if(bCloseFront)
     483             :                 {
     484        3261 :                     const double fOffset(fDepth * fDiagonal * 0.5);
     485        3261 :                     fZFront = fDepth - fOffset;
     486        3261 :                     basegfx::B2DPolyPolygon aOuterFront;
     487        3261 :                     impGetOuterPolyPolygon(aFront, aOuterFront, fOffset, bCharacterMode);
     488        6522 :                     basegfx::B3DHomMatrix aTransformFront;
     489        3261 :                     aTransformFront.translate(0.0, 0.0, fDepth);
     490        6522 :                     rSliceVector.push_back(Slice3D(aOuterFront, aTransformFront, SLICETYPE3D_FRONTCAP));
     491             :                 }
     492             : 
     493        3261 :                 if(bCloseBack)
     494             :                 {
     495        3261 :                     const double fOffset(fDepth * fDiagonal * 0.5);
     496        3261 :                     fZBack = fOffset;
     497        3261 :                     impGetOuterPolyPolygon(aBack, aOuterBack, fOffset, bCharacterMode);
     498             :                 }
     499             : 
     500             :                 // add front and back polygons at evtl. changed depths
     501             :                 {
     502        6522 :                     basegfx::B3DHomMatrix aTransformA, aTransformB;
     503             : 
     504        3261 :                     aTransformA.translate(0.0, 0.0, fZFront);
     505        3261 :                     rSliceVector.push_back(Slice3D(aFront, aTransformA));
     506             : 
     507        3261 :                     aTransformB.translate(0.0, 0.0, fZBack);
     508        6522 :                     rSliceVector.push_back(Slice3D(aBack, aTransformB));
     509             :                 }
     510             : 
     511        3261 :                 if(bCloseBack)
     512             :                 {
     513        3261 :                     rSliceVector.push_back(Slice3D(aOuterBack, basegfx::B3DHomMatrix(), SLICETYPE3D_BACKCAP));
     514        3261 :                 }
     515             :             }
     516        3261 :         }
     517             : 
     518          96 :         basegfx::B3DPolyPolygon extractHorizontalLinesFromSlice(const Slice3DVector& rSliceVector, bool bCloseHorLines)
     519             :         {
     520          96 :             basegfx::B3DPolyPolygon aRetval;
     521          96 :             const sal_uInt32 nNumSlices(rSliceVector.size());
     522             : 
     523          96 :             if(nNumSlices)
     524             :             {
     525          96 :                 const sal_uInt32 nSlideSubPolygonCount(rSliceVector[0].getB3DPolyPolygon().count());
     526             : 
     527         336 :                 for(sal_uInt32 b(0); b < nSlideSubPolygonCount; b++)
     528             :                 {
     529         240 :                     const sal_uInt32 nSubPolygonPointCount(rSliceVector[0].getB3DPolyPolygon().getB3DPolygon(b).count());
     530             : 
     531         720 :                     for(sal_uInt32 c(0); c < nSubPolygonPointCount; c++)
     532             :                     {
     533         480 :                         basegfx::B3DPolygon aNew;
     534             : 
     535       15840 :                         for(sal_uInt32 d(0); d < nNumSlices; d++)
     536             :                         {
     537       15360 :                             const bool bSamePolygonCount(nSlideSubPolygonCount == rSliceVector[d].getB3DPolyPolygon().count());
     538       15360 :                             const bool bSamePointCount(nSubPolygonPointCount == rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).count());
     539             : 
     540       15360 :                             if(bSamePolygonCount && bSamePointCount)
     541             :                             {
     542       15360 :                                 aNew.append(rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).getB3DPoint(c));
     543             :                             }
     544             :                             else
     545             :                             {
     546             :                                 OSL_ENSURE(bSamePolygonCount, "Slice tools::PolyPolygon with different Polygon count (!)");
     547             :                                 OSL_ENSURE(bSamePointCount, "Slice Polygon with different point count (!)");
     548             :                             }
     549             :                         }
     550             : 
     551         480 :                         aNew.setClosed(bCloseHorLines);
     552         480 :                         aRetval.append(aNew);
     553         480 :                     }
     554             :                 }
     555             :             }
     556             : 
     557          96 :             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         262 :         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         262 :             const sal_uInt32 nNumSlices(rSliceVector.size());
     587             : 
     588         262 :             if(nNumSlices)
     589             :             {
     590             :                 // common parameters
     591         262 :                 const sal_uInt32 nLoopCount(bClosed ? nNumSlices : nNumSlices - 1L);
     592         262 :                 basegfx::B3DPolyPolygon aEdgeRounding;
     593             :                 sal_uInt32 a;
     594             : 
     595             :                 // tetxture parameters
     596         262 :                 double fInvTexHeight(1.0);
     597         262 :                 double fTexHeightPos(0.0);
     598         262 :                 double fTexStart(0.0);
     599         262 :                 double fTexStop(1.0);
     600         524 :                 ::std::vector<double> aTexHeightArray;
     601         262 :                 basegfx::B3DRange aTexRangeFront;
     602         262 :                 basegfx::B3DRange aTexRangeBack;
     603             : 
     604         262 :                 if(bCreateTextureCoordinates)
     605             :                 {
     606         208 :                     aTexRangeFront = basegfx::tools::getRange(rSliceVector[0L].getB3DPolyPolygon());
     607         208 :                     aTexRangeBack = basegfx::tools::getRange(rSliceVector[nNumSlices - 1L].getB3DPolyPolygon());
     608             : 
     609         208 :                     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         208 :                     basegfx::B3DPoint aCenter(basegfx::tools::getRange(rSliceVector[0L].getB3DPolyPolygon()).getCenter());
     620             : 
     621        6400 :                     for(a = 0L; a < nLoopCount; a++)
     622             :                     {
     623        6192 :                         const basegfx::B3DPoint aNextCenter(basegfx::tools::getRange(rSliceVector[(a + 1L) % nNumSlices].getB3DPolyPolygon()).getCenter());
     624        6192 :                         const double fLength(basegfx::B3DVector(aNextCenter - aCenter).getLength());
     625        6192 :                         aTexHeightArray.push_back(fLength);
     626        6192 :                         aCenter = aNextCenter;
     627        6192 :                     }
     628             : 
     629         208 :                     const double fTexHeight(::std::accumulate(aTexHeightArray.begin(), aTexHeightArray.end(), 0.0));
     630             : 
     631         208 :                     if(!basegfx::fTools::equalZero(fTexHeight))
     632             :                     {
     633         208 :                         fInvTexHeight = 1.0 / fTexHeight;
     634         208 :                     }
     635             :                 }
     636             : 
     637         262 :                 if(nLoopCount)
     638             :                 {
     639        6616 :                     for(a = 0L; a < nLoopCount; a++)
     640             :                     {
     641        6354 :                         const Slice3D& rSliceA(rSliceVector[a]);
     642        6354 :                         const Slice3D& rSliceB(rSliceVector[(a + 1L) % nNumSlices]);
     643        6354 :                         const bool bAcceptPair(SLICETYPE3D_REGULAR == rSliceA.getSliceType() && SLICETYPE3D_REGULAR == rSliceB.getSliceType());
     644        6354 :                         basegfx::B3DPolyPolygon aPolA(rSliceA.getB3DPolyPolygon());
     645       12708 :                         basegfx::B3DPolyPolygon aPolB(rSliceB.getB3DPolyPolygon());
     646             : 
     647        6354 :                         if(bAcceptPair)
     648             :                         {
     649        6214 :                             if(bCreateNormals)
     650             :                             {
     651        6214 :                                 impCreateInBetweenNormals(aPolB, aPolA, bSmoothHorizontalNormals);
     652             :                             }
     653             : 
     654             :                             {
     655        6214 :                                 const sal_uInt32 nIndPrev((a + nNumSlices - 1L) % nNumSlices);
     656        6214 :                                 const Slice3D& rSlicePrev(rSliceVector[nIndPrev]);
     657        6214 :                                 basegfx::B3DPolyPolygon aPrev(rSlicePrev.getB3DPolyPolygon());
     658       12428 :                                 basegfx::B3DPolyPolygon aPolAA(rSliceA.getB3DPolyPolygon());
     659             : 
     660        6214 :                                 if(SLICETYPE3D_FRONTCAP == rSlicePrev.getSliceType())
     661             :                                 {
     662          70 :                                     basegfx::B3DPolyPolygon aFront(rSlicePrev.getB3DPolyPolygon());
     663          70 :                                     const bool bHasSlant(aPolAA != aPrev);
     664             : 
     665          70 :                                     if(bCreateTextureCoordinates)
     666             :                                     {
     667          16 :                                         aFront = basegfx::tools::applyDefaultTextureCoordinatesParallel(aFront, aTexRangeFront);
     668             :                                     }
     669             : 
     670          70 :                                     if(bCreateNormals)
     671             :                                     {
     672          70 :                                         basegfx::B3DVector aNormal(0.0, 0.0, -1.0);
     673             : 
     674          70 :                                         if(aFront.count())
     675             :                                         {
     676          70 :                                             aNormal = -aFront.getB3DPolygon(0L).getNormal();
     677             :                                         }
     678             : 
     679          70 :                                         impSetNormal(aFront, aNormal);
     680             : 
     681          70 :                                         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          70 :                                             if(bSmoothNormals)
     712             :                                             {
     713             :                                                 // smooth
     714          70 :                                                 impMixNormals(aPolA, aFront, fSmoothNormalsMix);
     715             :                                             }
     716             : 
     717          70 :                                             if(bSmoothLids)
     718             :                                             {
     719             :                                                 // smooth and copy
     720           0 :                                                 impMixNormals(aFront, aPolA, fSmoothLidsMix);
     721           0 :                                                 aPolA = aFront;
     722             :                                             }
     723          70 :                                         }
     724             :                                     }
     725             : 
     726          70 :                                     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          70 :                                     aFront.flip();
     738          70 :                                     rFill.push_back(aFront);
     739             :                                 }
     740             :                                 else
     741             :                                 {
     742        6144 :                                     if(bCreateNormals && bSmoothNormals && (nIndPrev != a + 1L))
     743             :                                     {
     744        6144 :                                         impCreateInBetweenNormals(aPolAA, aPrev, bSmoothHorizontalNormals);
     745        6144 :                                         impMixNormals(aPolA, aPolAA, 0.5);
     746             :                                     }
     747        6214 :                                 }
     748             :                             }
     749             : 
     750             :                             {
     751        6214 :                                 const sal_uInt32 nIndNext((a + 2L) % nNumSlices);
     752        6214 :                                 const Slice3D& rSliceNext(rSliceVector[nIndNext]);
     753        6214 :                                 basegfx::B3DPolyPolygon aNext(rSliceNext.getB3DPolyPolygon());
     754       12428 :                                 basegfx::B3DPolyPolygon aPolBB(rSliceB.getB3DPolyPolygon());
     755             : 
     756        6214 :                                 if(SLICETYPE3D_BACKCAP == rSliceNext.getSliceType())
     757             :                                 {
     758          70 :                                     basegfx::B3DPolyPolygon aBack(rSliceNext.getB3DPolyPolygon());
     759          70 :                                     const bool bHasSlant(aPolBB != aNext);
     760             : 
     761          70 :                                     if(bCreateTextureCoordinates)
     762             :                                     {
     763          16 :                                         aBack = basegfx::tools::applyDefaultTextureCoordinatesParallel(aBack, aTexRangeBack);
     764             :                                     }
     765             : 
     766          70 :                                     if(bCreateNormals)
     767             :                                     {
     768          70 :                                         const basegfx::B3DVector aNormal(aBack.count() ? aBack.getB3DPolygon(0L).getNormal() : basegfx::B3DVector(0.0, 0.0, 1.0));
     769          70 :                                         impSetNormal(aBack, aNormal);
     770             : 
     771          70 :                                         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          70 :                                             if(bSmoothNormals)
     802             :                                             {
     803             :                                                 // smooth
     804          70 :                                                 impMixNormals(aPolB, aBack, fSmoothNormalsMix);
     805             :                                             }
     806             : 
     807          70 :                                             if(bSmoothLids)
     808             :                                             {
     809             :                                                 // smooth and copy
     810           0 :                                                 impMixNormals(aBack, aPolB, fSmoothLidsMix);
     811           0 :                                                 aPolB = aBack;
     812             :                                             }
     813          70 :                                         }
     814             :                                     }
     815             : 
     816          70 :                                     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          70 :                                     rFill.push_back(aBack);
     828             :                                 }
     829             :                                 else
     830             :                                 {
     831        6144 :                                     if(bCreateNormals && bSmoothNormals && (nIndNext != a))
     832             :                                     {
     833        6144 :                                         impCreateInBetweenNormals(aNext, aPolBB, bSmoothHorizontalNormals);
     834        6144 :                                         impMixNormals(aPolB, aPolBB, 0.5);
     835             :                                     }
     836        6214 :                                 }
     837             :                             }
     838             : 
     839        6214 :                             if(bCreateTextureCoordinates)
     840             :                             {
     841        6160 :                                 fTexStart = (fTexHeightPos + aTexHeightArray[a]) * fInvTexHeight;
     842        6160 :                                 fTexStop = fTexHeightPos * fInvTexHeight;
     843             :                             }
     844             : 
     845        6214 :                             impAddInBetweenFill(aEdgeRounding, aPolB, aPolA, fTexStart, fTexStop, bCreateNormals, bCreateTextureCoordinates);
     846             :                         }
     847             : 
     848        6354 :                         if(bCreateTextureCoordinates)
     849             :                         {
     850        6192 :                             fTexHeightPos += aTexHeightArray[a];
     851             :                         }
     852        6354 :                     }
     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         262 :                 if(bCreateTextureCoordinates)
     883             :                 {
     884         208 :                     aEdgeRounding.transformTextureCoordiantes(rTexTransform);
     885             :                 }
     886             : 
     887       16142 :                 for(a = 0L; a < aEdgeRounding.count(); a++)
     888             :                 {
     889       15880 :                     rFill.push_back(basegfx::B3DPolyPolygon(aEdgeRounding.getB3DPolygon(a)));
     890         262 :                 }
     891             :             }
     892         262 :         }
     893             : 
     894         384 :         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         384 :             const sal_uInt32 nPointCount(rLoopA.count());
     902             : 
     903             :             // with idetic polygons there are no outlines
     904         384 :             if(rLoopA != rLoopB)
     905             :             {
     906         240 :                 if(nPointCount && nPointCount == rLoopB.count())
     907             :                 {
     908         240 :                     const basegfx::B3DHomMatrix aObjectTransform(rViewInformation.getObjectToView() * rObjectTransform);
     909         480 :                     const basegfx::B2DPolygon a2DLoopA(basegfx::tools::createB2DPolygonFromB3DPolygon(rLoopA, aObjectTransform));
     910         480 :                     const basegfx::B2DPolygon a2DLoopB(basegfx::tools::createB2DPolygonFromB3DPolygon(rLoopB, aObjectTransform));
     911         480 :                     const basegfx::B2DPoint a2DCenterA(a2DLoopA.getB2DRange().getCenter());
     912         480 :                     const basegfx::B2DPoint a2DCenterB(a2DLoopB.getB2DRange().getCenter());
     913             : 
     914             :                     // without detectable Y-Axis there are no outlines
     915         240 :                     if(!a2DCenterA.equal(a2DCenterB))
     916             :                     {
     917             :                         // search for outmost left and right inter-loop-edges which do not cut the loops
     918          96 :                         const basegfx::B2DPoint aCommonCenter(basegfx::average(a2DCenterA, a2DCenterB));
     919         192 :                         const basegfx::B2DVector aAxisVector(a2DCenterA - a2DCenterB);
     920          96 :                         double fMaxLeft(0.0);
     921          96 :                         double fMaxRight(0.0);
     922          96 :                         sal_uInt32 nIndexLeft(0);
     923          96 :                         sal_uInt32 nIndexRight(0);
     924             : 
     925        3168 :                         for(sal_uInt32 a(0); a < nPointCount; a++)
     926             :                         {
     927        3072 :                             const basegfx::B2DPoint aStart(a2DLoopA.getB2DPoint(a));
     928        6144 :                             const basegfx::B2DPoint aEnd(a2DLoopB.getB2DPoint(a));
     929        6144 :                             const basegfx::B2DPoint aMiddle(basegfx::average(aStart, aEnd));
     930             : 
     931        3072 :                             if(!basegfx::tools::isInside(a2DLoopA, aMiddle))
     932             :                             {
     933        3032 :                                 if(!basegfx::tools::isInside(a2DLoopB, aMiddle))
     934             :                                 {
     935        2992 :                                     if(!impHasCutWith(a2DLoopA, aStart, aEnd))
     936             :                                     {
     937        1544 :                                         if(!impHasCutWith(a2DLoopB, aStart, aEnd))
     938             :                                         {
     939         864 :                                             const basegfx::B2DVector aCandidateVector(aMiddle - aCommonCenter);
     940         864 :                                             const double fCross(aCandidateVector.cross(aAxisVector));
     941         864 :                                             const double fDistance(aCandidateVector.getLength());
     942             : 
     943         864 :                                             if(fCross > 0.0)
     944             :                                             {
     945         432 :                                                 if(fDistance > fMaxLeft)
     946             :                                                 {
     947         144 :                                                     fMaxLeft = fDistance;
     948         144 :                                                     nIndexLeft = a;
     949             :                                                 }
     950             :                                             }
     951         432 :                                             else if(fCross < 0.0)
     952             :                                             {
     953         432 :                                                 if(fDistance > fMaxRight)
     954             :                                                 {
     955         408 :                                                     fMaxRight = fDistance;
     956         408 :                                                     nIndexRight = a;
     957             :                                                 }
     958         864 :                                             }
     959             :                                         }
     960             :                                     }
     961             :                                 }
     962             :                             }
     963        3072 :                         }
     964             : 
     965          96 :                         if(fMaxLeft != 0.0)
     966             :                         {
     967          96 :                             basegfx::B3DPolygon aToBeAdded;
     968          96 :                             aToBeAdded.append(rLoopA.getB3DPoint(nIndexLeft));
     969          96 :                             aToBeAdded.append(rLoopB.getB3DPoint(nIndexLeft));
     970          96 :                             rTarget.append(aToBeAdded);
     971             :                         }
     972             : 
     973          96 :                         if(fMaxRight != 0.0)
     974             :                         {
     975          96 :                             basegfx::B3DPolygon aToBeAdded;
     976          96 :                             aToBeAdded.append(rLoopA.getB3DPoint(nIndexRight));
     977          96 :                             aToBeAdded.append(rLoopB.getB3DPoint(nIndexRight));
     978          96 :                             rTarget.append(aToBeAdded);
     979          96 :                         }
     980         240 :                     }
     981             :                 }
     982             :             }
     983         384 :         }
     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