LCOV - code coverage report
Current view: top level - libreoffice/drawinglayer/source/primitive3d - sdrextrudelathetools3d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 456 0.0 %
Date: 2012-12-27 Functions: 0 13 0.0 %
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           0 :     void impGetOuterPolyPolygon(
      65             :         basegfx::B2DPolyPolygon& rPolygon,
      66             :         basegfx::B2DPolyPolygon& rOuterPolyPolygon,
      67             :         double fOffset,
      68             :         bool bCharacterMode)
      69             :     {
      70           0 :         rOuterPolyPolygon = rPolygon;
      71             : 
      72           0 :         if(basegfx::fTools::more(fOffset, 0.0))
      73             :         {
      74           0 :             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           0 :                 const basegfx::B2DRange aRange(basegfx::tools::getRange(rPolygon));
      80           0 :                 rPolygon = basegfx::tools::growInNormalDirection(rPolygon, fOffset);
      81           0 :                 const basegfx::B2DRange aGrownRange(basegfx::tools::getRange(rPolygon));
      82           0 :                 const double fScaleX(basegfx::fTools::equalZero(aGrownRange.getWidth()) ? 1.0 : aRange.getWidth() / aGrownRange.getWidth());
      83           0 :                 const double fScaleY(basegfx::fTools::equalZero(aGrownRange.getHeight())? 1.0 : aRange.getHeight() / aGrownRange.getHeight());
      84           0 :                 basegfx::B2DHomMatrix aScaleTrans;
      85             : 
      86           0 :                 aScaleTrans.translate(-aGrownRange.getMinX(), -aGrownRange.getMinY());
      87           0 :                 aScaleTrans.scale(fScaleX, fScaleY);
      88           0 :                 aScaleTrans.translate(aRange.getMinX(), aRange.getMinY());
      89           0 :                 rPolygon.transform(aScaleTrans);
      90           0 :                 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           0 :     }
     101             : 
     102           0 :     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           0 :         const sal_uInt32 nPolygonCount(::std::min(rPolA.count(), rPolB.count()));
     113             : 
     114           0 :         for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     115             :         {
     116           0 :             const basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     117           0 :             const basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     118             :             OSL_ENSURE(aSubA.count() == aSubB.count(), "impAddInBetweenFill: unequally sized polygons (!)");
     119           0 :             const sal_uInt32 nPointCount(::std::min(aSubA.count(), aSubB.count()));
     120             : 
     121           0 :             if(nPointCount)
     122             :             {
     123           0 :                 const sal_uInt32 nEdgeCount(aSubA.isClosed() ? nPointCount : nPointCount - 1L);
     124           0 :                 double fTexHorMultiplicatorA(0.0), fTexHorMultiplicatorB(0.0);
     125           0 :                 double fPolygonPosA(0.0), fPolygonPosB(0.0);
     126             : 
     127           0 :                 if(bCreateTextureCoordinates)
     128             :                 {
     129           0 :                     const double fPolygonLengthA(basegfx::tools::getLength(aSubA));
     130           0 :                     fTexHorMultiplicatorA = basegfx::fTools::equalZero(fPolygonLengthA) ? 1.0 : 1.0 / fPolygonLengthA;
     131             : 
     132           0 :                     const double fPolygonLengthB(basegfx::tools::getLength(aSubB));
     133           0 :                     fTexHorMultiplicatorB = basegfx::fTools::equalZero(fPolygonLengthB) ? 1.0 : 1.0 / fPolygonLengthB;
     134             :                 }
     135             : 
     136           0 :                 for(sal_uInt32 b(0L); b < nEdgeCount; b++)
     137             :                 {
     138           0 :                     const sal_uInt32 nIndexA(b);
     139           0 :                     const sal_uInt32 nIndexB((b + 1L) % nPointCount);
     140             : 
     141           0 :                     const basegfx::B3DPoint aStartA(aSubA.getB3DPoint(nIndexA));
     142           0 :                     const basegfx::B3DPoint aEndA(aSubA.getB3DPoint(nIndexB));
     143           0 :                     const basegfx::B3DPoint aStartB(aSubB.getB3DPoint(nIndexA));
     144           0 :                     const basegfx::B3DPoint aEndB(aSubB.getB3DPoint(nIndexB));
     145             : 
     146           0 :                     basegfx::B3DPolygon aNew;
     147           0 :                     aNew.setClosed(true);
     148             : 
     149           0 :                     aNew.append(aStartA);
     150           0 :                     aNew.append(aStartB);
     151           0 :                     aNew.append(aEndB);
     152           0 :                     aNew.append(aEndA);
     153             : 
     154           0 :                     if(bCreateNormals)
     155             :                     {
     156           0 :                         aNew.setNormal(0L, aSubA.getNormal(nIndexA));
     157           0 :                         aNew.setNormal(1L, aSubB.getNormal(nIndexA));
     158           0 :                         aNew.setNormal(2L, aSubB.getNormal(nIndexB));
     159           0 :                         aNew.setNormal(3L, aSubA.getNormal(nIndexB));
     160             :                     }
     161             : 
     162           0 :                     if(bCreateTextureCoordinates)
     163             :                     {
     164           0 :                         const double fRelTexAL(fPolygonPosA * fTexHorMultiplicatorA);
     165           0 :                         const double fEdgeLengthA(basegfx::B3DVector(aEndA - aStartA).getLength());
     166           0 :                         fPolygonPosA += fEdgeLengthA;
     167           0 :                         const double fRelTexAR(fPolygonPosA * fTexHorMultiplicatorA);
     168             : 
     169           0 :                         const double fRelTexBL(fPolygonPosB * fTexHorMultiplicatorB);
     170           0 :                         const double fEdgeLengthB(basegfx::B3DVector(aEndB - aStartB).getLength());
     171           0 :                         fPolygonPosB += fEdgeLengthB;
     172           0 :                         const double fRelTexBR(fPolygonPosB * fTexHorMultiplicatorB);
     173             : 
     174           0 :                         aNew.setTextureCoordinate(0L, basegfx::B2DPoint(fRelTexAL, fTexVerStart));
     175           0 :                         aNew.setTextureCoordinate(1L, basegfx::B2DPoint(fRelTexBL, fTexVerStop));
     176           0 :                         aNew.setTextureCoordinate(2L, basegfx::B2DPoint(fRelTexBR, fTexVerStop));
     177           0 :                         aNew.setTextureCoordinate(3L, basegfx::B2DPoint(fRelTexAR, fTexVerStart));
     178             :                     }
     179             : 
     180           0 :                     rTarget.append(aNew);
     181           0 :                 }
     182             :             }
     183           0 :         }
     184           0 :     }
     185             : 
     186           0 :     void impSetNormal(
     187             :         basegfx::B3DPolyPolygon& rCandidate,
     188             :         const basegfx::B3DVector& rNormal)
     189             :     {
     190           0 :         for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
     191             :         {
     192           0 :             basegfx::B3DPolygon aSub(rCandidate.getB3DPolygon(a));
     193             : 
     194           0 :             for(sal_uInt32 b(0L); b < aSub.count(); b++)
     195             :             {
     196           0 :                 aSub.setNormal(b, rNormal);
     197             :             }
     198             : 
     199           0 :             rCandidate.setB3DPolygon(a, aSub);
     200           0 :         }
     201           0 :     }
     202             : 
     203           0 :     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           0 :         const sal_uInt32 nPolygonCount(::std::min(rPolA.count(), rPolB.count()));
     210             : 
     211           0 :         for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     212             :         {
     213           0 :             basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     214           0 :             basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     215             :             OSL_ENSURE(aSubA.count() == aSubB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     216           0 :             const sal_uInt32 nPointCount(::std::min(aSubA.count(), aSubB.count()));
     217             : 
     218           0 :             if(nPointCount)
     219             :             {
     220           0 :                 basegfx::B3DPoint aPrevA(aSubA.getB3DPoint(nPointCount - 1L));
     221           0 :                 basegfx::B3DPoint aCurrA(aSubA.getB3DPoint(0L));
     222           0 :                 const bool bClosed(aSubA.isClosed());
     223             : 
     224           0 :                 for(sal_uInt32 b(0L); b < nPointCount; b++)
     225             :                 {
     226           0 :                     const sal_uInt32 nIndNext((b + 1L) % nPointCount);
     227           0 :                     const basegfx::B3DPoint aNextA(aSubA.getB3DPoint(nIndNext));
     228           0 :                     const basegfx::B3DPoint aCurrB(aSubB.getB3DPoint(b));
     229             : 
     230             :                     // vector to back
     231           0 :                     basegfx::B3DVector aDepth(aCurrB - aCurrA);
     232           0 :                     aDepth.normalize();
     233             : 
     234           0 :                     if(aDepth.equalZero())
     235             :                     {
     236             :                         // no difference, try to get depth from next point
     237           0 :                         const basegfx::B3DPoint aNextB(aSubB.getB3DPoint(nIndNext));
     238           0 :                         aDepth = aNextB - aNextA;
     239           0 :                         aDepth.normalize();
     240             :                     }
     241             : 
     242             :                     // vector to left (correct for non-closed lines)
     243           0 :                     const bool bFirstAndNotClosed(!bClosed && 0L == b);
     244           0 :                     basegfx::B3DVector aLeft(bFirstAndNotClosed ? aCurrA - aNextA : aPrevA - aCurrA);
     245           0 :                     aLeft.normalize();
     246             : 
     247             :                     // create left normal
     248           0 :                     const basegfx::B3DVector aNormalLeft(aDepth.getPerpendicular(aLeft));
     249             : 
     250           0 :                     if(bSmoothHorizontalNormals)
     251             :                     {
     252             :                         // vector to right (correct for non-closed lines)
     253           0 :                         const bool bLastAndNotClosed(!bClosed && b + 1L == nPointCount);
     254           0 :                         basegfx::B3DVector aRight(bLastAndNotClosed ? aCurrA - aPrevA : aNextA - aCurrA);
     255           0 :                         aRight.normalize();
     256             : 
     257             :                         // create right normal
     258           0 :                         const basegfx::B3DVector aNormalRight(aRight.getPerpendicular(aDepth));
     259             : 
     260             :                         // create smoothed in-between normal
     261           0 :                         basegfx::B3DVector aNewNormal(aNormalLeft + aNormalRight);
     262           0 :                         aNewNormal.normalize();
     263             : 
     264             :                         // set as new normal at polygons
     265           0 :                         aSubA.setNormal(b, aNewNormal);
     266           0 :                         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           0 :                     aPrevA = aCurrA;
     277           0 :                     aCurrA = aNextA;
     278           0 :                 }
     279             : 
     280           0 :                 rPolA.setB3DPolygon(a, aSubA);
     281           0 :                 rPolB.setB3DPolygon(a, aSubB);
     282             :             }
     283           0 :         }
     284           0 :     }
     285             : 
     286           0 :     void impMixNormals(
     287             :         basegfx::B3DPolyPolygon& rPolA,
     288             :         const basegfx::B3DPolyPolygon& rPolB,
     289             :         double fWeightA)
     290             :     {
     291           0 :         const double fWeightB(1.0 - fWeightA);
     292             :         OSL_ENSURE(rPolA.count() == rPolB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     293           0 :         const sal_uInt32 nPolygonCount(::std::min(rPolA.count(), rPolB.count()));
     294             : 
     295           0 :         for(sal_uInt32 a(0L); a < nPolygonCount; a++)
     296             :         {
     297           0 :             basegfx::B3DPolygon aSubA(rPolA.getB3DPolygon(a));
     298           0 :             const basegfx::B3DPolygon aSubB(rPolB.getB3DPolygon(a));
     299             :             OSL_ENSURE(aSubA.count() == aSubB.count(), "sdrExtrudePrimitive3D: unequally sized polygons (!)");
     300           0 :             const sal_uInt32 nPointCount(::std::min(aSubA.count(), aSubB.count()));
     301             : 
     302           0 :             for(sal_uInt32 b(0L); b < nPointCount; b++)
     303             :             {
     304           0 :                 const basegfx::B3DVector aVA(aSubA.getNormal(b) * fWeightA);
     305           0 :                 const basegfx::B3DVector aVB(aSubB.getNormal(b) * fWeightB);
     306           0 :                 basegfx::B3DVector aVNew(aVA + aVB);
     307           0 :                 aVNew.normalize();
     308           0 :                 aSubA.setNormal(b, aVNew);
     309           0 :             }
     310             : 
     311           0 :             rPolA.setB3DPolygon(a, aSubA);
     312           0 :         }
     313           0 :     }
     314             : 
     315           0 :     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           0 :         const sal_uInt32 nPointCount(rPoly.count());
     319             : 
     320           0 :         if(nPointCount)
     321             :         {
     322           0 :             basegfx::B2DPoint aCurrent(rPoly.getB2DPoint(0));
     323           0 :             const basegfx::B2DVector aVector(rEnd - rStart);
     324             : 
     325           0 :             for(sal_uInt32 a(0); a < nPointCount; a++)
     326             :             {
     327           0 :                 const sal_uInt32 nNextIndex((a + 1) % nPointCount);
     328           0 :                 const basegfx::B2DPoint aNext(rPoly.getB2DPoint(nNextIndex));
     329           0 :                 const basegfx::B2DVector aEdgeVector(aNext - aCurrent);
     330             : 
     331           0 :                 if(basegfx::tools::findCut(
     332             :                     rStart, aVector,
     333           0 :                     aCurrent, aEdgeVector))
     334             :                 {
     335           0 :                     return true;
     336             :                 }
     337             : 
     338           0 :                 aCurrent = aNext;
     339           0 :             }
     340             :         }
     341             : 
     342           0 :         return false;
     343             :     }
     344             : } // end of anonymous namespace
     345             : 
     346             : //////////////////////////////////////////////////////////////////////////////
     347             : 
     348             : namespace drawinglayer
     349             : {
     350             :     namespace primitive3d
     351             :     {
     352           0 :         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           0 :             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           0 :                 const bool bBackScale(!basegfx::fTools::equal(fBackScale, 1.0));
     371           0 :                 const bool bClosedRotation(!bBackScale && basegfx::fTools::equal(fRotation, F_2PI));
     372           0 :                 basegfx::B2DPolyPolygon aFront(rSource);
     373           0 :                 basegfx::B2DPolyPolygon aBack(rSource);
     374           0 :                 basegfx::B3DHomMatrix aTransformBack;
     375           0 :                 basegfx::B2DPolyPolygon aOuterBack;
     376             : 
     377           0 :                 if(bClosedRotation)
     378             :                 {
     379           0 :                     bCloseFront = bCloseBack = false;
     380             :                 }
     381             : 
     382           0 :                 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           0 :                 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           0 :                 if(!bClosedRotation)
     422             :                 {
     423           0 :                     rSliceVector.push_back(Slice3D(aFront, basegfx::B3DHomMatrix()));
     424             :                 }
     425             : 
     426             :                 // create segments (a + 1 .. nSteps)
     427           0 :                 const double fStepSize(1.0 / (double)nSteps);
     428             : 
     429           0 :                 for(sal_uInt32 a(0L); a < nSteps; a++)
     430             :                 {
     431           0 :                     const double fStep((double)(a + 1L) * fStepSize);
     432           0 :                     basegfx::B2DPolyPolygon aNewPoly(bBackScale ? basegfx::tools::interpolate(aFront, aBack, fStep) : aFront);
     433           0 :                     basegfx::B3DHomMatrix aNewMat;
     434           0 :                     aNewMat.rotate(0.0, fRotation * fStep, 0.0);
     435           0 :                     rSliceVector.push_back(Slice3D(aNewPoly, aNewMat));
     436           0 :                 }
     437             : 
     438           0 :                 if(bCloseBack)
     439             :                 {
     440           0 :                     rSliceVector.push_back(Slice3D(aOuterBack, aTransformBack, SLICETYPE3D_BACKCAP));
     441           0 :                 }
     442             :             }
     443           0 :         }
     444             : 
     445           0 :         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           0 :             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           0 :                 basegfx::B2DPolyPolygon aFront(rSource);
     464           0 :                 basegfx::B2DPolyPolygon aBack(rSource);
     465           0 :                 const bool bBackScale(!basegfx::fTools::equal(fBackScale, 1.0));
     466           0 :                 double fZFront(fDepth); // default depth for aFront
     467           0 :                 double fZBack(0.0); // default depth for aBack
     468           0 :                 basegfx::B2DPolyPolygon aOuterBack;
     469             : 
     470           0 :                 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           0 :                 if(bCloseFront)
     483             :                 {
     484           0 :                     const double fOffset(fDepth * fDiagonal * 0.5);
     485           0 :                     fZFront = fDepth - fOffset;
     486           0 :                     basegfx::B2DPolyPolygon aOuterFront;
     487           0 :                     impGetOuterPolyPolygon(aFront, aOuterFront, fOffset, bCharacterMode);
     488           0 :                     basegfx::B3DHomMatrix aTransformFront;
     489           0 :                     aTransformFront.translate(0.0, 0.0, fDepth);
     490           0 :                     rSliceVector.push_back(Slice3D(aOuterFront, aTransformFront, SLICETYPE3D_FRONTCAP));
     491             :                 }
     492             : 
     493           0 :                 if(bCloseBack)
     494             :                 {
     495           0 :                     const double fOffset(fDepth * fDiagonal * 0.5);
     496           0 :                     fZBack = fOffset;
     497           0 :                     impGetOuterPolyPolygon(aBack, aOuterBack, fOffset, bCharacterMode);
     498             :                 }
     499             : 
     500             :                 // add front and back polygons at evtl. changed depths
     501             :                 {
     502           0 :                     basegfx::B3DHomMatrix aTransformA, aTransformB;
     503             : 
     504           0 :                     aTransformA.translate(0.0, 0.0, fZFront);
     505           0 :                     rSliceVector.push_back(Slice3D(aFront, aTransformA));
     506             : 
     507           0 :                     aTransformB.translate(0.0, 0.0, fZBack);
     508           0 :                     rSliceVector.push_back(Slice3D(aBack, aTransformB));
     509             :                 }
     510             : 
     511           0 :                 if(bCloseBack)
     512             :                 {
     513           0 :                     rSliceVector.push_back(Slice3D(aOuterBack, basegfx::B3DHomMatrix(), SLICETYPE3D_BACKCAP));
     514           0 :                 }
     515             :             }
     516           0 :         }
     517             : 
     518           0 :         basegfx::B3DPolyPolygon extractHorizontalLinesFromSlice(const Slice3DVector& rSliceVector, bool bCloseHorLines)
     519             :         {
     520           0 :             basegfx::B3DPolyPolygon aRetval;
     521           0 :             const sal_uInt32 nNumSlices(rSliceVector.size());
     522             : 
     523           0 :             if(nNumSlices)
     524             :             {
     525           0 :                 const sal_uInt32 nSlideSubPolygonCount(rSliceVector[0].getB3DPolyPolygon().count());
     526             : 
     527           0 :                 for(sal_uInt32 b(0); b < nSlideSubPolygonCount; b++)
     528             :                 {
     529           0 :                     const sal_uInt32 nSubPolygonPointCount(rSliceVector[0].getB3DPolyPolygon().getB3DPolygon(b).count());
     530             : 
     531           0 :                     for(sal_uInt32 c(0); c < nSubPolygonPointCount; c++)
     532             :                     {
     533           0 :                         basegfx::B3DPolygon aNew;
     534             : 
     535           0 :                         for(sal_uInt32 d(0); d < nNumSlices; d++)
     536             :                         {
     537           0 :                             const bool bSamePolygonCount(nSlideSubPolygonCount == rSliceVector[d].getB3DPolyPolygon().count());
     538           0 :                             const bool bSamePointCount(nSubPolygonPointCount == rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).count());
     539             : 
     540           0 :                             if(bSamePolygonCount && bSamePointCount)
     541             :                             {
     542           0 :                                 aNew.append(rSliceVector[d].getB3DPolyPolygon().getB3DPolygon(b).getB3DPoint(c));
     543             :                             }
     544             :                             else
     545             :                             {
     546             :                                 OSL_ENSURE(bSamePolygonCount, "Slice PolyPolygon with different Polygon count (!)");
     547             :                                 OSL_ENSURE(bSamePointCount, "Slice Polygon with different point count (!)");
     548             :                             }
     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           0 :         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           0 :             const sal_uInt32 nNumSlices(rSliceVector.size());
     587             : 
     588           0 :             if(nNumSlices)
     589             :             {
     590             :                 // common parameters
     591           0 :                 const sal_uInt32 nLoopCount(bClosed ? nNumSlices : nNumSlices - 1L);
     592           0 :                 basegfx::B3DPolyPolygon aEdgeRounding;
     593             :                 sal_uInt32 a;
     594             : 
     595             :                 // tetxture parameters
     596           0 :                 double fInvTexHeight(1.0);
     597           0 :                 double fTexHeightPos(0.0);
     598           0 :                 double fTexStart(0.0);
     599           0 :                 double fTexStop(1.0);
     600           0 :                 ::std::vector<double> aTexHeightArray;
     601           0 :                 basegfx::B3DRange aTexRangeFront;
     602           0 :                 basegfx::B3DRange aTexRangeBack;
     603             : 
     604           0 :                 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           0 :                 if(nLoopCount)
     638             :                 {
     639           0 :                     for(a = 0L; a < nLoopCount; a++)
     640             :                     {
     641           0 :                         const Slice3D& rSliceA(rSliceVector[a]);
     642           0 :                         const Slice3D& rSliceB(rSliceVector[(a + 1L) % nNumSlices]);
     643           0 :                         const bool bAcceptPair(SLICETYPE3D_REGULAR == rSliceA.getSliceType() && SLICETYPE3D_REGULAR == rSliceB.getSliceType());
     644           0 :                         basegfx::B3DPolyPolygon aPolA(rSliceA.getB3DPolyPolygon());
     645           0 :                         basegfx::B3DPolyPolygon aPolB(rSliceB.getB3DPolyPolygon());
     646             : 
     647           0 :                         if(bAcceptPair)
     648             :                         {
     649           0 :                             if(bCreateNormals)
     650             :                             {
     651           0 :                                 impCreateInBetweenNormals(aPolB, aPolA, bSmoothHorizontalNormals);
     652             :                             }
     653             : 
     654             :                             {
     655           0 :                                 const sal_uInt32 nIndPrev((a + nNumSlices - 1L) % nNumSlices);
     656           0 :                                 const Slice3D& rSlicePrev(rSliceVector[nIndPrev]);
     657           0 :                                 basegfx::B3DPolyPolygon aPrev(rSlicePrev.getB3DPolyPolygon());
     658           0 :                                 basegfx::B3DPolyPolygon aPolAA(rSliceA.getB3DPolyPolygon());
     659             : 
     660           0 :                                 if(SLICETYPE3D_FRONTCAP == rSlicePrev.getSliceType())
     661             :                                 {
     662           0 :                                     basegfx::B3DPolyPolygon aFront(rSlicePrev.getB3DPolyPolygon());
     663           0 :                                     const bool bHasSlant(aPolAA != aPrev);
     664             : 
     665           0 :                                     if(bCreateTextureCoordinates)
     666             :                                     {
     667           0 :                                         aFront = basegfx::tools::applyDefaultTextureCoordinatesParallel(aFront, aTexRangeFront);
     668             :                                     }
     669             : 
     670           0 :                                     if(bCreateNormals)
     671             :                                     {
     672           0 :                                         basegfx::B3DVector aNormal(0.0, 0.0, -1.0);
     673             : 
     674           0 :                                         if(aFront.count())
     675             :                                         {
     676           0 :                                             aNormal = -aFront.getB3DPolygon(0L).getNormal();
     677             :                                         }
     678             : 
     679           0 :                                         impSetNormal(aFront, aNormal);
     680             : 
     681           0 :                                         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           0 :                                             if(bSmoothNormals)
     712             :                                             {
     713             :                                                 // smooth
     714           0 :                                                 impMixNormals(aPolA, aFront, fSmoothNormalsMix);
     715             :                                             }
     716             : 
     717           0 :                                             if(bSmoothLids)
     718             :                                             {
     719             :                                                 // smooth and copy
     720           0 :                                                 impMixNormals(aFront, aPolA, fSmoothLidsMix);
     721           0 :                                                 aPolA = aFront;
     722             :                                             }
     723           0 :                                         }
     724             :                                     }
     725             : 
     726           0 :                                     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           0 :                                     aFront.flip();
     738           0 :                                     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           0 :                                 }
     748             :                             }
     749             : 
     750             :                             {
     751           0 :                                 const sal_uInt32 nIndNext((a + 2L) % nNumSlices);
     752           0 :                                 const Slice3D& rSliceNext(rSliceVector[nIndNext]);
     753           0 :                                 basegfx::B3DPolyPolygon aNext(rSliceNext.getB3DPolyPolygon());
     754           0 :                                 basegfx::B3DPolyPolygon aPolBB(rSliceB.getB3DPolyPolygon());
     755             : 
     756           0 :                                 if(SLICETYPE3D_BACKCAP == rSliceNext.getSliceType())
     757             :                                 {
     758           0 :                                     basegfx::B3DPolyPolygon aBack(rSliceNext.getB3DPolyPolygon());
     759           0 :                                     const bool bHasSlant(aPolBB != aNext);
     760             : 
     761           0 :                                     if(bCreateTextureCoordinates)
     762             :                                     {
     763           0 :                                         aBack = basegfx::tools::applyDefaultTextureCoordinatesParallel(aBack, aTexRangeBack);
     764             :                                     }
     765             : 
     766           0 :                                     if(bCreateNormals)
     767             :                                     {
     768           0 :                                         const basegfx::B3DVector aNormal(aBack.count() ? aBack.getB3DPolygon(0L).getNormal() : basegfx::B3DVector(0.0, 0.0, 1.0));
     769           0 :                                         impSetNormal(aBack, aNormal);
     770             : 
     771           0 :                                         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           0 :                                             if(bSmoothNormals)
     802             :                                             {
     803             :                                                 // smooth
     804           0 :                                                 impMixNormals(aPolB, aBack, fSmoothNormalsMix);
     805             :                                             }
     806             : 
     807           0 :                                             if(bSmoothLids)
     808             :                                             {
     809             :                                                 // smooth and copy
     810           0 :                                                 impMixNormals(aBack, aPolB, fSmoothLidsMix);
     811           0 :                                                 aPolB = aBack;
     812             :                                             }
     813           0 :                                         }
     814             :                                     }
     815             : 
     816           0 :                                     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           0 :                                     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           0 :                                 }
     837             :                             }
     838             : 
     839           0 :                             if(bCreateTextureCoordinates)
     840             :                             {
     841           0 :                                 fTexStart = (fTexHeightPos + aTexHeightArray[a]) * fInvTexHeight;
     842           0 :                                 fTexStop = fTexHeightPos * fInvTexHeight;
     843             :                             }
     844             : 
     845           0 :                             impAddInBetweenFill(aEdgeRounding, aPolB, aPolA, fTexStart, fTexStop, bCreateNormals, bCreateTextureCoordinates);
     846             :                         }
     847             : 
     848           0 :                         if(bCreateTextureCoordinates)
     849             :                         {
     850           0 :                             fTexHeightPos += aTexHeightArray[a];
     851             :                         }
     852           0 :                     }
     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           0 :                 if(bCreateTextureCoordinates)
     883             :                 {
     884           0 :                     aEdgeRounding.transformTextureCoordiantes(rTexTransform);
     885             :                 }
     886             : 
     887           0 :                 for(a = 0L; a < aEdgeRounding.count(); a++)
     888             :                 {
     889           0 :                     rFill.push_back(basegfx::B3DPolyPolygon(aEdgeRounding.getB3DPolygon(a)));
     890           0 :                 }
     891             :             }
     892           0 :         }
     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