LCOV - code coverage report
Current view: top level - drawinglayer/source/primitive3d - polygontubeprimitive3d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 259 0.0 %
Date: 2012-08-25 Functions: 0 9 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 588 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <drawinglayer/primitive3d/polygontubeprimitive3d.hxx>
      30                 :            : #include <drawinglayer/attribute/materialattribute3d.hxx>
      31                 :            : #include <basegfx/matrix/b3dhommatrix.hxx>
      32                 :            : #include <basegfx/polygon/b3dpolypolygon.hxx>
      33                 :            : #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
      34                 :            : #include <basegfx/polygon/b3dpolypolygontools.hxx>
      35                 :            : #include <drawinglayer/primitive3d/transformprimitive3d.hxx>
      36                 :            : #include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
      37                 :            : 
      38                 :            : //////////////////////////////////////////////////////////////////////////////
      39                 :            : 
      40                 :            : namespace drawinglayer
      41                 :            : {
      42                 :            :     namespace primitive3d
      43                 :            :     {
      44                 :            :         namespace // anonymous namespace
      45                 :            :         {
      46                 :          0 :             Primitive3DSequence getLineTubeSegments(
      47                 :            :                 sal_uInt32 nSegments,
      48                 :            :                 const attribute::MaterialAttribute3D& rMaterial)
      49                 :            :             {
      50                 :            :                 // static data for buffered tube primitives
      51 [ #  # ][ #  # ]:          0 :                 static Primitive3DSequence aLineTubeList;
         [ #  # ][ #  # ]
      52                 :            :                 static sal_uInt32 nLineTubeSegments(0L);
      53 [ #  # ][ #  # ]:          0 :                 static attribute::MaterialAttribute3D aLineMaterial;
         [ #  # ][ #  # ]
      54                 :            : 
      55                 :            :                 // may exclusively change static data, use mutex
      56         [ #  # ]:          0 :                 ::osl::Mutex m_mutex;
      57                 :            : 
      58 [ #  # ][ #  # ]:          0 :                 if(nSegments != nLineTubeSegments || !(rMaterial == aLineMaterial))
         [ #  # ][ #  # ]
      59                 :            :                 {
      60                 :          0 :                     nLineTubeSegments = nSegments;
      61         [ #  # ]:          0 :                     aLineMaterial = rMaterial;
      62 [ #  # ][ #  # ]:          0 :                     aLineTubeList = Primitive3DSequence();
                 [ #  # ]
      63                 :            :                 }
      64                 :            : 
      65 [ #  # ][ #  # ]:          0 :                 if(!aLineTubeList.hasElements() && 0L != nLineTubeSegments)
                 [ #  # ]
      66                 :            :                 {
      67                 :          0 :                     const basegfx::B3DPoint aLeft(0.0, 0.0, 0.0);
      68                 :          0 :                     const basegfx::B3DPoint aRight(1.0, 0.0, 0.0);
      69                 :          0 :                     basegfx::B3DPoint aLastLeft(0.0, 1.0, 0.0);
      70                 :          0 :                     basegfx::B3DPoint aLastRight(1.0, 1.0, 0.0);
      71         [ #  # ]:          0 :                     basegfx::B3DHomMatrix aRot;
      72         [ #  # ]:          0 :                     aRot.rotate(F_2PI / (double)nLineTubeSegments, 0.0, 0.0);
      73         [ #  # ]:          0 :                     aLineTubeList.realloc(nLineTubeSegments);
      74                 :            : 
      75         [ #  # ]:          0 :                     for(sal_uInt32 a(0L); a < nLineTubeSegments; a++)
      76                 :            :                     {
      77         [ #  # ]:          0 :                         const basegfx::B3DPoint aNextLeft(aRot * aLastLeft);
      78         [ #  # ]:          0 :                         const basegfx::B3DPoint aNextRight(aRot * aLastRight);
      79         [ #  # ]:          0 :                         basegfx::B3DPolygon aNewPolygon;
      80                 :            : 
      81         [ #  # ]:          0 :                         aNewPolygon.append(aNextLeft);
      82         [ #  # ]:          0 :                         aNewPolygon.setNormal(0L, basegfx::B3DVector(aNextLeft - aLeft));
      83                 :            : 
      84         [ #  # ]:          0 :                         aNewPolygon.append(aLastLeft);
      85         [ #  # ]:          0 :                         aNewPolygon.setNormal(1L, basegfx::B3DVector(aLastLeft - aLeft));
      86                 :            : 
      87         [ #  # ]:          0 :                         aNewPolygon.append(aLastRight);
      88         [ #  # ]:          0 :                         aNewPolygon.setNormal(2L, basegfx::B3DVector(aLastRight - aRight));
      89                 :            : 
      90         [ #  # ]:          0 :                         aNewPolygon.append(aNextRight);
      91         [ #  # ]:          0 :                         aNewPolygon.setNormal(3L, basegfx::B3DVector(aNextRight - aRight));
      92                 :            : 
      93         [ #  # ]:          0 :                         aNewPolygon.setClosed(true);
      94                 :            : 
      95         [ #  # ]:          0 :                         const basegfx::B3DPolyPolygon aNewPolyPolygon(aNewPolygon);
      96 [ #  # ][ #  # ]:          0 :                         const Primitive3DReference xRef(new PolyPolygonMaterialPrimitive3D(aNewPolyPolygon, aLineMaterial, false));
                 [ #  # ]
      97 [ #  # ][ #  # ]:          0 :                         aLineTubeList[a] = xRef;
      98                 :            : 
      99         [ #  # ]:          0 :                         aLastLeft = aNextLeft;
     100         [ #  # ]:          0 :                         aLastRight = aNextRight;
     101 [ #  # ][ #  # ]:          0 :                     }
                 [ #  # ]
     102                 :            :                 }
     103                 :            : 
     104 [ #  # ][ #  # ]:          0 :                 return aLineTubeList;
     105                 :            :             }
     106                 :            : 
     107                 :          0 :             Primitive3DSequence getLineCapSegments(
     108                 :            :                 sal_uInt32 nSegments,
     109                 :            :                 const attribute::MaterialAttribute3D& rMaterial)
     110                 :            :             {
     111                 :            :                 // static data for buffered tube primitives
     112 [ #  # ][ #  # ]:          0 :                 static Primitive3DSequence aLineCapList;
         [ #  # ][ #  # ]
     113                 :            :                 static sal_uInt32 nLineCapSegments(0L);
     114 [ #  # ][ #  # ]:          0 :                 static attribute::MaterialAttribute3D aLineMaterial;
         [ #  # ][ #  # ]
     115                 :            : 
     116                 :            :                 // may exclusively change static data, use mutex
     117         [ #  # ]:          0 :                 ::osl::Mutex m_mutex;
     118                 :            : 
     119 [ #  # ][ #  # ]:          0 :                 if(nSegments != nLineCapSegments || !(rMaterial == aLineMaterial))
         [ #  # ][ #  # ]
     120                 :            :                 {
     121                 :          0 :                     nLineCapSegments = nSegments;
     122         [ #  # ]:          0 :                     aLineMaterial = rMaterial;
     123 [ #  # ][ #  # ]:          0 :                     aLineCapList = Primitive3DSequence();
                 [ #  # ]
     124                 :            :                 }
     125                 :            : 
     126 [ #  # ][ #  # ]:          0 :                 if(!aLineCapList.hasElements() && 0L != nLineCapSegments)
                 [ #  # ]
     127                 :            :                 {
     128                 :          0 :                     const basegfx::B3DPoint aNull(0.0, 0.0, 0.0);
     129                 :          0 :                     basegfx::B3DPoint aLast(0.0, 1.0, 0.0);
     130         [ #  # ]:          0 :                     basegfx::B3DHomMatrix aRot;
     131         [ #  # ]:          0 :                     aRot.rotate(F_2PI / (double)nLineCapSegments, 0.0, 0.0);
     132         [ #  # ]:          0 :                     aLineCapList.realloc(nLineCapSegments);
     133                 :            : 
     134         [ #  # ]:          0 :                     for(sal_uInt32 a(0L); a < nLineCapSegments; a++)
     135                 :            :                     {
     136         [ #  # ]:          0 :                         const basegfx::B3DPoint aNext(aRot * aLast);
     137         [ #  # ]:          0 :                         basegfx::B3DPolygon aNewPolygon;
     138                 :            : 
     139         [ #  # ]:          0 :                         aNewPolygon.append(aLast);
     140         [ #  # ]:          0 :                         aNewPolygon.setNormal(0L, basegfx::B3DVector(aLast - aNull));
     141                 :            : 
     142         [ #  # ]:          0 :                         aNewPolygon.append(aNext);
     143         [ #  # ]:          0 :                         aNewPolygon.setNormal(1L, basegfx::B3DVector(aNext - aNull));
     144                 :            : 
     145         [ #  # ]:          0 :                         aNewPolygon.append(aNull);
     146         [ #  # ]:          0 :                         aNewPolygon.setNormal(2L, basegfx::B3DVector(-1.0, 0.0, 0.0));
     147                 :            : 
     148         [ #  # ]:          0 :                         aNewPolygon.setClosed(true);
     149                 :            : 
     150         [ #  # ]:          0 :                         const basegfx::B3DPolyPolygon aNewPolyPolygon(aNewPolygon);
     151 [ #  # ][ #  # ]:          0 :                         const Primitive3DReference xRef(new PolyPolygonMaterialPrimitive3D(aNewPolyPolygon, aLineMaterial, false));
                 [ #  # ]
     152 [ #  # ][ #  # ]:          0 :                         aLineCapList[a] = xRef;
     153                 :            : 
     154         [ #  # ]:          0 :                         aLast = aNext;
     155 [ #  # ][ #  # ]:          0 :                     }
                 [ #  # ]
     156                 :            :                 }
     157                 :            : 
     158 [ #  # ][ #  # ]:          0 :                 return aLineCapList;
     159                 :            :             }
     160                 :            : 
     161                 :          0 :             Primitive3DSequence getLineJoinSegments(
     162                 :            :                 sal_uInt32 nSegments,
     163                 :            :                 const attribute::MaterialAttribute3D& rMaterial,
     164                 :            :                 double fAngle,
     165                 :            :                 double /*fDegreeStepWidth*/,
     166                 :            :                 double fMiterMinimumAngle,
     167                 :            :                 basegfx::B2DLineJoin aLineJoin)
     168                 :            :             {
     169                 :            :                 // nSegments is for whole circle, adapt to half circle
     170                 :          0 :                 const sal_uInt32 nVerSeg(nSegments >> 1L);
     171         [ #  # ]:          0 :                 std::vector< BasePrimitive3D* > aResultVector;
     172                 :            : 
     173         [ #  # ]:          0 :                 if(nVerSeg)
     174                 :            :                 {
     175         [ #  # ]:          0 :                     if(basegfx::B2DLINEJOIN_ROUND == aLineJoin)
     176                 :            :                     {
     177                 :            :                         // calculate new horizontal segments
     178                 :          0 :                         const sal_uInt32 nHorSeg((sal_uInt32)((fAngle / F_2PI) * (double)nSegments));
     179                 :            : 
     180         [ #  # ]:          0 :                         if(nHorSeg)
     181                 :            :                         {
     182                 :            :                             // create half-sphere
     183         [ #  # ]:          0 :                             const basegfx::B3DPolyPolygon aSphere(basegfx::tools::createUnitSphereFillPolyPolygon(nHorSeg, nVerSeg, true, F_PI2, -F_PI2, 0.0, fAngle));
     184                 :            : 
     185 [ #  # ][ #  # ]:          0 :                             for(sal_uInt32 a(0L); a < aSphere.count(); a++)
     186                 :            :                             {
     187         [ #  # ]:          0 :                                 const basegfx::B3DPolygon aPartPolygon(aSphere.getB3DPolygon(a));
     188         [ #  # ]:          0 :                                 const basegfx::B3DPolyPolygon aPartPolyPolygon(aPartPolygon);
     189         [ #  # ]:          0 :                                 BasePrimitive3D* pNew = new PolyPolygonMaterialPrimitive3D(aPartPolyPolygon, rMaterial, false);
     190         [ #  # ]:          0 :                                 aResultVector.push_back(pNew);
     191 [ #  # ][ #  # ]:          0 :                             }
                 [ #  # ]
     192                 :            :                         }
     193                 :            :                         else
     194                 :            :                         {
     195                 :            :                             // fallback to bevel when there is not at least one segment hor and ver
     196                 :          0 :                             aLineJoin = basegfx::B2DLINEJOIN_BEVEL;
     197                 :            :                         }
     198                 :            :                     }
     199                 :            : 
     200 [ #  # ][ #  # ]:          0 :                     if(basegfx::B2DLINEJOIN_MIDDLE == aLineJoin
                 [ #  # ]
     201                 :            :                         || basegfx::B2DLINEJOIN_BEVEL == aLineJoin
     202                 :            :                         || basegfx::B2DLINEJOIN_MITER == aLineJoin)
     203                 :            :                     {
     204         [ #  # ]:          0 :                         if(basegfx::B2DLINEJOIN_MITER == aLineJoin)
     205                 :            :                         {
     206                 :          0 :                             const double fMiterAngle(fAngle/2.0);
     207                 :            : 
     208         [ #  # ]:          0 :                             if(fMiterAngle < fMiterMinimumAngle)
     209                 :            :                             {
     210                 :            :                                 // fallback to bevel when miter's angle is too small
     211                 :          0 :                                 aLineJoin = basegfx::B2DLINEJOIN_BEVEL;
     212                 :            :                             }
     213                 :            :                         }
     214                 :            : 
     215                 :          0 :                         const double fInc(F_PI / (double)nVerSeg);
     216                 :          0 :                         const double fSin(sin(-fAngle));
     217                 :          0 :                         const double fCos(cos(-fAngle));
     218                 :          0 :                         const bool bMiter(basegfx::B2DLINEJOIN_MITER == aLineJoin);
     219         [ #  # ]:          0 :                         const double fMiterSin(bMiter ? sin(-(fAngle/2.0)) : 0.0);
     220         [ #  # ]:          0 :                         const double fMiterCos(bMiter ? cos(-(fAngle/2.0)) : 0.0);
     221                 :          0 :                         double fPos(-F_PI2);
     222                 :          0 :                         basegfx::B3DPoint aPointOnXY, aPointRotY, aNextPointOnXY, aNextPointRotY;
     223                 :          0 :                         basegfx::B3DPoint aCurrMiter, aNextMiter;
     224 [ #  # ][ #  # ]:          0 :                         basegfx::B3DPolygon aNewPolygon, aMiterPolygon;
     225                 :            : 
     226                 :            :                         // close polygon
     227         [ #  # ]:          0 :                         aNewPolygon.setClosed(true);
     228         [ #  # ]:          0 :                         aMiterPolygon.setClosed(true);
     229                 :            : 
     230         [ #  # ]:          0 :                         for(sal_uInt32 a(0L); a < nVerSeg; a++)
     231                 :            :                         {
     232                 :          0 :                             const bool bFirst(0L == a);
     233                 :          0 :                             const bool bLast(a + 1L == nVerSeg);
     234                 :            : 
     235 [ #  # ][ #  # ]:          0 :                             if(bFirst || !bLast)
     236                 :            :                             {
     237                 :          0 :                                 fPos += fInc;
     238                 :            : 
     239                 :            :                                 aNextPointOnXY = basegfx::B3DPoint(
     240                 :            :                                     cos(fPos),
     241                 :            :                                     sin(fPos),
     242         [ #  # ]:          0 :                                     0.0);
     243                 :            : 
     244                 :            :                                 aNextPointRotY = basegfx::B3DPoint(
     245                 :          0 :                                     aNextPointOnXY.getX() * fCos,
     246                 :            :                                     aNextPointOnXY.getY(),
     247         [ #  # ]:          0 :                                     aNextPointOnXY.getX() * fSin);
     248                 :            : 
     249         [ #  # ]:          0 :                                 if(bMiter)
     250                 :            :                                 {
     251                 :            :                                     aNextMiter = basegfx::B3DPoint(
     252                 :            :                                         aNextPointOnXY.getX(),
     253                 :            :                                         aNextPointOnXY.getY(),
     254         [ #  # ]:          0 :                                         fMiterSin * (aNextPointOnXY.getX() / fMiterCos));
     255                 :            :                                 }
     256                 :            :                             }
     257                 :            : 
     258         [ #  # ]:          0 :                             if(bFirst)
     259                 :            :                             {
     260         [ #  # ]:          0 :                                 aNewPolygon.clear();
     261                 :            : 
     262         [ #  # ]:          0 :                                 if(bMiter)
     263                 :            :                                 {
     264         [ #  # ]:          0 :                                     aNewPolygon.append(basegfx::B3DPoint(0.0, -1.0, 0.0));
     265         [ #  # ]:          0 :                                     aNewPolygon.append(aNextPointOnXY);
     266         [ #  # ]:          0 :                                     aNewPolygon.append(aNextMiter);
     267                 :            : 
     268         [ #  # ]:          0 :                                     aMiterPolygon.clear();
     269         [ #  # ]:          0 :                                     aMiterPolygon.append(basegfx::B3DPoint(0.0, -1.0, 0.0));
     270         [ #  # ]:          0 :                                     aMiterPolygon.append(aNextMiter);
     271         [ #  # ]:          0 :                                     aMiterPolygon.append(aNextPointRotY);
     272                 :            :                                 }
     273                 :            :                                 else
     274                 :            :                                 {
     275         [ #  # ]:          0 :                                     aNewPolygon.append(basegfx::B3DPoint(0.0, -1.0, 0.0));
     276         [ #  # ]:          0 :                                     aNewPolygon.append(aNextPointOnXY);
     277         [ #  # ]:          0 :                                     aNewPolygon.append(aNextPointRotY);
     278                 :            :                                 }
     279                 :            :                             }
     280         [ #  # ]:          0 :                             else if(bLast)
     281                 :            :                             {
     282         [ #  # ]:          0 :                                 aNewPolygon.clear();
     283                 :            : 
     284         [ #  # ]:          0 :                                 if(bMiter)
     285                 :            :                                 {
     286         [ #  # ]:          0 :                                     aNewPolygon.append(basegfx::B3DPoint(0.0, 1.0, 0.0));
     287         [ #  # ]:          0 :                                     aNewPolygon.append(aCurrMiter);
     288         [ #  # ]:          0 :                                     aNewPolygon.append(aPointOnXY);
     289                 :            : 
     290         [ #  # ]:          0 :                                     aMiterPolygon.clear();
     291         [ #  # ]:          0 :                                     aMiterPolygon.append(basegfx::B3DPoint(0.0, 1.0, 0.0));
     292         [ #  # ]:          0 :                                     aMiterPolygon.append(aPointRotY);
     293         [ #  # ]:          0 :                                     aMiterPolygon.append(aCurrMiter);
     294                 :            :                                 }
     295                 :            :                                 else
     296                 :            :                                 {
     297         [ #  # ]:          0 :                                     aNewPolygon.append(basegfx::B3DPoint(0.0, 1.0, 0.0));
     298         [ #  # ]:          0 :                                     aNewPolygon.append(aPointRotY);
     299         [ #  # ]:          0 :                                     aNewPolygon.append(aPointOnXY);
     300                 :            :                                 }
     301                 :            :                             }
     302                 :            :                             else
     303                 :            :                             {
     304         [ #  # ]:          0 :                                 aNewPolygon.clear();
     305                 :            : 
     306         [ #  # ]:          0 :                                 if(bMiter)
     307                 :            :                                 {
     308         [ #  # ]:          0 :                                     aNewPolygon.append(aPointOnXY);
     309         [ #  # ]:          0 :                                     aNewPolygon.append(aNextPointOnXY);
     310         [ #  # ]:          0 :                                     aNewPolygon.append(aNextMiter);
     311         [ #  # ]:          0 :                                     aNewPolygon.append(aCurrMiter);
     312                 :            : 
     313         [ #  # ]:          0 :                                     aMiterPolygon.clear();
     314         [ #  # ]:          0 :                                     aMiterPolygon.append(aCurrMiter);
     315         [ #  # ]:          0 :                                     aMiterPolygon.append(aNextMiter);
     316         [ #  # ]:          0 :                                     aMiterPolygon.append(aNextPointRotY);
     317         [ #  # ]:          0 :                                     aMiterPolygon.append(aPointRotY);
     318                 :            :                                 }
     319                 :            :                                 else
     320                 :            :                                 {
     321         [ #  # ]:          0 :                                     aNewPolygon.append(aPointRotY);
     322         [ #  # ]:          0 :                                     aNewPolygon.append(aPointOnXY);
     323         [ #  # ]:          0 :                                     aNewPolygon.append(aNextPointOnXY);
     324         [ #  # ]:          0 :                                     aNewPolygon.append(aNextPointRotY);
     325                 :            :                                 }
     326                 :            :                             }
     327                 :            : 
     328                 :            :                             // set normals
     329 [ #  # ][ #  # ]:          0 :                             for(sal_uInt32 b(0L); b < aNewPolygon.count(); b++)
     330                 :            :                             {
     331 [ #  # ][ #  # ]:          0 :                                 aNewPolygon.setNormal(b, basegfx::B3DVector(aNewPolygon.getB3DPoint(b)));
     332                 :            :                             }
     333                 :            : 
     334                 :            :                             // create primitive
     335 [ #  # ][ #  # ]:          0 :                             if(aNewPolygon.count())
     336                 :            :                             {
     337         [ #  # ]:          0 :                                 const basegfx::B3DPolyPolygon aNewPolyPolygon(aNewPolygon);
     338         [ #  # ]:          0 :                                 BasePrimitive3D* pNew = new PolyPolygonMaterialPrimitive3D(aNewPolyPolygon, rMaterial, false);
     339 [ #  # ][ #  # ]:          0 :                                 aResultVector.push_back(pNew);
     340                 :            :                             }
     341                 :            : 
     342 [ #  # ][ #  # ]:          0 :                             if(bMiter && aMiterPolygon.count())
         [ #  # ][ #  # ]
     343                 :            :                             {
     344                 :            :                                 // set normals
     345 [ #  # ][ #  # ]:          0 :                                 for(sal_uInt32 c(0L); c < aMiterPolygon.count(); c++)
     346                 :            :                                 {
     347 [ #  # ][ #  # ]:          0 :                                     aMiterPolygon.setNormal(c, basegfx::B3DVector(aMiterPolygon.getB3DPoint(c)));
     348                 :            :                                 }
     349                 :            : 
     350                 :            :                                 // create primitive
     351         [ #  # ]:          0 :                                 const basegfx::B3DPolyPolygon aMiterPolyPolygon(aMiterPolygon);
     352         [ #  # ]:          0 :                                 BasePrimitive3D* pNew = new PolyPolygonMaterialPrimitive3D(aMiterPolyPolygon, rMaterial, false);
     353 [ #  # ][ #  # ]:          0 :                                 aResultVector.push_back(pNew);
     354                 :            :                             }
     355                 :            : 
     356                 :            :                             // prepare next step
     357 [ #  # ][ #  # ]:          0 :                             if(bFirst || !bLast)
     358                 :            :                             {
     359         [ #  # ]:          0 :                                 aPointOnXY = aNextPointOnXY;
     360         [ #  # ]:          0 :                                 aPointRotY = aNextPointRotY;
     361                 :            : 
     362         [ #  # ]:          0 :                                 if(bMiter)
     363                 :            :                                 {
     364         [ #  # ]:          0 :                                     aCurrMiter = aNextMiter;
     365                 :            :                                 }
     366                 :            :                             }
     367 [ #  # ][ #  # ]:          0 :                         }
     368                 :            :                     }
     369                 :            :                 }
     370                 :            : 
     371         [ #  # ]:          0 :                 Primitive3DSequence aRetval(aResultVector.size());
     372                 :            : 
     373         [ #  # ]:          0 :                 for(sal_uInt32 a(0L); a < aResultVector.size(); a++)
     374                 :            :                 {
     375 [ #  # ][ #  # ]:          0 :                     aRetval[a] = Primitive3DReference(aResultVector[a]);
         [ #  # ][ #  # ]
                 [ #  # ]
     376                 :            :                 }
     377                 :            : 
     378                 :          0 :                 return aRetval;
     379                 :            :             }
     380                 :            : 
     381                 :          0 :             basegfx::B3DHomMatrix getRotationFromVector(const basegfx::B3DVector& rVector)
     382                 :            :             {
     383                 :            :                 // build transformation from unit vector to vector
     384                 :          0 :                 basegfx::B3DHomMatrix aRetval;
     385                 :            : 
     386                 :            :                 // get applied rotations from angles in XY and in XZ (cartesian)
     387                 :          0 :                 const double fRotInXY(atan2(rVector.getY(), rVector.getXZLength()));
     388                 :          0 :                 const double fRotInXZ(atan2(-rVector.getZ(), rVector.getX()));
     389                 :            : 
     390                 :            :                 // apply rotations. Rot around Z needs to be done first, so apply in two steps
     391         [ #  # ]:          0 :                 aRetval.rotate(0.0, 0.0, fRotInXY);
     392         [ #  # ]:          0 :                 aRetval.rotate(0.0, fRotInXZ, 0.0);
     393                 :            : 
     394                 :          0 :                 return aRetval;
     395                 :            :             }
     396                 :            :         } // end of anonymous namespace
     397                 :            :     } // end of namespace primitive3d
     398                 :            : } // end of namespace drawinglayer
     399                 :            : 
     400                 :            : //////////////////////////////////////////////////////////////////////////////
     401                 :            : 
     402                 :            : using namespace com::sun::star;
     403                 :            : 
     404                 :            : //////////////////////////////////////////////////////////////////////////////
     405                 :            : 
     406                 :            : namespace drawinglayer
     407                 :            : {
     408                 :            :     namespace primitive3d
     409                 :            :     {
     410                 :          0 :         Primitive3DSequence PolygonTubePrimitive3D::impCreate3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const
     411                 :            :         {
     412         [ #  # ]:          0 :             const sal_uInt32 nPointCount(getB3DPolygon().count());
     413         [ #  # ]:          0 :             std::vector< BasePrimitive3D* > aResultVector;
     414                 :            : 
     415         [ #  # ]:          0 :             if(0L != nPointCount)
     416                 :            :             {
     417         [ #  # ]:          0 :                 if(basegfx::fTools::more(getRadius(), 0.0))
     418                 :            :                 {
     419         [ #  # ]:          0 :                     const attribute::MaterialAttribute3D aMaterial(getBColor());
     420                 :            :                     static sal_uInt32 nSegments(8L); // default for 3d line segments, for more quality just raise this value (in even steps)
     421         [ #  # ]:          0 :                     const bool bClosed(getB3DPolygon().isClosed());
     422                 :          0 :                     const bool bNoLineJoin(basegfx::B2DLINEJOIN_NONE == getLineJoin());
     423         [ #  # ]:          0 :                     const sal_uInt32 nLoopCount(bClosed ? nPointCount : nPointCount - 1L);
     424         [ #  # ]:          0 :                     basegfx::B3DPoint aLast(getB3DPolygon().getB3DPoint(nPointCount - 1L));
     425         [ #  # ]:          0 :                     basegfx::B3DPoint aCurr(getB3DPolygon().getB3DPoint(0L));
     426                 :            : 
     427         [ #  # ]:          0 :                     for(sal_uInt32 a(0L); a < nLoopCount; a++)
     428                 :            :                     {
     429                 :            :                         // get next data
     430         [ #  # ]:          0 :                         const basegfx::B3DPoint aNext(getB3DPolygon().getB3DPoint((a + 1L) % nPointCount));
     431                 :          0 :                         const basegfx::B3DVector aForw(aNext - aCurr);
     432         [ #  # ]:          0 :                         const double fForwLen(aForw.getLength());
     433                 :            : 
     434         [ #  # ]:          0 :                         if(basegfx::fTools::more(fForwLen, 0.0))
     435                 :            :                         {
     436                 :            :                             // get rotation from vector, this describes rotation from (1, 0, 0) to aForw
     437         [ #  # ]:          0 :                             basegfx::B3DHomMatrix aRotVector(getRotationFromVector(aForw));
     438                 :            : 
     439                 :            :                             // create default transformation with scale and rotate
     440         [ #  # ]:          0 :                             basegfx::B3DHomMatrix aVectorTrans;
     441         [ #  # ]:          0 :                             aVectorTrans.scale(fForwLen, getRadius(), getRadius());
     442         [ #  # ]:          0 :                             aVectorTrans *= aRotVector;
     443         [ #  # ]:          0 :                             aVectorTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
     444                 :            : 
     445 [ #  # ][ #  # ]:          0 :                             if(bNoLineJoin || (!bClosed && !a))
                 [ #  # ]
     446                 :            :                             {
     447                 :            :                                 // line start edge, build transformed primitiveVector3D
     448 [ #  # ][ #  # ]:          0 :                                 TransformPrimitive3D* pNewTransformedA = new TransformPrimitive3D(aVectorTrans, getLineCapSegments(nSegments, aMaterial));
                 [ #  # ]
     449         [ #  # ]:          0 :                                 aResultVector.push_back(pNewTransformedA);
     450                 :            :                             }
     451                 :            :                             else
     452                 :            :                             {
     453                 :          0 :                                 const basegfx::B3DVector aBack(aCurr - aLast);
     454         [ #  # ]:          0 :                                 const double fCross(basegfx::cross(aBack, aForw).getLength());
     455                 :            : 
     456         [ #  # ]:          0 :                                 if(!basegfx::fTools::equalZero(fCross))
     457                 :            :                                 {
     458                 :            :                                     // line connect non-parallel, aBack, aForw, use getLineJoin()
     459         [ #  # ]:          0 :                                     const double fAngle(acos(aBack.scalar(aForw) / (fForwLen * aBack.getLength()))); // 0.0 .. F_PI2
     460         [ #  # ]:          0 :                                     Primitive3DSequence aNewList(getLineJoinSegments(nSegments, aMaterial, fAngle, getDegreeStepWidth(), getMiterMinimumAngle(), getLineJoin()));
     461                 :            : 
     462                 :            :                                     // calculate transformation. First, get angle in YZ between nForw projected on (1, 0, 0) and nBack
     463         [ #  # ]:          0 :                                     basegfx::B3DHomMatrix aInvRotVector(aRotVector);
     464         [ #  # ]:          0 :                                     aInvRotVector.invert();
     465         [ #  # ]:          0 :                                     basegfx::B3DVector aTransBack(aInvRotVector * aBack);
     466                 :          0 :                                     const double fRotInYZ(atan2(aTransBack.getY(), aTransBack.getZ()));
     467                 :            : 
     468                 :            :                                     // create trans by rotating unit sphere with angle 90 degrees around Y, then 180-fRot in X.
     469                 :            :                                     // Also apply usual scaling and translation
     470         [ #  # ]:          0 :                                     basegfx::B3DHomMatrix aSphereTrans;
     471         [ #  # ]:          0 :                                     aSphereTrans.rotate(0.0, F_PI2, 0.0);
     472         [ #  # ]:          0 :                                     aSphereTrans.rotate(F_PI - fRotInYZ, 0.0, 0.0);
     473         [ #  # ]:          0 :                                     aSphereTrans *= aRotVector;
     474         [ #  # ]:          0 :                                     aSphereTrans.scale(getRadius(), getRadius(), getRadius());
     475         [ #  # ]:          0 :                                     aSphereTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
     476                 :            : 
     477                 :            :                                     // line start edge, build transformed primitiveVector3D
     478         [ #  # ]:          0 :                                     TransformPrimitive3D* pNewTransformedB = new TransformPrimitive3D(aSphereTrans, aNewList);
     479 [ #  # ][ #  # ]:          0 :                                     aResultVector.push_back(pNewTransformedB);
         [ #  # ][ #  # ]
     480                 :          0 :                                 }
     481                 :            :                             }
     482                 :            : 
     483                 :            :                             // create line segments, build transformed primitiveVector3D
     484 [ #  # ][ #  # ]:          0 :                             TransformPrimitive3D* pNewTransformedC = new TransformPrimitive3D(aVectorTrans, getLineTubeSegments(nSegments, aMaterial));
                 [ #  # ]
     485         [ #  # ]:          0 :                             aResultVector.push_back(pNewTransformedC);
     486                 :            : 
     487 [ #  # ][ #  # ]:          0 :                             if(bNoLineJoin || (!bClosed && ((a + 1L) == nLoopCount)))
                 [ #  # ]
     488                 :            :                             {
     489                 :            :                                 // line end edge, first rotate (mirror) and translate, then use use aRotVector
     490         [ #  # ]:          0 :                                 basegfx::B3DHomMatrix aBackTrans;
     491         [ #  # ]:          0 :                                 aBackTrans.rotate(0.0, F_PI, 0.0);
     492         [ #  # ]:          0 :                                 aBackTrans.translate(1.0, 0.0, 0.0);
     493         [ #  # ]:          0 :                                 aBackTrans.scale(fForwLen, getRadius(), getRadius());
     494         [ #  # ]:          0 :                                 aBackTrans *= aRotVector;
     495         [ #  # ]:          0 :                                 aBackTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
     496                 :            : 
     497                 :            :                                 // line end edge, build transformed primitiveVector3D
     498 [ #  # ][ #  # ]:          0 :                                 TransformPrimitive3D* pNewTransformedD = new TransformPrimitive3D(aBackTrans, getLineCapSegments(nSegments, aMaterial));
                 [ #  # ]
     499 [ #  # ][ #  # ]:          0 :                                 aResultVector.push_back(pNewTransformedD);
     500 [ #  # ][ #  # ]:          0 :                             }
     501                 :            :                         }
     502                 :            : 
     503                 :            :                         // prepare next loop step
     504         [ #  # ]:          0 :                         aLast = aCurr;
     505         [ #  # ]:          0 :                         aCurr = aNext;
     506         [ #  # ]:          0 :                     }
     507                 :            :                 }
     508                 :            :                 else
     509                 :            :                 {
     510                 :            :                     // create hairline
     511         [ #  # ]:          0 :                     PolygonHairlinePrimitive3D* pNew = new PolygonHairlinePrimitive3D(getB3DPolygon(), getBColor());
     512         [ #  # ]:          0 :                     aResultVector.push_back(pNew);
     513                 :            :                 }
     514                 :            :             }
     515                 :            : 
     516                 :            :             // prepare return value
     517         [ #  # ]:          0 :             Primitive3DSequence aRetval(aResultVector.size());
     518                 :            : 
     519         [ #  # ]:          0 :             for(sal_uInt32 a(0L); a < aResultVector.size(); a++)
     520                 :            :             {
     521 [ #  # ][ #  # ]:          0 :                 aRetval[a] = Primitive3DReference(aResultVector[a]);
         [ #  # ][ #  # ]
                 [ #  # ]
     522                 :            :             }
     523                 :            : 
     524                 :          0 :             return aRetval;
     525                 :            :         }
     526                 :            : 
     527                 :          0 :         PolygonTubePrimitive3D::PolygonTubePrimitive3D(
     528                 :            :             const basegfx::B3DPolygon& rPolygon,
     529                 :            :             const basegfx::BColor& rBColor,
     530                 :            :             double fRadius, basegfx::B2DLineJoin aLineJoin,
     531                 :            :             double fDegreeStepWidth,
     532                 :            :             double fMiterMinimumAngle)
     533                 :            :         :   PolygonHairlinePrimitive3D(rPolygon, rBColor),
     534                 :            :             maLast3DDecomposition(),
     535                 :            :             mfRadius(fRadius),
     536                 :            :             mfDegreeStepWidth(fDegreeStepWidth),
     537                 :            :             mfMiterMinimumAngle(fMiterMinimumAngle),
     538         [ #  # ]:          0 :             maLineJoin(aLineJoin)
     539                 :            :         {
     540                 :          0 :         }
     541                 :            : 
     542                 :          0 :         bool PolygonTubePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const
     543                 :            :         {
     544         [ #  # ]:          0 :             if(PolygonHairlinePrimitive3D::operator==(rPrimitive))
     545                 :            :             {
     546                 :          0 :                 const PolygonTubePrimitive3D& rCompare = (PolygonTubePrimitive3D&)rPrimitive;
     547                 :            : 
     548                 :          0 :                 return (getRadius() == rCompare.getRadius()
     549                 :          0 :                     && getDegreeStepWidth() == rCompare.getDegreeStepWidth()
     550                 :          0 :                     && getMiterMinimumAngle() == rCompare.getMiterMinimumAngle()
     551 [ #  # ][ #  #  :          0 :                     && getLineJoin() == rCompare.getLineJoin());
             #  #  #  # ]
     552                 :            :             }
     553                 :            : 
     554                 :          0 :             return false;
     555                 :            :         }
     556                 :            : 
     557                 :          0 :         Primitive3DSequence PolygonTubePrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const
     558                 :            :         {
     559         [ #  # ]:          0 :             ::osl::MutexGuard aGuard( m_aMutex );
     560                 :            : 
     561         [ #  # ]:          0 :             if(!getLast3DDecomposition().hasElements())
     562                 :            :             {
     563         [ #  # ]:          0 :                 const Primitive3DSequence aNewSequence(impCreate3DDecomposition(rViewInformation));
     564 [ #  # ][ #  # ]:          0 :                 const_cast< PolygonTubePrimitive3D* >(this)->setLast3DDecomposition(aNewSequence);
     565                 :            :             }
     566                 :            : 
     567 [ #  # ][ #  # ]:          0 :             return getLast3DDecomposition();
     568                 :            :         }
     569                 :            : 
     570                 :            :         // provide unique ID
     571                 :          0 :         ImplPrimitrive3DIDBlock(PolygonTubePrimitive3D, PRIMITIVE3D_ID_POLYGONTUBEPRIMITIVE3D)
     572                 :            : 
     573                 :            :     } // end of namespace primitive3d
     574                 :            : } // end of namespace drawinglayer
     575                 :            : 
     576                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10