/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_drawinglayer.hxx"

#include <drawinglayer/primitive3d/polygontubeprimitive3d.hxx>
#include <drawinglayer/attribute/materialattribute3d.hxx>
#include <basegfx/matrix/b3dhommatrix.hxx>
#include <basegfx/polygon/b3dpolypolygon.hxx>
#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
#include <basegfx/polygon/b3dpolypolygontools.hxx>
#include <drawinglayer/primitive3d/transformprimitive3d.hxx>
#include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>

//////////////////////////////////////////////////////////////////////////////

namespace drawinglayer
{
	namespace primitive3d
	{
		namespace // anonymous namespace
		{
			Primitive3DSequence getLineTubeSegments(
				sal_uInt32 nSegments, 
				const attribute::MaterialAttribute3D& rMaterial)
			{
				// static data for buffered tube primitives
				static Primitive3DSequence aLineTubeList;
				static sal_uInt32 nLineTubeSegments(0L);
				static attribute::MaterialAttribute3D aLineMaterial;

				// may exclusively change static data, use mutex
			    ::osl::Mutex m_mutex;

				if(nSegments != nLineTubeSegments || !(rMaterial == aLineMaterial))
				{
					nLineTubeSegments = nSegments;
					aLineMaterial = rMaterial;
					aLineTubeList = Primitive3DSequence();
				}

				if(!aLineTubeList.hasElements() && 0L != nLineTubeSegments)
				{
					const basegfx::B3DPoint aLeft(0.0, 0.0, 0.0);
					const basegfx::B3DPoint aRight(1.0, 0.0, 0.0);
					basegfx::B3DPoint aLastLeft(0.0, 1.0, 0.0);
					basegfx::B3DPoint aLastRight(1.0, 1.0, 0.0);
					basegfx::B3DHomMatrix aRot;
					aRot.rotate(F_2PI / (double)nLineTubeSegments, 0.0, 0.0);
					aLineTubeList.realloc(nLineTubeSegments);

					for(sal_uInt32 a(0L); a < nLineTubeSegments; a++)
					{
						const basegfx::B3DPoint aNextLeft(aRot * aLastLeft);
						const basegfx::B3DPoint aNextRight(aRot * aLastRight);
						basegfx::B3DPolygon aNewPolygon;
						
						aNewPolygon.append(aNextLeft);
						aNewPolygon.setNormal(0L, basegfx::B3DVector(aNextLeft - aLeft));

						aNewPolygon.append(aLastLeft);
						aNewPolygon.setNormal(1L, basegfx::B3DVector(aLastLeft - aLeft));

						aNewPolygon.append(aLastRight);
						aNewPolygon.setNormal(2L, basegfx::B3DVector(aLastRight - aRight));

						aNewPolygon.append(aNextRight);
						aNewPolygon.setNormal(3L, basegfx::B3DVector(aNextRight - aRight));
						
						aNewPolygon.setClosed(true);

						const basegfx::B3DPolyPolygon aNewPolyPolygon(aNewPolygon);
						const Primitive3DReference xRef(new PolyPolygonMaterialPrimitive3D(aNewPolyPolygon, aLineMaterial, false));
						aLineTubeList[a] = xRef;

						aLastLeft = aNextLeft;
						aLastRight = aNextRight;
					}
				}

				return aLineTubeList;
			}

			Primitive3DSequence getLineCapSegments(
				sal_uInt32 nSegments, 
				const attribute::MaterialAttribute3D& rMaterial)
			{
				// static data for buffered tube primitives
				static Primitive3DSequence aLineCapList;
				static sal_uInt32 nLineCapSegments(0L);
				static attribute::MaterialAttribute3D aLineMaterial;

				// may exclusively change static data, use mutex
			    ::osl::Mutex m_mutex;

				if(nSegments != nLineCapSegments || !(rMaterial == aLineMaterial))
				{
					nLineCapSegments = nSegments;
					aLineMaterial = rMaterial;
					aLineCapList = Primitive3DSequence();
				}

				if(!aLineCapList.hasElements() && 0L != nLineCapSegments)
				{
					const basegfx::B3DPoint aNull(0.0, 0.0, 0.0);
					basegfx::B3DPoint aLast(0.0, 1.0, 0.0);
					basegfx::B3DHomMatrix aRot;
					aRot.rotate(F_2PI / (double)nLineCapSegments, 0.0, 0.0);
					aLineCapList.realloc(nLineCapSegments);

					for(sal_uInt32 a(0L); a < nLineCapSegments; a++)
					{
						const basegfx::B3DPoint aNext(aRot * aLast);
						basegfx::B3DPolygon aNewPolygon;
						
						aNewPolygon.append(aLast);
						aNewPolygon.setNormal(0L, basegfx::B3DVector(aLast - aNull));

						aNewPolygon.append(aNext);
						aNewPolygon.setNormal(1L, basegfx::B3DVector(aNext - aNull));

						aNewPolygon.append(aNull);
						aNewPolygon.setNormal(2L, basegfx::B3DVector(-1.0, 0.0, 0.0));

						aNewPolygon.setClosed(true);

						const basegfx::B3DPolyPolygon aNewPolyPolygon(aNewPolygon);
						const Primitive3DReference xRef(new PolyPolygonMaterialPrimitive3D(aNewPolyPolygon, aLineMaterial, false));
						aLineCapList[a] = xRef;

						aLast = aNext;
					}
				}

				return aLineCapList;
			}

            Primitive3DSequence getLineCapRoundSegments(
                sal_uInt32 nSegments, 
                const attribute::MaterialAttribute3D& rMaterial)
            {
                // static data for buffered tube primitives
                static Primitive3DSequence aLineCapRoundList;
                static sal_uInt32 nLineCapRoundSegments(0);
                static attribute::MaterialAttribute3D aLineMaterial;

                // may exclusively change static data, use mutex
                ::osl::Mutex m_mutex;

                if(nSegments != nLineCapRoundSegments || !(rMaterial == aLineMaterial))
                {
                    nLineCapRoundSegments = nSegments;
                    aLineMaterial = rMaterial;
                    aLineCapRoundList = Primitive3DSequence();
                }
                
                if(!aLineCapRoundList.hasElements() && nLineCapRoundSegments)
                {
                    // calculate new horizontal segments
                    sal_uInt32 nVerSeg(nSegments / 2);

                    if(nVerSeg < 1)
                    {
                        nVerSeg = 1;
                    }

                    // create half-sphere; upper half of unit sphere
                    basegfx::B3DPolyPolygon aSphere(
                        basegfx::tools::createUnitSphereFillPolyPolygon(
                            nSegments, 
                            nVerSeg, 
                            true, 
                            F_PI2, 0.0, 
                            0.0, F_2PI));
                    const sal_uInt32 nCount(aSphere.count());

                    if(nCount)
                    {
                        // rotate to have sphere cap orientned to negative X-Axis; do not
                        // forget to transform normals, too
                        basegfx::B3DHomMatrix aSphereTrans;

                        aSphereTrans.rotate(0.0, 0.0, F_PI2);
                        aSphere.transform(aSphereTrans);
                        aSphere.transformNormals(aSphereTrans);

                        // realloc for primitives and create based on polygon snippets
                        aLineCapRoundList.realloc(nCount);

                        for(sal_uInt32 a(0); a < nCount; a++)
                        {
                            const basegfx::B3DPolygon aPartPolygon(aSphere.getB3DPolygon(a));
                            const basegfx::B3DPolyPolygon aPartPolyPolygon(aPartPolygon);

                            // need to create one primitive per Polygon since the primitive
                            // is for planar PolyPolygons which is definitely not the case here
                            aLineCapRoundList[a] = new PolyPolygonMaterialPrimitive3D(
                                aPartPolyPolygon, 
                                rMaterial, 
                                false);
                        }
                    }
                }
                
                return aLineCapRoundList;
            }

			Primitive3DSequence getLineJoinSegments(
				sal_uInt32 nSegments, 
				const attribute::MaterialAttribute3D& rMaterial, 
				double fAngle,
				double /*fDegreeStepWidth*/, 
				double fMiterMinimumAngle, 
				basegfx::B2DLineJoin aLineJoin)
			{
				// nSegments is for whole circle, adapt to half circle
				const sal_uInt32 nVerSeg(nSegments >> 1L);
				std::vector< BasePrimitive3D* > aResultVector;

				if(nVerSeg)
				{
					if(basegfx::B2DLINEJOIN_ROUND == aLineJoin)
					{
						// calculate new horizontal segments
						const sal_uInt32 nHorSeg(basegfx::fround((fAngle / F_2PI) * (double)nSegments));

						if(nHorSeg)
						{
							// create half-sphere
							const basegfx::B3DPolyPolygon aSphere(basegfx::tools::createUnitSphereFillPolyPolygon(nHorSeg, nVerSeg, true, F_PI2, -F_PI2, 0.0, fAngle));

							for(sal_uInt32 a(0L); a < aSphere.count(); a++)
							{
								const basegfx::B3DPolygon aPartPolygon(aSphere.getB3DPolygon(a));
								const basegfx::B3DPolyPolygon aPartPolyPolygon(aPartPolygon);
								BasePrimitive3D* pNew = new PolyPolygonMaterialPrimitive3D(aPartPolyPolygon, rMaterial, false);
								aResultVector.push_back(pNew);
							}
						}
						else
						{
							// fallback to bevel when there is not at least one segment hor and ver
							aLineJoin = basegfx::B2DLINEJOIN_BEVEL;
						}
					}

					if(basegfx::B2DLINEJOIN_MIDDLE == aLineJoin
						|| basegfx::B2DLINEJOIN_BEVEL == aLineJoin
						|| basegfx::B2DLINEJOIN_MITER == aLineJoin)
					{
						if(basegfx::B2DLINEJOIN_MITER == aLineJoin)
						{
							const double fMiterAngle(fAngle/2.0);

							if(fMiterAngle < fMiterMinimumAngle)
							{
								// fallback to bevel when miter's angle is too small
								aLineJoin = basegfx::B2DLINEJOIN_BEVEL;
							}
						}

						const double fInc(F_PI / (double)nVerSeg);
						const double fSin(sin(-fAngle));
						const double fCos(cos(-fAngle));
						const bool bMiter(basegfx::B2DLINEJOIN_MITER == aLineJoin);
						const double fMiterSin(bMiter ? sin(-(fAngle/2.0)) : 0.0);
						const double fMiterCos(bMiter ? cos(-(fAngle/2.0)) : 0.0);
						double fPos(-F_PI2);
						basegfx::B3DPoint aPointOnXY, aPointRotY, aNextPointOnXY, aNextPointRotY;
						basegfx::B3DPoint aCurrMiter, aNextMiter;
						basegfx::B3DPolygon aNewPolygon, aMiterPolygon;

						// close polygon
						aNewPolygon.setClosed(true);
						aMiterPolygon.setClosed(true);

						for(sal_uInt32 a(0L); a < nVerSeg; a++)
						{
							const bool bFirst(0L == a);
							const bool bLast(a + 1L == nVerSeg);

							if(bFirst || !bLast)
							{
								fPos += fInc;
								
								aNextPointOnXY = basegfx::B3DPoint(
									cos(fPos), 
									sin(fPos), 
									0.0);
								
								aNextPointRotY = basegfx::B3DPoint(
									aNextPointOnXY.getX() * fCos, 
									aNextPointOnXY.getY(), 
									aNextPointOnXY.getX() * fSin);

								if(bMiter)
								{
									aNextMiter = basegfx::B3DPoint(
										aNextPointOnXY.getX(), 
										aNextPointOnXY.getY(), 
										fMiterSin * (aNextPointOnXY.getX() / fMiterCos));
								}
							}
							
							if(bFirst)
							{
								aNewPolygon.clear();

								if(bMiter)
								{
									aNewPolygon.append(basegfx::B3DPoint(0.0, -1.0, 0.0));
									aNewPolygon.append(aNextPointOnXY);
									aNewPolygon.append(aNextMiter);

									aMiterPolygon.clear();
									aMiterPolygon.append(basegfx::B3DPoint(0.0, -1.0, 0.0));
									aMiterPolygon.append(aNextMiter);
									aMiterPolygon.append(aNextPointRotY);
								}
								else
								{
									aNewPolygon.append(basegfx::B3DPoint(0.0, -1.0, 0.0));
									aNewPolygon.append(aNextPointOnXY);
									aNewPolygon.append(aNextPointRotY);
								}
							}
							else if(bLast)
							{
								aNewPolygon.clear();
		
								if(bMiter)
								{
									aNewPolygon.append(basegfx::B3DPoint(0.0, 1.0, 0.0));
									aNewPolygon.append(aCurrMiter);
									aNewPolygon.append(aPointOnXY);

									aMiterPolygon.clear();
									aMiterPolygon.append(basegfx::B3DPoint(0.0, 1.0, 0.0));
									aMiterPolygon.append(aPointRotY);
									aMiterPolygon.append(aCurrMiter);
								}
								else
								{
									aNewPolygon.append(basegfx::B3DPoint(0.0, 1.0, 0.0));
									aNewPolygon.append(aPointRotY);
									aNewPolygon.append(aPointOnXY);
								}
							}
							else
							{
								aNewPolygon.clear();

								if(bMiter)
								{
									aNewPolygon.append(aPointOnXY);
									aNewPolygon.append(aNextPointOnXY);
									aNewPolygon.append(aNextMiter);
									aNewPolygon.append(aCurrMiter);

									aMiterPolygon.clear();
									aMiterPolygon.append(aCurrMiter);
									aMiterPolygon.append(aNextMiter);
									aMiterPolygon.append(aNextPointRotY);
									aMiterPolygon.append(aPointRotY);
								}
								else
								{
									aNewPolygon.append(aPointRotY);
									aNewPolygon.append(aPointOnXY);
									aNewPolygon.append(aNextPointOnXY);
									aNewPolygon.append(aNextPointRotY);
								}
							}
						
							// set normals
							for(sal_uInt32 b(0L); b < aNewPolygon.count(); b++)
							{
								aNewPolygon.setNormal(b, basegfx::B3DVector(aNewPolygon.getB3DPoint(b)));
							}

							// create primitive
							if(aNewPolygon.count())
							{
								const basegfx::B3DPolyPolygon aNewPolyPolygon(aNewPolygon);
								BasePrimitive3D* pNew = new PolyPolygonMaterialPrimitive3D(aNewPolyPolygon, rMaterial, false);
								aResultVector.push_back(pNew);
							}
							
							if(bMiter && aMiterPolygon.count())
							{
								// set normals
								for(sal_uInt32 c(0L); c < aMiterPolygon.count(); c++)
								{
									aMiterPolygon.setNormal(c, basegfx::B3DVector(aMiterPolygon.getB3DPoint(c)));
								}

								// create primitive
								const basegfx::B3DPolyPolygon aMiterPolyPolygon(aMiterPolygon);
								BasePrimitive3D* pNew = new PolyPolygonMaterialPrimitive3D(aMiterPolyPolygon, rMaterial, false);
								aResultVector.push_back(pNew);
							}
							
							// prepare next step
							if(bFirst || !bLast)
							{
								aPointOnXY = aNextPointOnXY;
								aPointRotY = aNextPointRotY;
								
								if(bMiter)
								{
									aCurrMiter = aNextMiter;
								}
							}
						}
					}
				}

				Primitive3DSequence aRetval(aResultVector.size());

				for(sal_uInt32 a(0L); a < aResultVector.size(); a++)
				{
					aRetval[a] = Primitive3DReference(aResultVector[a]);
				}

				return aRetval;
			}

			basegfx::B3DHomMatrix getRotationFromVector(const basegfx::B3DVector& rVector)
			{
				// build transformation from unit vector to vector
				basegfx::B3DHomMatrix aRetval;

				// get applied rotations from angles in XY and in XZ (cartesian)
				const double fRotInXY(atan2(rVector.getY(), rVector.getXZLength()));
				const double fRotInXZ(atan2(-rVector.getZ(), rVector.getX()));

				// apply rotations. Rot around Z needs to be done first, so apply in two steps
				aRetval.rotate(0.0, 0.0, fRotInXY);
				aRetval.rotate(0.0, fRotInXZ, 0.0);

				return aRetval;
			}
		} // end of anonymous namespace
	} // end of namespace primitive3d
} // end of namespace drawinglayer

//////////////////////////////////////////////////////////////////////////////

using namespace com::sun::star;

//////////////////////////////////////////////////////////////////////////////

namespace drawinglayer
{
    namespace primitive3d
    {
        Primitive3DSequence PolygonTubePrimitive3D::impCreate3DDecomposition(const geometry::ViewInformation3D& /*rViewInformation*/) const
        {
            const sal_uInt32 nPointCount(getB3DPolygon().count());
            std::vector< BasePrimitive3D* > aResultVector;
            
            if(nPointCount)
            {
                if(basegfx::fTools::more(getRadius(), 0.0))
                {
                    const attribute::MaterialAttribute3D aMaterial(getBColor());
                    static sal_uInt32 nSegments(8); // default for 3d line segments, for more quality just raise this value (in even steps)
                    const bool bClosed(getB3DPolygon().isClosed());
                    const bool bNoLineJoin(basegfx::B2DLINEJOIN_NONE == getLineJoin());
                    const sal_uInt32 nLoopCount(bClosed ? nPointCount : nPointCount - 1);
                    basegfx::B3DPoint aLast(getB3DPolygon().getB3DPoint(nPointCount - 1));
                    basegfx::B3DPoint aCurr(getB3DPolygon().getB3DPoint(0));
                    
                    for(sal_uInt32 a(0); a < nLoopCount; a++)
                    {
                        // get next data
                        const basegfx::B3DPoint aNext(getB3DPolygon().getB3DPoint((a + 1) % nPointCount));
                        const basegfx::B3DVector aForw(aNext - aCurr);
                        const double fForwLen(aForw.getLength());
                        
                        if(basegfx::fTools::more(fForwLen, 0.0))
                        {
                            // find out if linecap is active
                            const bool bFirst(!a);
                            const bool bLast(a + 1 == nLoopCount);
                            const bool bLineCapPossible(!bClosed && (bFirst || bLast));
                            const bool bLineCapRound(bLineCapPossible && com::sun::star::drawing::LineCap_ROUND == getLineCap());
                            const bool bLineCapSquare(bLineCapPossible && com::sun::star::drawing::LineCap_SQUARE == getLineCap());

                            // get rotation from vector, this describes rotation from (1, 0, 0) to aForw
                            basegfx::B3DHomMatrix aRotVector(getRotationFromVector(aForw));

                            // prepare transformations for tube and cap
                            basegfx::B3DHomMatrix aTubeTrans;
                            basegfx::B3DHomMatrix aCapTrans;

                            // cap gets radius size
                            aCapTrans.scale(getRadius(), getRadius(), getRadius());

                            if(bLineCapSquare)
                            {
                                // when square line cap just prolong line segment in X, maybe 2 x radius when
                                // first and last (simple line segment)
                                const double fExtraLength(bFirst && bLast ? getRadius() * 2.0 : getRadius());
                                
                                aTubeTrans.scale(fForwLen + fExtraLength, getRadius(), getRadius());

                                if(bFirst)
                                {
                                    // correct start positions for tube and cap when first and square prolonged
                                    aTubeTrans.translate(-getRadius(), 0.0, 0.0);
                                    aCapTrans.translate(-getRadius(), 0.0, 0.0);
                                }
                            }
                            else
                            {
                                // normal tube size
                                aTubeTrans.scale(fForwLen, getRadius(), getRadius());
                            }

                            // rotate and translate tube and cap
                            aTubeTrans *= aRotVector;
                            aTubeTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
                            aCapTrans *= aRotVector;
                            aCapTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());

                            if(bNoLineJoin || (!bClosed && bFirst))
                            {
                                // line start edge, build transformed primitiveVector3D
                                Primitive3DSequence aSequence;

                                if(bLineCapRound && bFirst)
                                {
                                    // LineCapRound used
                                    aSequence = getLineCapRoundSegments(nSegments, aMaterial);
                                }
                                else
                                {
                                    // simple closing cap
                                    aSequence = getLineCapSegments(nSegments, aMaterial);
                                }

                                TransformPrimitive3D* pNewTransformedA = new TransformPrimitive3D(aCapTrans, aSequence);
                                aResultVector.push_back(pNewTransformedA);
                            }
                            else
                            {
                                const basegfx::B3DVector aBack(aCurr - aLast);
                                const double fCross(basegfx::cross(aBack, aForw).getLength());

                                if(!basegfx::fTools::equalZero(fCross))
                                {
                                    // line connect non-parallel, aBack, aForw, use getLineJoin()
                                    const double fAngle(acos(aBack.scalar(aForw) / (fForwLen * aBack.getLength()))); // 0.0 .. F_PI2
                                    Primitive3DSequence aNewList(
                                        getLineJoinSegments(
                                            nSegments, 
                                            aMaterial, 
                                            fAngle, 
                                            getDegreeStepWidth(), 
                                            getMiterMinimumAngle(), 
                                            getLineJoin()));

                                    // calculate transformation. First, get angle in YZ between nForw projected on (1, 0, 0) and nBack
                                    basegfx::B3DHomMatrix aInvRotVector(aRotVector);
                                    aInvRotVector.invert();
                                    basegfx::B3DVector aTransBack(aInvRotVector * aBack);
                                    const double fRotInYZ(atan2(aTransBack.getY(), aTransBack.getZ()));
                                    
                                    // create trans by rotating unit sphere with angle 90 degrees around Y, then 180-fRot in X.
                                    // Also apply usual scaling and translation
                                    basegfx::B3DHomMatrix aSphereTrans;
                                    aSphereTrans.rotate(0.0, F_PI2, 0.0);
                                    aSphereTrans.rotate(F_PI - fRotInYZ, 0.0, 0.0);
                                    aSphereTrans *= aRotVector;
                                    aSphereTrans.scale(getRadius(), getRadius(), getRadius());
                                    aSphereTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());
                                    
                                    // line start edge, build transformed primitiveVector3D
                                    aResultVector.push_back(
                                        new TransformPrimitive3D(
                                            aSphereTrans, 
                                            aNewList));
                                }
                            }

                            // create line segments, build transformed primitiveVector3D
                            aResultVector.push_back(
                                new TransformPrimitive3D(
                                    aTubeTrans, 
                                    getLineTubeSegments(nSegments, aMaterial)));

                            if(bNoLineJoin || (!bClosed && bLast))
                            {
                                // line end edge
                                basegfx::B3DHomMatrix aBackCapTrans;

                                // Mirror (line end) and radius scale
                                aBackCapTrans.rotate(0.0, F_PI, 0.0);
                                aBackCapTrans.scale(getRadius(), getRadius(), getRadius());

                                if(bLineCapSquare && bLast)
                                {
                                    // correct position when square and prolonged
                                    aBackCapTrans.translate(fForwLen + getRadius(), 0.0, 0.0);
                                }
                                else
                                {
                                    // standard position
                                    aBackCapTrans.translate(fForwLen, 0.0, 0.0);
                                }

                                // rotate and translate to destination
                                aBackCapTrans *= aRotVector;
                                aBackCapTrans.translate(aCurr.getX(), aCurr.getY(), aCurr.getZ());

                                // get primitiveVector3D
                                Primitive3DSequence aSequence;

                                if(bLineCapRound && bLast)
                                {
                                    // LineCapRound used
                                    aSequence = getLineCapRoundSegments(nSegments, aMaterial);
                                }
                                else
                                {
                                    // simple closing cap
                                    aSequence = getLineCapSegments(nSegments, aMaterial);
                                }

                                aResultVector.push_back(
                                    new TransformPrimitive3D(
                                        aBackCapTrans, 
                                        aSequence));
                            }
                        }

						// prepare next loop step
						aLast = aCurr;
						aCurr = aNext;
					}
				}
				else
				{
					// create hairline
					PolygonHairlinePrimitive3D* pNew = new PolygonHairlinePrimitive3D(getB3DPolygon(), getBColor());
					aResultVector.push_back(pNew);
				}
			}

			// prepare return value
			Primitive3DSequence aRetval(aResultVector.size());

			for(sal_uInt32 a(0L); a < aResultVector.size(); a++)
			{
				aRetval[a] = Primitive3DReference(aResultVector[a]);
			}

			return aRetval;
		}

		PolygonTubePrimitive3D::PolygonTubePrimitive3D(
			const basegfx::B3DPolygon& rPolygon, 
			const basegfx::BColor& rBColor,
			double fRadius, basegfx::B2DLineJoin aLineJoin,
            com::sun::star::drawing::LineCap aLineCap,
			double fDegreeStepWidth,
			double fMiterMinimumAngle)
		:	PolygonHairlinePrimitive3D(rPolygon, rBColor),
			maLast3DDecomposition(),
            mfRadius(fRadius),
			mfDegreeStepWidth(fDegreeStepWidth),
			mfMiterMinimumAngle(fMiterMinimumAngle),
			maLineJoin(aLineJoin),
            maLineCap(aLineCap)
		{
		}

		bool PolygonTubePrimitive3D::operator==(const BasePrimitive3D& rPrimitive) const
		{
			if(PolygonHairlinePrimitive3D::operator==(rPrimitive))
			{
				const PolygonTubePrimitive3D& rCompare = (PolygonTubePrimitive3D&)rPrimitive;

				return (getRadius() == rCompare.getRadius()
					&& getDegreeStepWidth() == rCompare.getDegreeStepWidth()
					&& getMiterMinimumAngle() == rCompare.getMiterMinimumAngle()
					&& getLineJoin() == rCompare.getLineJoin()
                    && getLineCap() == rCompare.getLineCap());
			}

			return false;
		}

		Primitive3DSequence PolygonTubePrimitive3D::get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const
		{
			::osl::MutexGuard aGuard( m_aMutex );

			if(!getLast3DDecomposition().hasElements())
			{
				const Primitive3DSequence aNewSequence(impCreate3DDecomposition(rViewInformation));
				const_cast< PolygonTubePrimitive3D* >(this)->setLast3DDecomposition(aNewSequence);
			}

			return getLast3DDecomposition();
		}

        // provide unique ID
		ImplPrimitrive3DIDBlock(PolygonTubePrimitive3D, PRIMITIVE3D_ID_POLYGONTUBEPRIMITIVE3D)

	} // end of namespace primitive3d
} // end of namespace drawinglayer

//////////////////////////////////////////////////////////////////////////////
// eof
