LCOV - code coverage report
Current view: top level - basegfx/source/polygon - b3dpolygontools.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 36 340 10.6 %
Date: 2012-08-25 Functions: 4 15 26.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 30 528 5.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <osl/diagnose.h>
      30                 :            : #include <basegfx/polygon/b3dpolygontools.hxx>
      31                 :            : #include <basegfx/polygon/b3dpolygon.hxx>
      32                 :            : #include <basegfx/numeric/ftools.hxx>
      33                 :            : #include <basegfx/range/b3drange.hxx>
      34                 :            : #include <basegfx/point/b2dpoint.hxx>
      35                 :            : #include <basegfx/matrix/b3dhommatrix.hxx>
      36                 :            : #include <basegfx/polygon/b2dpolygon.hxx>
      37                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      38                 :            : #include <basegfx/tuple/b3ituple.hxx>
      39                 :            : #include <numeric>
      40                 :            : 
      41                 :            : //////////////////////////////////////////////////////////////////////////////
      42                 :            : 
      43                 :            : namespace basegfx
      44                 :            : {
      45                 :            :     namespace tools
      46                 :            :     {
      47                 :            :         // B3DPolygon tools
      48                 :       1501 :         void checkClosed(B3DPolygon& rCandidate)
      49                 :            :         {
      50         [ +  - ]:       9006 :             while(rCandidate.count() > 1L
           [ +  -  +  + ]
                 [ +  + ]
      51 [ +  - ][ +  - ]:       6004 :                 && rCandidate.getB3DPoint(0L).equal(rCandidate.getB3DPoint(rCandidate.count() - 1L)))
         [ +  - ][ +  - ]
                 [ +  - ]
           [ #  #  #  # ]
      52                 :            :             {
      53                 :       1501 :                 rCandidate.setClosed(true);
      54                 :       1501 :                 rCandidate.remove(rCandidate.count() - 1L);
      55                 :            :             }
      56                 :       1501 :         }
      57                 :            : 
      58                 :          0 :         sal_uInt32 getIndexOfSuccessor(sal_uInt32 nIndex, const B3DPolygon& rCandidate)
      59                 :            :         {
      60                 :            :             OSL_ENSURE(nIndex < rCandidate.count(), "getIndexOfPredecessor: Access to polygon out of range (!)");
      61                 :            : 
      62         [ #  # ]:          0 :             if(nIndex + 1L < rCandidate.count())
      63                 :            :             {
      64                 :          0 :                 return nIndex + 1L;
      65                 :            :             }
      66                 :            :             else
      67                 :            :             {
      68                 :          0 :                 return 0L;
      69                 :            :             }
      70                 :            :         }
      71                 :            : 
      72                 :      33301 :         B3DRange getRange(const B3DPolygon& rCandidate)
      73                 :            :         {
      74                 :      33301 :             B3DRange aRetval;
      75                 :      33301 :             const sal_uInt32 nPointCount(rCandidate.count());
      76                 :            : 
      77         [ +  + ]:     160225 :             for(sal_uInt32 a(0L); a < nPointCount; a++)
      78                 :            :             {
      79         [ +  - ]:     126924 :                 const B3DPoint aTestPoint(rCandidate.getB3DPoint(a));
      80         [ +  - ]:     126924 :                 aRetval.expand(aTestPoint);
      81                 :     126924 :             }
      82                 :            : 
      83                 :      33301 :             return aRetval;
      84                 :            :         }
      85                 :            : 
      86                 :        438 :         B3DVector getNormal(const B3DPolygon& rCandidate)
      87                 :            :         {
      88                 :        438 :             return rCandidate.getNormal();
      89                 :            :         }
      90                 :            : 
      91                 :          0 :         double getLength(const B3DPolygon& rCandidate)
      92                 :            :         {
      93                 :          0 :             double fRetval(0.0);
      94                 :          0 :             const sal_uInt32 nPointCount(rCandidate.count());
      95                 :            : 
      96         [ #  # ]:          0 :             if(nPointCount > 1L)
      97                 :            :             {
      98         [ #  # ]:          0 :                 const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1L);
      99                 :            : 
     100         [ #  # ]:          0 :                 for(sal_uInt32 a(0L); a < nLoopCount; a++)
     101                 :            :                 {
     102         [ #  # ]:          0 :                     const sal_uInt32 nNextIndex(getIndexOfSuccessor(a, rCandidate));
     103         [ #  # ]:          0 :                     const B3DPoint aCurrentPoint(rCandidate.getB3DPoint(a));
     104         [ #  # ]:          0 :                     const B3DPoint aNextPoint(rCandidate.getB3DPoint(nNextIndex));
     105                 :          0 :                     const B3DVector aVector(aNextPoint - aCurrentPoint);
     106         [ #  # ]:          0 :                     fRetval += aVector.getLength();
     107                 :          0 :                 }
     108                 :            :             }
     109                 :            : 
     110                 :          0 :             return fRetval;
     111                 :            :         }
     112                 :            : 
     113                 :          0 :         void applyLineDashing(const B3DPolygon& rCandidate, const ::std::vector<double>& rDotDashArray, B3DPolyPolygon* pLineTarget, B3DPolyPolygon* pGapTarget, double fDotDashLength)
     114                 :            :         {
     115                 :          0 :             const sal_uInt32 nPointCount(rCandidate.count());
     116                 :          0 :             const sal_uInt32 nDotDashCount(rDotDashArray.size());
     117                 :            : 
     118         [ #  # ]:          0 :             if(fTools::lessOrEqual(fDotDashLength, 0.0))
     119                 :            :             {
     120                 :          0 :                 fDotDashLength = ::std::accumulate(rDotDashArray.begin(), rDotDashArray.end(), 0.0);
     121                 :            :             }
     122                 :            : 
     123 [ #  # ][ #  # ]:          0 :             if(fTools::more(fDotDashLength, 0.0) && (pLineTarget || pGapTarget) && nPointCount)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     124                 :            :             {
     125                 :            :                 // clear targets
     126         [ #  # ]:          0 :                 if(pLineTarget)
     127                 :            :                 {
     128         [ #  # ]:          0 :                     pLineTarget->clear();
     129                 :            :                 }
     130                 :            : 
     131         [ #  # ]:          0 :                 if(pGapTarget)
     132                 :            :                 {
     133         [ #  # ]:          0 :                     pGapTarget->clear();
     134                 :            :                 }
     135                 :            : 
     136                 :            :                 // prepare current edge's start
     137         [ #  # ]:          0 :                 B3DPoint aCurrentPoint(rCandidate.getB3DPoint(0));
     138 [ #  # ][ #  # ]:          0 :                 const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1);
     139                 :            : 
     140                 :            :                 // prepare DotDashArray iteration and the line/gap switching bool
     141                 :          0 :                 sal_uInt32 nDotDashIndex(0);
     142                 :          0 :                 bool bIsLine(true);
     143         [ #  # ]:          0 :                 double fDotDashMovingLength(rDotDashArray[0]);
     144         [ #  # ]:          0 :                 B3DPolygon aSnippet;
     145                 :            : 
     146                 :            :                 // iterate over all edges
     147         [ #  # ]:          0 :                 for(sal_uInt32 a(0); a < nEdgeCount; a++)
     148                 :            :                 {
     149                 :            :                     // update current edge
     150                 :          0 :                     double fLastDotDashMovingLength(0.0);
     151                 :          0 :                     const sal_uInt32 nNextIndex((a + 1) % nPointCount);
     152         [ #  # ]:          0 :                     const B3DPoint aNextPoint(rCandidate.getB3DPoint(nNextIndex));
     153         [ #  # ]:          0 :                     const double fEdgeLength(B3DVector(aNextPoint - aCurrentPoint).getLength());
     154                 :            : 
     155         [ #  # ]:          0 :                     while(fTools::less(fDotDashMovingLength, fEdgeLength))
     156                 :            :                     {
     157                 :            :                         // new split is inside edge, create and append snippet [fLastDotDashMovingLength, fDotDashMovingLength]
     158 [ #  # ][ #  # ]:          0 :                         const bool bHandleLine(bIsLine && pLineTarget);
     159 [ #  # ][ #  # ]:          0 :                         const bool bHandleGap(!bIsLine && pGapTarget);
     160                 :            : 
     161 [ #  # ][ #  # ]:          0 :                         if(bHandleLine || bHandleGap)
     162                 :            :                         {
     163 [ #  # ][ #  # ]:          0 :                             if(!aSnippet.count())
     164                 :            :                             {
     165         [ #  # ]:          0 :                                 aSnippet.append(interpolate(aCurrentPoint, aNextPoint, fLastDotDashMovingLength / fEdgeLength));
     166                 :            :                             }
     167                 :            : 
     168         [ #  # ]:          0 :                             aSnippet.append(interpolate(aCurrentPoint, aNextPoint, fDotDashMovingLength / fEdgeLength));
     169                 :            : 
     170         [ #  # ]:          0 :                             if(bHandleLine)
     171                 :            :                             {
     172         [ #  # ]:          0 :                                 pLineTarget->append(aSnippet);
     173                 :            :                             }
     174                 :            :                             else
     175                 :            :                             {
     176         [ #  # ]:          0 :                                 pGapTarget->append(aSnippet);
     177                 :            :                             }
     178                 :            : 
     179         [ #  # ]:          0 :                             aSnippet.clear();
     180                 :            :                         }
     181                 :            : 
     182                 :            :                         // prepare next DotDashArray step and flip line/gap flag
     183                 :          0 :                         fLastDotDashMovingLength = fDotDashMovingLength;
     184         [ #  # ]:          0 :                         fDotDashMovingLength += rDotDashArray[(++nDotDashIndex) % nDotDashCount];
     185                 :          0 :                         bIsLine = !bIsLine;
     186                 :            :                     }
     187                 :            : 
     188                 :            :                     // append snippet [fLastDotDashMovingLength, fEdgeLength]
     189 [ #  # ][ #  # ]:          0 :                     const bool bHandleLine(bIsLine && pLineTarget);
     190 [ #  # ][ #  # ]:          0 :                     const bool bHandleGap(!bIsLine && pGapTarget);
     191                 :            : 
     192 [ #  # ][ #  # ]:          0 :                     if(bHandleLine || bHandleGap)
     193                 :            :                     {
     194 [ #  # ][ #  # ]:          0 :                         if(!aSnippet.count())
     195                 :            :                         {
     196         [ #  # ]:          0 :                             aSnippet.append(interpolate(aCurrentPoint, aNextPoint, fLastDotDashMovingLength / fEdgeLength));
     197                 :            :                         }
     198                 :            : 
     199         [ #  # ]:          0 :                         aSnippet.append(aNextPoint);
     200                 :            :                     }
     201                 :            : 
     202                 :            :                     // prepare move to next edge
     203                 :          0 :                     fDotDashMovingLength -= fEdgeLength;
     204                 :            : 
     205                 :            :                     // prepare next edge step (end point gets new start point)
     206         [ #  # ]:          0 :                     aCurrentPoint = aNextPoint;
     207                 :          0 :                 }
     208                 :            : 
     209                 :            :                 // append last intermediate results (if exists)
     210 [ #  # ][ #  # ]:          0 :                 if(aSnippet.count())
     211                 :            :                 {
     212 [ #  # ][ #  # ]:          0 :                     if(bIsLine && pLineTarget)
     213                 :            :                     {
     214         [ #  # ]:          0 :                         pLineTarget->append(aSnippet);
     215                 :            :                     }
     216 [ #  # ][ #  # ]:          0 :                     else if(!bIsLine && pGapTarget)
     217                 :            :                     {
     218         [ #  # ]:          0 :                         pGapTarget->append(aSnippet);
     219                 :            :                     }
     220                 :            :                 }
     221                 :            : 
     222                 :            :                 // check if start and end polygon may be merged
     223         [ #  # ]:          0 :                 if(pLineTarget)
     224                 :            :                 {
     225         [ #  # ]:          0 :                     const sal_uInt32 nCount(pLineTarget->count());
     226                 :            : 
     227         [ #  # ]:          0 :                     if(nCount > 1)
     228                 :            :                     {
     229                 :            :                         // these polygons were created above, there exists none with less than two points,
     230                 :            :                         // thus dircet point access below is allowed
     231         [ #  # ]:          0 :                         const B3DPolygon aFirst(pLineTarget->getB3DPolygon(0));
     232         [ #  # ]:          0 :                         B3DPolygon aLast(pLineTarget->getB3DPolygon(nCount - 1));
     233                 :            : 
     234 [ #  # ][ #  # ]:          0 :                         if(aFirst.getB3DPoint(0).equal(aLast.getB3DPoint(aLast.count() - 1)))
         [ #  # ][ #  # ]
     235                 :            :                         {
     236                 :            :                             // start of first and end of last are the same -> merge them
     237         [ #  # ]:          0 :                             aLast.append(aFirst);
     238         [ #  # ]:          0 :                             aLast.removeDoublePoints();
     239         [ #  # ]:          0 :                             pLineTarget->setB3DPolygon(0, aLast);
     240         [ #  # ]:          0 :                             pLineTarget->remove(nCount - 1);
     241 [ #  # ][ #  # ]:          0 :                         }
     242                 :            :                     }
     243                 :            :                 }
     244                 :            : 
     245         [ #  # ]:          0 :                 if(pGapTarget)
     246                 :            :                 {
     247         [ #  # ]:          0 :                     const sal_uInt32 nCount(pGapTarget->count());
     248                 :            : 
     249         [ #  # ]:          0 :                     if(nCount > 1)
     250                 :            :                     {
     251                 :            :                         // these polygons were created above, there exists none with less than two points,
     252                 :            :                         // thus dircet point access below is allowed
     253         [ #  # ]:          0 :                         const B3DPolygon aFirst(pGapTarget->getB3DPolygon(0));
     254         [ #  # ]:          0 :                         B3DPolygon aLast(pGapTarget->getB3DPolygon(nCount - 1));
     255                 :            : 
     256 [ #  # ][ #  # ]:          0 :                         if(aFirst.getB3DPoint(0).equal(aLast.getB3DPoint(aLast.count() - 1)))
         [ #  # ][ #  # ]
     257                 :            :                         {
     258                 :            :                             // start of first and end of last are the same -> merge them
     259         [ #  # ]:          0 :                             aLast.append(aFirst);
     260         [ #  # ]:          0 :                             aLast.removeDoublePoints();
     261         [ #  # ]:          0 :                             pGapTarget->setB3DPolygon(0, aLast);
     262         [ #  # ]:          0 :                             pGapTarget->remove(nCount - 1);
     263 [ #  # ][ #  # ]:          0 :                         }
     264                 :            :                     }
     265         [ #  # ]:          0 :                 }
     266                 :            :             }
     267                 :            :             else
     268                 :            :             {
     269                 :            :                 // parameters make no sense, just add source to targets
     270         [ #  # ]:          0 :                 if(pLineTarget)
     271                 :            :                 {
     272                 :          0 :                     pLineTarget->append(rCandidate);
     273                 :            :                 }
     274                 :            : 
     275         [ #  # ]:          0 :                 if(pGapTarget)
     276                 :            :                 {
     277                 :          0 :                     pGapTarget->append(rCandidate);
     278                 :            :                 }
     279                 :            :             }
     280                 :          0 :         }
     281                 :            : 
     282                 :          0 :         B3DPolygon applyDefaultNormalsSphere( const B3DPolygon& rCandidate, const B3DPoint& rCenter)
     283                 :            :         {
     284                 :          0 :             B3DPolygon aRetval(rCandidate);
     285                 :            : 
     286 [ #  # ][ #  # ]:          0 :             for(sal_uInt32 a(0L); a < aRetval.count(); a++)
     287                 :            :             {
     288         [ #  # ]:          0 :                 B3DVector aVector(aRetval.getB3DPoint(a) - rCenter);
     289         [ #  # ]:          0 :                 aVector.normalize();
     290         [ #  # ]:          0 :                 aRetval.setNormal(a, aVector);
     291                 :          0 :             }
     292                 :            : 
     293                 :          0 :             return aRetval;
     294                 :            :         }
     295                 :            : 
     296                 :          0 :         B3DPolygon invertNormals( const B3DPolygon& rCandidate)
     297                 :            :         {
     298                 :          0 :             B3DPolygon aRetval(rCandidate);
     299                 :            : 
     300 [ #  # ][ #  # ]:          0 :             if(aRetval.areNormalsUsed())
     301                 :            :             {
     302 [ #  # ][ #  # ]:          0 :                 for(sal_uInt32 a(0L); a < aRetval.count(); a++)
     303                 :            :                 {
     304 [ #  # ][ #  # ]:          0 :                     aRetval.setNormal(a, -aRetval.getNormal(a));
     305                 :            :                 }
     306                 :            :             }
     307                 :            : 
     308                 :          0 :             return aRetval;
     309                 :            :         }
     310                 :            : 
     311                 :        144 :         B3DPolygon applyDefaultTextureCoordinatesParallel( const B3DPolygon& rCandidate, const B3DRange& rRange, bool bChangeX, bool bChangeY)
     312                 :            :         {
     313                 :        144 :             B3DPolygon aRetval(rCandidate);
     314                 :            : 
     315 [ #  # ][ -  + ]:        144 :             if(bChangeX || bChangeY)
     316                 :            :             {
     317                 :            :                 // create projection of standard texture coordinates in (X, Y) onto
     318                 :            :                 // the 3d coordinates straight
     319         [ +  - ]:        144 :                 const double fWidth(rRange.getWidth());
     320         [ +  - ]:        144 :                 const double fHeight(rRange.getHeight());
     321                 :        144 :                 const bool bWidthSet(!fTools::equalZero(fWidth));
     322                 :        144 :                 const bool bHeightSet(!fTools::equalZero(fHeight));
     323                 :        144 :                 const double fOne(1.0);
     324                 :            : 
     325 [ +  - ][ +  + ]:        720 :                 for(sal_uInt32 a(0L); a < aRetval.count(); a++)
     326                 :            :                 {
     327         [ +  - ]:        576 :                     const B3DPoint aPoint(aRetval.getB3DPoint(a));
     328         [ +  - ]:        576 :                     B2DPoint aTextureCoordinate(aRetval.getTextureCoordinate(a));
     329                 :            : 
     330         [ +  - ]:        576 :                     if(bChangeX)
     331                 :            :                     {
     332         [ +  - ]:        576 :                         if(bWidthSet)
     333                 :            :                         {
     334         [ +  - ]:        576 :                             aTextureCoordinate.setX((aPoint.getX() - rRange.getMinX()) / fWidth);
     335                 :            :                         }
     336                 :            :                         else
     337                 :            :                         {
     338                 :          0 :                             aTextureCoordinate.setX(0.0);
     339                 :            :                         }
     340                 :            :                     }
     341                 :            : 
     342         [ +  - ]:        576 :                     if(bChangeY)
     343                 :            :                     {
     344         [ +  - ]:        576 :                         if(bHeightSet)
     345                 :            :                         {
     346         [ +  - ]:        576 :                             aTextureCoordinate.setY(fOne - ((aPoint.getY() - rRange.getMinY()) / fHeight));
     347                 :            :                         }
     348                 :            :                         else
     349                 :            :                         {
     350                 :          0 :                             aTextureCoordinate.setY(fOne);
     351                 :            :                         }
     352                 :            :                     }
     353                 :            : 
     354         [ +  - ]:        576 :                     aRetval.setTextureCoordinate(a, aTextureCoordinate);
     355                 :        576 :                 }
     356                 :            :             }
     357                 :            : 
     358                 :        144 :             return aRetval;
     359                 :            :         }
     360                 :            : 
     361                 :          0 :         B3DPolygon applyDefaultTextureCoordinatesSphere( const B3DPolygon& rCandidate, const B3DPoint& rCenter, bool bChangeX, bool bChangeY)
     362                 :            :         {
     363                 :          0 :             B3DPolygon aRetval(rCandidate);
     364                 :            : 
     365 [ #  # ][ #  # ]:          0 :             if(bChangeX || bChangeY)
     366                 :            :             {
     367                 :            :                 // create texture coordinates using sphere projection to cartesian coordinates,
     368                 :            :                 // use object's center as base
     369                 :          0 :                 const double fOne(1.0);
     370         [ #  # ]:          0 :                 const sal_uInt32 nPointCount(aRetval.count());
     371                 :          0 :                 bool bPolarPoints(false);
     372                 :            :                 sal_uInt32 a;
     373                 :            : 
     374                 :            :                 // create center cartesian coordinates to have a possibility to decide if on boundary
     375                 :            :                 // transitions which value to choose
     376         [ #  # ]:          0 :                 const B3DRange aPlaneRange(getRange(rCandidate));
     377         [ #  # ]:          0 :                 const B3DPoint aPlaneCenter(aPlaneRange.getCenter() - rCenter);
     378                 :          0 :                 const double fXCenter(fOne - ((atan2(aPlaneCenter.getZ(), aPlaneCenter.getX()) + F_PI) / F_2PI));
     379                 :            : 
     380         [ #  # ]:          0 :                 for(a = 0L; a < nPointCount; a++)
     381                 :            :                 {
     382         [ #  # ]:          0 :                     const B3DVector aVector(aRetval.getB3DPoint(a) - rCenter);
     383                 :          0 :                     const double fY(fOne - ((atan2(aVector.getY(), aVector.getXZLength()) + F_PI2) / F_PI));
     384         [ #  # ]:          0 :                     B2DPoint aTexCoor(aRetval.getTextureCoordinate(a));
     385                 :            : 
     386         [ #  # ]:          0 :                     if(fTools::equalZero(fY))
     387                 :            :                     {
     388                 :            :                         // point is a north polar point, no useful X-coordinate can be created.
     389         [ #  # ]:          0 :                         if(bChangeY)
     390                 :            :                         {
     391                 :          0 :                             aTexCoor.setY(0.0);
     392                 :            : 
     393         [ #  # ]:          0 :                             if(bChangeX)
     394                 :            :                             {
     395                 :          0 :                                 bPolarPoints = true;
     396                 :            :                             }
     397                 :            :                         }
     398                 :            :                     }
     399         [ #  # ]:          0 :                     else if(fTools::equal(fY, fOne))
     400                 :            :                     {
     401                 :            :                         // point is a south polar point, no useful X-coordinate can be created. Set
     402                 :            :                         // Y-coordinte, though
     403         [ #  # ]:          0 :                         if(bChangeY)
     404                 :            :                         {
     405                 :          0 :                             aTexCoor.setY(fOne);
     406                 :            : 
     407         [ #  # ]:          0 :                             if(bChangeX)
     408                 :            :                             {
     409                 :          0 :                                 bPolarPoints = true;
     410                 :            :                             }
     411                 :            :                         }
     412                 :            :                     }
     413                 :            :                     else
     414                 :            :                     {
     415                 :          0 :                         double fX(fOne - ((atan2(aVector.getZ(), aVector.getX()) + F_PI) / F_2PI));
     416                 :            : 
     417                 :            :                         // correct cartesinan point coordiante dependent from center value
     418         [ #  # ]:          0 :                         if(fX > fXCenter + 0.5)
     419                 :            :                         {
     420                 :          0 :                             fX -= fOne;
     421                 :            :                         }
     422         [ #  # ]:          0 :                         else if(fX < fXCenter - 0.5)
     423                 :            :                         {
     424                 :          0 :                             fX += fOne;
     425                 :            :                         }
     426                 :            : 
     427         [ #  # ]:          0 :                         if(bChangeX)
     428                 :            :                         {
     429                 :          0 :                             aTexCoor.setX(fX);
     430                 :            :                         }
     431                 :            : 
     432         [ #  # ]:          0 :                         if(bChangeY)
     433                 :            :                         {
     434                 :          0 :                             aTexCoor.setY(fY);
     435                 :            :                         }
     436                 :            :                     }
     437                 :            : 
     438         [ #  # ]:          0 :                     aRetval.setTextureCoordinate(a, aTexCoor);
     439                 :          0 :                 }
     440                 :            : 
     441         [ #  # ]:          0 :                 if(bPolarPoints)
     442                 :            :                 {
     443                 :            :                     // correct X-texture coordinates if polar points are contained. Those
     444                 :            :                     // coordinates cannot be correct, so use prev or next X-coordinate
     445         [ #  # ]:          0 :                     for(a = 0L; a < nPointCount; a++)
     446                 :            :                     {
     447         [ #  # ]:          0 :                         B2DPoint aTexCoor(aRetval.getTextureCoordinate(a));
     448                 :            : 
     449 [ #  # ][ #  # ]:          0 :                         if(fTools::equalZero(aTexCoor.getY()) || fTools::equal(aTexCoor.getY(), fOne))
         [ #  # ][ #  # ]
                 [ #  # ]
     450                 :            :                         {
     451                 :            :                             // get prev, next TexCoor and test for pole
     452 [ #  # ][ #  # ]:          0 :                             const B2DPoint aPrevTexCoor(aRetval.getTextureCoordinate(a ? a - 1L : nPointCount - 1L));
     453         [ #  # ]:          0 :                             const B2DPoint aNextTexCoor(aRetval.getTextureCoordinate((a + 1L) % nPointCount));
     454 [ #  # ][ #  # ]:          0 :                             const bool bPrevPole(fTools::equalZero(aPrevTexCoor.getY()) || fTools::equal(aPrevTexCoor.getY(), fOne));
         [ #  # ][ #  # ]
     455 [ #  # ][ #  # ]:          0 :                             const bool bNextPole(fTools::equalZero(aNextTexCoor.getY()) || fTools::equal(aNextTexCoor.getY(), fOne));
         [ #  # ][ #  # ]
     456                 :            : 
     457 [ #  # ][ #  # ]:          0 :                             if(!bPrevPole && !bNextPole)
     458                 :            :                             {
     459                 :            :                                 // both no poles, mix them
     460                 :          0 :                                 aTexCoor.setX((aPrevTexCoor.getX() + aNextTexCoor.getX()) / 2.0);
     461                 :            :                             }
     462         [ #  # ]:          0 :                             else if(!bNextPole)
     463                 :            :                             {
     464                 :            :                                 // copy next
     465                 :          0 :                                 aTexCoor.setX(aNextTexCoor.getX());
     466                 :            :                             }
     467                 :            :                             else
     468                 :            :                             {
     469                 :            :                                 // copy prev, even if it's a pole, hopefully it is already corrected
     470                 :          0 :                                 aTexCoor.setX(aPrevTexCoor.getX());
     471                 :            :                             }
     472                 :            : 
     473         [ #  # ]:          0 :                             aRetval.setTextureCoordinate(a, aTexCoor);
     474                 :            :                         }
     475                 :          0 :                     }
     476                 :          0 :                 }
     477                 :            :             }
     478                 :            : 
     479                 :          0 :             return aRetval;
     480                 :            :         }
     481                 :            : 
     482                 :          0 :         bool isInside(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder)
     483                 :            :         {
     484 [ #  # ][ #  # ]:          0 :             if(bWithBorder && isPointOnPolygon(rCandidate, rPoint, true))
                 [ #  # ]
     485                 :            :             {
     486                 :          0 :                 return true;
     487                 :            :             }
     488                 :            :             else
     489                 :            :             {
     490                 :          0 :                 bool bRetval(false);
     491         [ #  # ]:          0 :                 const B3DVector aPlaneNormal(rCandidate.getNormal());
     492                 :            : 
     493 [ #  # ][ #  # ]:          0 :                 if(!aPlaneNormal.equalZero())
     494                 :            :                 {
     495         [ #  # ]:          0 :                     const sal_uInt32 nPointCount(rCandidate.count());
     496                 :            : 
     497         [ #  # ]:          0 :                     if(nPointCount)
     498                 :            :                     {
     499         [ #  # ]:          0 :                         B3DPoint aCurrentPoint(rCandidate.getB3DPoint(nPointCount - 1));
     500                 :          0 :                         const double fAbsX(fabs(aPlaneNormal.getX()));
     501                 :          0 :                         const double fAbsY(fabs(aPlaneNormal.getY()));
     502                 :          0 :                         const double fAbsZ(fabs(aPlaneNormal.getZ()));
     503                 :            : 
     504 [ #  # ][ #  # ]:          0 :                         if(fAbsX > fAbsY && fAbsX > fAbsZ)
     505                 :            :                         {
     506                 :            :                             // normal points mostly in X-Direction, use YZ-Polygon projection for check
     507                 :            :                             // x -> y, y -> z
     508         [ #  # ]:          0 :                             for(sal_uInt32 a(0); a < nPointCount; a++)
     509                 :            :                             {
     510                 :          0 :                                 const B3DPoint aPreviousPoint(aCurrentPoint);
     511 [ #  # ][ #  # ]:          0 :                                 aCurrentPoint = rCandidate.getB3DPoint(a);
     512                 :            : 
     513                 :            :                                 // cross-over in Z?
     514                 :          0 :                                 const bool bCompZA(fTools::more(aPreviousPoint.getZ(), rPoint.getZ()));
     515                 :          0 :                                 const bool bCompZB(fTools::more(aCurrentPoint.getZ(), rPoint.getZ()));
     516                 :            : 
     517         [ #  # ]:          0 :                                 if(bCompZA != bCompZB)
     518                 :            :                                 {
     519                 :            :                                     // cross-over in Y?
     520                 :          0 :                                     const bool bCompYA(fTools::more(aPreviousPoint.getY(), rPoint.getY()));
     521                 :          0 :                                     const bool bCompYB(fTools::more(aCurrentPoint.getY(), rPoint.getY()));
     522                 :            : 
     523         [ #  # ]:          0 :                                     if(bCompYA == bCompYB)
     524                 :            :                                     {
     525         [ #  # ]:          0 :                                         if(bCompYA)
     526                 :            :                                         {
     527                 :          0 :                                             bRetval = !bRetval;
     528                 :            :                                         }
     529                 :            :                                     }
     530                 :            :                                     else
     531                 :            :                                     {
     532                 :            :                                         const double fCompare(
     533                 :          0 :                                             aCurrentPoint.getY() - (aCurrentPoint.getZ() - rPoint.getZ()) *
     534                 :          0 :                                             (aPreviousPoint.getY() - aCurrentPoint.getY()) /
     535                 :          0 :                                             (aPreviousPoint.getZ() - aCurrentPoint.getZ()));
     536                 :            : 
     537         [ #  # ]:          0 :                                         if(fTools::more(fCompare, rPoint.getY()))
     538                 :            :                                         {
     539                 :          0 :                                             bRetval = !bRetval;
     540                 :            :                                         }
     541                 :            :                                     }
     542                 :            :                                 }
     543                 :          0 :                             }
     544                 :            :                         }
     545 [ #  # ][ #  # ]:          0 :                         else if(fAbsY > fAbsX && fAbsY > fAbsZ)
     546                 :            :                         {
     547                 :            :                             // normal points mostly in Y-Direction, use XZ-Polygon projection for check
     548                 :            :                             // x -> x, y -> z
     549         [ #  # ]:          0 :                             for(sal_uInt32 a(0); a < nPointCount; a++)
     550                 :            :                             {
     551                 :          0 :                                 const B3DPoint aPreviousPoint(aCurrentPoint);
     552 [ #  # ][ #  # ]:          0 :                                 aCurrentPoint = rCandidate.getB3DPoint(a);
     553                 :            : 
     554                 :            :                                 // cross-over in Z?
     555                 :          0 :                                 const bool bCompZA(fTools::more(aPreviousPoint.getZ(), rPoint.getZ()));
     556                 :          0 :                                 const bool bCompZB(fTools::more(aCurrentPoint.getZ(), rPoint.getZ()));
     557                 :            : 
     558         [ #  # ]:          0 :                                 if(bCompZA != bCompZB)
     559                 :            :                                 {
     560                 :            :                                     // cross-over in X?
     561                 :          0 :                                     const bool bCompXA(fTools::more(aPreviousPoint.getX(), rPoint.getX()));
     562                 :          0 :                                     const bool bCompXB(fTools::more(aCurrentPoint.getX(), rPoint.getX()));
     563                 :            : 
     564         [ #  # ]:          0 :                                     if(bCompXA == bCompXB)
     565                 :            :                                     {
     566         [ #  # ]:          0 :                                         if(bCompXA)
     567                 :            :                                         {
     568                 :          0 :                                             bRetval = !bRetval;
     569                 :            :                                         }
     570                 :            :                                     }
     571                 :            :                                     else
     572                 :            :                                     {
     573                 :            :                                         const double fCompare(
     574                 :          0 :                                             aCurrentPoint.getX() - (aCurrentPoint.getZ() - rPoint.getZ()) *
     575                 :          0 :                                             (aPreviousPoint.getX() - aCurrentPoint.getX()) /
     576                 :          0 :                                             (aPreviousPoint.getZ() - aCurrentPoint.getZ()));
     577                 :            : 
     578         [ #  # ]:          0 :                                         if(fTools::more(fCompare, rPoint.getX()))
     579                 :            :                                         {
     580                 :          0 :                                             bRetval = !bRetval;
     581                 :            :                                         }
     582                 :            :                                     }
     583                 :            :                                 }
     584                 :          0 :                             }
     585                 :            :                         }
     586                 :            :                         else
     587                 :            :                         {
     588                 :            :                             // normal points mostly in Z-Direction, use XY-Polygon projection for check
     589                 :            :                             // x -> x, y -> y
     590         [ #  # ]:          0 :                             for(sal_uInt32 a(0); a < nPointCount; a++)
     591                 :            :                             {
     592                 :          0 :                                 const B3DPoint aPreviousPoint(aCurrentPoint);
     593 [ #  # ][ #  # ]:          0 :                                 aCurrentPoint = rCandidate.getB3DPoint(a);
     594                 :            : 
     595                 :            :                                 // cross-over in Y?
     596                 :          0 :                                 const bool bCompYA(fTools::more(aPreviousPoint.getY(), rPoint.getY()));
     597                 :          0 :                                 const bool bCompYB(fTools::more(aCurrentPoint.getY(), rPoint.getY()));
     598                 :            : 
     599         [ #  # ]:          0 :                                 if(bCompYA != bCompYB)
     600                 :            :                                 {
     601                 :            :                                     // cross-over in X?
     602                 :          0 :                                     const bool bCompXA(fTools::more(aPreviousPoint.getX(), rPoint.getX()));
     603                 :          0 :                                     const bool bCompXB(fTools::more(aCurrentPoint.getX(), rPoint.getX()));
     604                 :            : 
     605         [ #  # ]:          0 :                                     if(bCompXA == bCompXB)
     606                 :            :                                     {
     607         [ #  # ]:          0 :                                         if(bCompXA)
     608                 :            :                                         {
     609                 :          0 :                                             bRetval = !bRetval;
     610                 :            :                                         }
     611                 :            :                                     }
     612                 :            :                                     else
     613                 :            :                                     {
     614                 :            :                                         const double fCompare(
     615                 :          0 :                                             aCurrentPoint.getX() - (aCurrentPoint.getY() - rPoint.getY()) *
     616                 :          0 :                                             (aPreviousPoint.getX() - aCurrentPoint.getX()) /
     617                 :          0 :                                             (aPreviousPoint.getY() - aCurrentPoint.getY()));
     618                 :            : 
     619         [ #  # ]:          0 :                                         if(fTools::more(fCompare, rPoint.getX()))
     620                 :            :                                         {
     621                 :          0 :                                             bRetval = !bRetval;
     622                 :            :                                         }
     623                 :            :                                     }
     624                 :            :                                 }
     625                 :          0 :                             }
     626                 :          0 :                         }
     627                 :            :                     }
     628                 :            :                 }
     629                 :            : 
     630                 :          0 :                 return bRetval;
     631                 :            :             }
     632                 :            :         }
     633                 :            : 
     634                 :          0 :         bool isPointOnLine(const B3DPoint& rStart, const B3DPoint& rEnd, const B3DPoint& rCandidate, bool bWithPoints)
     635                 :            :         {
     636 [ #  # ][ #  # ]:          0 :             if(rCandidate.equal(rStart) || rCandidate.equal(rEnd))
                 [ #  # ]
     637                 :            :             {
     638                 :            :                 // candidate is in epsilon around start or end -> inside
     639                 :          0 :                 return bWithPoints;
     640                 :            :             }
     641         [ #  # ]:          0 :             else if(rStart.equal(rEnd))
     642                 :            :             {
     643                 :            :                 // start and end are equal, but candidate is outside their epsilon -> outside
     644                 :          0 :                 return false;
     645                 :            :             }
     646                 :            :             else
     647                 :            :             {
     648                 :          0 :                 const B3DVector aEdgeVector(rEnd - rStart);
     649                 :          0 :                 const B3DVector aTestVector(rCandidate - rStart);
     650                 :            : 
     651 [ #  # ][ #  # ]:          0 :                 if(areParallel(aEdgeVector, aTestVector))
     652                 :            :                 {
     653                 :          0 :                     const double fZero(0.0);
     654                 :          0 :                     const double fOne(1.0);
     655                 :          0 :                     double fParamTestOnCurr(0.0);
     656                 :            : 
     657         [ #  # ]:          0 :                     if(aEdgeVector.getX() > aEdgeVector.getY())
     658                 :            :                     {
     659         [ #  # ]:          0 :                         if(aEdgeVector.getX() > aEdgeVector.getZ())
     660                 :            :                         {
     661                 :            :                             // X is biggest
     662                 :          0 :                             fParamTestOnCurr = aTestVector.getX() / aEdgeVector.getX();
     663                 :            :                         }
     664                 :            :                         else
     665                 :            :                         {
     666                 :            :                             // Z is biggest
     667                 :          0 :                             fParamTestOnCurr = aTestVector.getZ() / aEdgeVector.getZ();
     668                 :            :                         }
     669                 :            :                     }
     670                 :            :                     else
     671                 :            :                     {
     672         [ #  # ]:          0 :                         if(aEdgeVector.getY() > aEdgeVector.getZ())
     673                 :            :                         {
     674                 :            :                             // Y is biggest
     675                 :          0 :                             fParamTestOnCurr = aTestVector.getY() / aEdgeVector.getY();
     676                 :            :                         }
     677                 :            :                         else
     678                 :            :                         {
     679                 :            :                             // Z is biggest
     680                 :          0 :                             fParamTestOnCurr = aTestVector.getZ() / aEdgeVector.getZ();
     681                 :            :                         }
     682                 :            :                     }
     683                 :            : 
     684 [ #  # ][ #  # ]:          0 :                     if(fTools::more(fParamTestOnCurr, fZero) && fTools::less(fParamTestOnCurr, fOne))
                 [ #  # ]
     685                 :            :                     {
     686                 :          0 :                         return true;
     687                 :            :                     }
     688                 :            :                 }
     689                 :            : 
     690                 :          0 :                 return false;
     691                 :            :             }
     692                 :            :         }
     693                 :            : 
     694                 :          0 :         bool isPointOnPolygon(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithPoints)
     695                 :            :         {
     696                 :          0 :             const sal_uInt32 nPointCount(rCandidate.count());
     697                 :            : 
     698         [ #  # ]:          0 :             if(nPointCount > 1L)
     699                 :            :             {
     700 [ #  # ][ #  # ]:          0 :                 const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1L);
     701         [ #  # ]:          0 :                 B3DPoint aCurrentPoint(rCandidate.getB3DPoint(0));
     702                 :            : 
     703         [ #  # ]:          0 :                 for(sal_uInt32 a(0); a < nLoopCount; a++)
     704                 :            :                 {
     705         [ #  # ]:          0 :                     const B3DPoint aNextPoint(rCandidate.getB3DPoint((a + 1) % nPointCount));
     706                 :            : 
     707 [ #  # ][ #  # ]:          0 :                     if(isPointOnLine(aCurrentPoint, aNextPoint, rPoint, bWithPoints))
     708                 :            :                     {
     709                 :          0 :                         return true;
     710                 :            :                     }
     711                 :            : 
     712 [ #  # ][ #  # ]:          0 :                     aCurrentPoint = aNextPoint;
     713         [ #  # ]:          0 :                 }
     714                 :            :             }
     715 [ #  # ][ #  # ]:          0 :             else if(nPointCount && bWithPoints)
     716                 :            :             {
     717                 :          0 :                 return rPoint.equal(rCandidate.getB3DPoint(0));
     718                 :            :             }
     719                 :            : 
     720                 :          0 :             return false;
     721                 :            :         }
     722                 :            : 
     723                 :          0 :         bool getCutBetweenLineAndPlane(const B3DVector& rPlaneNormal, const B3DPoint& rPlanePoint, const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, double& fCut)
     724                 :            :         {
     725 [ #  # ][ #  # ]:          0 :             if(!rPlaneNormal.equalZero() && !rEdgeStart.equal(rEdgeEnd))
                 [ #  # ]
     726                 :            :             {
     727                 :          0 :                 const B3DVector aTestEdge(rEdgeEnd - rEdgeStart);
     728                 :          0 :                 const double fScalarEdge(rPlaneNormal.scalar(aTestEdge));
     729                 :            : 
     730         [ #  # ]:          0 :                 if(!fTools::equalZero(fScalarEdge))
     731                 :            :                 {
     732                 :          0 :                     const B3DVector aCompareEdge(rPlanePoint - rEdgeStart);
     733                 :          0 :                     const double fScalarCompare(rPlaneNormal.scalar(aCompareEdge));
     734                 :            : 
     735                 :          0 :                     fCut = fScalarCompare / fScalarEdge;
     736                 :          0 :                     return true;
     737         [ #  # ]:          0 :                 }
     738                 :            :             }
     739                 :            : 
     740                 :          0 :             return false;
     741                 :            :         }
     742                 :            : 
     743                 :            :         // snap points of horizontal or vertical edges to discrete values
     744                 :          0 :         B3DPolygon snapPointsOfHorizontalOrVerticalEdges(const B3DPolygon& rCandidate)
     745                 :            :         {
     746                 :          0 :             const sal_uInt32 nPointCount(rCandidate.count());
     747                 :            : 
     748         [ #  # ]:          0 :             if(nPointCount > 1)
     749                 :            :             {
     750                 :            :                 // Start by copying the source polygon to get a writeable copy. The closed state is
     751                 :            :                 // copied by aRetval's initialisation, too, so no need to copy it in this method
     752         [ #  # ]:          0 :                 B3DPolygon aRetval(rCandidate);
     753                 :            : 
     754                 :            :                 // prepare geometry data. Get rounded from original
     755 [ #  # ][ #  # ]:          0 :                 B3ITuple aPrevTuple(basegfx::fround(rCandidate.getB3DPoint(nPointCount - 1)));
     756         [ #  # ]:          0 :                 B3DPoint aCurrPoint(rCandidate.getB3DPoint(0));
     757         [ #  # ]:          0 :                 B3ITuple aCurrTuple(basegfx::fround(aCurrPoint));
     758                 :            : 
     759                 :            :                 // loop over all points. This will also snap the implicit closing edge
     760                 :            :                 // even when not closed, but that's no problem here
     761         [ #  # ]:          0 :                 for(sal_uInt32 a(0); a < nPointCount; a++)
     762                 :            :                 {
     763                 :            :                     // get next point. Get rounded from original
     764                 :          0 :                     const bool bLastRun(a + 1 == nPointCount);
     765         [ #  # ]:          0 :                     const sal_uInt32 nNextIndex(bLastRun ? 0 : a + 1);
     766         [ #  # ]:          0 :                     const B3DPoint aNextPoint(rCandidate.getB3DPoint(nNextIndex));
     767         [ #  # ]:          0 :                     const B3ITuple aNextTuple(basegfx::fround(aNextPoint));
     768                 :            : 
     769                 :            :                     // get the states
     770                 :          0 :                     const bool bPrevVertical(aPrevTuple.getX() == aCurrTuple.getX());
     771                 :          0 :                     const bool bNextVertical(aNextTuple.getX() == aCurrTuple.getX());
     772                 :          0 :                     const bool bPrevHorizontal(aPrevTuple.getY() == aCurrTuple.getY());
     773                 :          0 :                     const bool bNextHorizontal(aNextTuple.getY() == aCurrTuple.getY());
     774 [ #  # ][ #  # ]:          0 :                     const bool bSnapX(bPrevVertical || bNextVertical);
     775 [ #  # ][ #  # ]:          0 :                     const bool bSnapY(bPrevHorizontal || bNextHorizontal);
     776                 :            : 
     777 [ #  # ][ #  # ]:          0 :                     if(bSnapX || bSnapY)
     778                 :            :                     {
     779                 :            :                         const B3DPoint aSnappedPoint(
     780                 :          0 :                             bSnapX ? aCurrTuple.getX() : aCurrPoint.getX(),
     781                 :          0 :                             bSnapY ? aCurrTuple.getY() : aCurrPoint.getY(),
     782 [ #  # ][ #  # ]:          0 :                             aCurrPoint.getZ());
     783                 :            : 
     784         [ #  # ]:          0 :                         aRetval.setB3DPoint(a, aSnappedPoint);
     785                 :            :                     }
     786                 :            : 
     787                 :            :                     // prepare next point
     788         [ #  # ]:          0 :                     if(!bLastRun)
     789                 :            :                     {
     790                 :          0 :                         aPrevTuple = aCurrTuple;
     791         [ #  # ]:          0 :                         aCurrPoint = aNextPoint;
     792                 :          0 :                         aCurrTuple = aNextTuple;
     793                 :            :                     }
     794                 :          0 :                 }
     795                 :            : 
     796 [ #  # ][ #  # ]:          0 :                 return aRetval;
     797                 :            :             }
     798                 :            :             else
     799                 :            :             {
     800                 :          0 :                 return rCandidate;
     801                 :            :             }
     802                 :            :         }
     803                 :            : 
     804                 :            :     } // end of namespace tools
     805                 :            : } // end of namespace basegfx
     806                 :            : 
     807                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10