xref: /trunk/main/basegfx/source/polygon/b3dpolygon.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*09dbbe93SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*09dbbe93SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*09dbbe93SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*09dbbe93SAndrew Rist  * distributed with this work for additional information
6*09dbbe93SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*09dbbe93SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*09dbbe93SAndrew Rist  * "License"); you may not use this file except in compliance
9*09dbbe93SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*09dbbe93SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*09dbbe93SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*09dbbe93SAndrew Rist  * software distributed under the License is distributed on an
15*09dbbe93SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*09dbbe93SAndrew Rist  * KIND, either express or implied.  See the License for the
17*09dbbe93SAndrew Rist  * specific language governing permissions and limitations
18*09dbbe93SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*09dbbe93SAndrew Rist  *************************************************************/
21*09dbbe93SAndrew Rist 
22*09dbbe93SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_basegfx.hxx"
26cdf0e10cSrcweir #include <osl/diagnose.h>
27cdf0e10cSrcweir #include <basegfx/polygon/b3dpolygon.hxx>
28cdf0e10cSrcweir #include <basegfx/point/b3dpoint.hxx>
29cdf0e10cSrcweir #include <basegfx/matrix/b3dhommatrix.hxx>
30cdf0e10cSrcweir #include <rtl/instance.hxx>
31cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
32cdf0e10cSrcweir #include <basegfx/color/bcolor.hxx>
33cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
34cdf0e10cSrcweir #include <vector>
35cdf0e10cSrcweir #include <algorithm>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
38cdf0e10cSrcweir 
39cdf0e10cSrcweir class CoordinateData3D
40cdf0e10cSrcweir {
41cdf0e10cSrcweir     basegfx::B3DPoint                               maPoint;
42cdf0e10cSrcweir 
43cdf0e10cSrcweir public:
CoordinateData3D()44cdf0e10cSrcweir     CoordinateData3D()
45cdf0e10cSrcweir     :   maPoint()
46cdf0e10cSrcweir     {
47cdf0e10cSrcweir     }
48cdf0e10cSrcweir 
CoordinateData3D(const basegfx::B3DPoint & rData)49cdf0e10cSrcweir     explicit CoordinateData3D(const basegfx::B3DPoint& rData)
50cdf0e10cSrcweir     :   maPoint(rData)
51cdf0e10cSrcweir     {
52cdf0e10cSrcweir     }
53cdf0e10cSrcweir 
getCoordinate() const54cdf0e10cSrcweir     const basegfx::B3DPoint& getCoordinate() const
55cdf0e10cSrcweir     {
56cdf0e10cSrcweir         return maPoint;
57cdf0e10cSrcweir     }
58cdf0e10cSrcweir 
setCoordinate(const basegfx::B3DPoint & rValue)59cdf0e10cSrcweir     void setCoordinate(const basegfx::B3DPoint& rValue)
60cdf0e10cSrcweir     {
61cdf0e10cSrcweir         if(rValue != maPoint)
62cdf0e10cSrcweir             maPoint = rValue;
63cdf0e10cSrcweir     }
64cdf0e10cSrcweir 
operator ==(const CoordinateData3D & rData) const65cdf0e10cSrcweir     bool operator==(const CoordinateData3D& rData) const
66cdf0e10cSrcweir     {
67cdf0e10cSrcweir         return (maPoint == rData.getCoordinate());
68cdf0e10cSrcweir     }
69cdf0e10cSrcweir 
transform(const basegfx::B3DHomMatrix & rMatrix)70cdf0e10cSrcweir     void transform(const basegfx::B3DHomMatrix& rMatrix)
71cdf0e10cSrcweir     {
72cdf0e10cSrcweir         maPoint *= rMatrix;
73cdf0e10cSrcweir     }
74cdf0e10cSrcweir };
75cdf0e10cSrcweir 
76cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
77cdf0e10cSrcweir 
78cdf0e10cSrcweir class CoordinateDataArray3D
79cdf0e10cSrcweir {
80cdf0e10cSrcweir     typedef ::std::vector< CoordinateData3D > CoordinateData3DVector;
81cdf0e10cSrcweir 
82cdf0e10cSrcweir     CoordinateData3DVector                          maVector;
83cdf0e10cSrcweir 
84cdf0e10cSrcweir public:
CoordinateDataArray3D(sal_uInt32 nCount)85cdf0e10cSrcweir     explicit CoordinateDataArray3D(sal_uInt32 nCount)
86cdf0e10cSrcweir     :   maVector(nCount)
87cdf0e10cSrcweir     {
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir 
CoordinateDataArray3D(const CoordinateDataArray3D & rOriginal)90cdf0e10cSrcweir     explicit CoordinateDataArray3D(const CoordinateDataArray3D& rOriginal)
91cdf0e10cSrcweir     :   maVector(rOriginal.maVector)
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir     }
94cdf0e10cSrcweir 
CoordinateDataArray3D(const CoordinateDataArray3D & rOriginal,sal_uInt32 nIndex,sal_uInt32 nCount)95cdf0e10cSrcweir     CoordinateDataArray3D(const CoordinateDataArray3D& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount)
96cdf0e10cSrcweir     :   maVector(rOriginal.maVector.begin() + nIndex, rOriginal.maVector.begin() + (nIndex + nCount))
97cdf0e10cSrcweir     {
98cdf0e10cSrcweir     }
99cdf0e10cSrcweir 
~CoordinateDataArray3D()100cdf0e10cSrcweir     ~CoordinateDataArray3D()
101cdf0e10cSrcweir     {
102cdf0e10cSrcweir     }
103cdf0e10cSrcweir 
getNormal() const104cdf0e10cSrcweir     ::basegfx::B3DVector getNormal() const
105cdf0e10cSrcweir     {
106cdf0e10cSrcweir         ::basegfx::B3DVector aRetval;
107cdf0e10cSrcweir         const sal_uInt32 nPointCount(maVector.size());
108cdf0e10cSrcweir 
109cdf0e10cSrcweir         if(nPointCount > 2)
110cdf0e10cSrcweir         {
111cdf0e10cSrcweir             sal_uInt32 nISmallest(0);
112cdf0e10cSrcweir             sal_uInt32 a(0);
113cdf0e10cSrcweir             const basegfx::B3DPoint* pSmallest(&maVector[0].getCoordinate());
114cdf0e10cSrcweir             const basegfx::B3DPoint* pNext(0);
115cdf0e10cSrcweir             const basegfx::B3DPoint* pPrev(0);
116cdf0e10cSrcweir 
117cdf0e10cSrcweir             // To guarantee a correctly oriented point, choose an outmost one
118cdf0e10cSrcweir             // which then cannot be concave
119cdf0e10cSrcweir             for(a = 1; a < nPointCount; a++)
120cdf0e10cSrcweir             {
121cdf0e10cSrcweir                 const basegfx::B3DPoint& rCandidate = maVector[a].getCoordinate();
122cdf0e10cSrcweir 
123cdf0e10cSrcweir                 if((rCandidate.getX() < pSmallest->getX())
124cdf0e10cSrcweir                     || (rCandidate.getX() == pSmallest->getX() && rCandidate.getY() < pSmallest->getY())
125cdf0e10cSrcweir                     || (rCandidate.getX() == pSmallest->getX() && rCandidate.getY() == pSmallest->getY() && rCandidate.getZ() < pSmallest->getZ()))
126cdf0e10cSrcweir                 {
127cdf0e10cSrcweir                     nISmallest = a;
128cdf0e10cSrcweir                     pSmallest = &rCandidate;
129cdf0e10cSrcweir                 }
130cdf0e10cSrcweir             }
131cdf0e10cSrcweir 
132cdf0e10cSrcweir             // look for a next point different from minimal one
133cdf0e10cSrcweir             for(a = (nISmallest + 1) % nPointCount; a != nISmallest; a = (a + 1) % nPointCount)
134cdf0e10cSrcweir             {
135cdf0e10cSrcweir                 const basegfx::B3DPoint& rCandidate = maVector[a].getCoordinate();
136cdf0e10cSrcweir 
137cdf0e10cSrcweir                 if(!rCandidate.equal(*pSmallest))
138cdf0e10cSrcweir                 {
139cdf0e10cSrcweir                     pNext = &rCandidate;
140cdf0e10cSrcweir                     break;
141cdf0e10cSrcweir                 }
142cdf0e10cSrcweir             }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir             // look for a previous point different from minimal one
145cdf0e10cSrcweir             for(a = (nISmallest + nPointCount - 1) % nPointCount; a != nISmallest; a = (a + nPointCount - 1) % nPointCount)
146cdf0e10cSrcweir             {
147cdf0e10cSrcweir                 const basegfx::B3DPoint& rCandidate = maVector[a].getCoordinate();
148cdf0e10cSrcweir 
149cdf0e10cSrcweir                 if(!rCandidate.equal(*pSmallest))
150cdf0e10cSrcweir                 {
151cdf0e10cSrcweir                     pPrev = &rCandidate;
152cdf0e10cSrcweir                     break;
153cdf0e10cSrcweir                 }
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir             // we always have a minimal point. If we also have a different next and previous,
157cdf0e10cSrcweir             // we can calculate the normal
158cdf0e10cSrcweir             if(pNext && pPrev)
159cdf0e10cSrcweir             {
160cdf0e10cSrcweir                 const basegfx::B3DVector aPrev(*pPrev - *pSmallest);
161cdf0e10cSrcweir                 const basegfx::B3DVector aNext(*pNext - *pSmallest);
162cdf0e10cSrcweir 
163cdf0e10cSrcweir                 aRetval = cross(aPrev, aNext);
164cdf0e10cSrcweir                 aRetval.normalize();
165cdf0e10cSrcweir             }
166cdf0e10cSrcweir         }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir         return aRetval;
169cdf0e10cSrcweir     }
170cdf0e10cSrcweir 
count() const171cdf0e10cSrcweir     sal_uInt32 count() const
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         return maVector.size();
174cdf0e10cSrcweir     }
175cdf0e10cSrcweir 
operator ==(const CoordinateDataArray3D & rCandidate) const176cdf0e10cSrcweir     bool operator==(const CoordinateDataArray3D& rCandidate) const
177cdf0e10cSrcweir     {
178cdf0e10cSrcweir         return (maVector == rCandidate.maVector);
179cdf0e10cSrcweir     }
180cdf0e10cSrcweir 
getCoordinate(sal_uInt32 nIndex) const181cdf0e10cSrcweir     const basegfx::B3DPoint& getCoordinate(sal_uInt32 nIndex) const
182cdf0e10cSrcweir     {
183cdf0e10cSrcweir         return maVector[nIndex].getCoordinate();
184cdf0e10cSrcweir     }
185cdf0e10cSrcweir 
setCoordinate(sal_uInt32 nIndex,const basegfx::B3DPoint & rValue)186cdf0e10cSrcweir     void setCoordinate(sal_uInt32 nIndex, const basegfx::B3DPoint& rValue)
187cdf0e10cSrcweir     {
188cdf0e10cSrcweir         maVector[nIndex].setCoordinate(rValue);
189cdf0e10cSrcweir     }
190cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const CoordinateData3D & rValue,sal_uInt32 nCount)191cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const CoordinateData3D& rValue, sal_uInt32 nCount)
192cdf0e10cSrcweir     {
193cdf0e10cSrcweir         if(nCount)
194cdf0e10cSrcweir         {
195cdf0e10cSrcweir             // add nCount copies of rValue
196cdf0e10cSrcweir             CoordinateData3DVector::iterator aIndex(maVector.begin());
197cdf0e10cSrcweir             aIndex += nIndex;
198cdf0e10cSrcweir             maVector.insert(aIndex, nCount, rValue);
199cdf0e10cSrcweir         }
200cdf0e10cSrcweir     }
201cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const CoordinateDataArray3D & rSource)202cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const CoordinateDataArray3D& rSource)
203cdf0e10cSrcweir     {
204cdf0e10cSrcweir         const sal_uInt32 nCount(rSource.maVector.size());
205cdf0e10cSrcweir 
206cdf0e10cSrcweir         if(nCount)
207cdf0e10cSrcweir         {
208cdf0e10cSrcweir             // insert data
209cdf0e10cSrcweir             CoordinateData3DVector::iterator aIndex(maVector.begin());
210cdf0e10cSrcweir             aIndex += nIndex;
211cdf0e10cSrcweir             CoordinateData3DVector::const_iterator aStart(rSource.maVector.begin());
212cdf0e10cSrcweir             CoordinateData3DVector::const_iterator aEnd(rSource.maVector.end());
213cdf0e10cSrcweir             maVector.insert(aIndex, aStart, aEnd);
214cdf0e10cSrcweir         }
215cdf0e10cSrcweir     }
216cdf0e10cSrcweir 
remove(sal_uInt32 nIndex,sal_uInt32 nCount)217cdf0e10cSrcweir     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
218cdf0e10cSrcweir     {
219cdf0e10cSrcweir         if(nCount)
220cdf0e10cSrcweir         {
221cdf0e10cSrcweir             // remove point data
222cdf0e10cSrcweir             CoordinateData3DVector::iterator aStart(maVector.begin());
223cdf0e10cSrcweir             aStart += nIndex;
224cdf0e10cSrcweir             const CoordinateData3DVector::iterator aEnd(aStart + nCount);
225cdf0e10cSrcweir             maVector.erase(aStart, aEnd);
226cdf0e10cSrcweir         }
227cdf0e10cSrcweir     }
228cdf0e10cSrcweir 
flip()229cdf0e10cSrcweir     void flip()
230cdf0e10cSrcweir     {
231cdf0e10cSrcweir         if(maVector.size() > 1)
232cdf0e10cSrcweir         {
233cdf0e10cSrcweir             const sal_uInt32 nHalfSize(maVector.size() >> 1L);
234cdf0e10cSrcweir             CoordinateData3DVector::iterator aStart(maVector.begin());
235cdf0e10cSrcweir             CoordinateData3DVector::iterator aEnd(maVector.end() - 1L);
236cdf0e10cSrcweir 
237cdf0e10cSrcweir             for(sal_uInt32 a(0); a < nHalfSize; a++)
238cdf0e10cSrcweir             {
239cdf0e10cSrcweir                 ::std::swap(*aStart, *aEnd);
240cdf0e10cSrcweir                 aStart++;
241cdf0e10cSrcweir                 aEnd--;
242cdf0e10cSrcweir             }
243cdf0e10cSrcweir         }
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir 
transform(const::basegfx::B3DHomMatrix & rMatrix)246cdf0e10cSrcweir     void transform(const ::basegfx::B3DHomMatrix& rMatrix)
247cdf0e10cSrcweir     {
248cdf0e10cSrcweir         CoordinateData3DVector::iterator aStart(maVector.begin());
249cdf0e10cSrcweir         CoordinateData3DVector::iterator aEnd(maVector.end());
250cdf0e10cSrcweir 
251cdf0e10cSrcweir         for(; aStart != aEnd; aStart++)
252cdf0e10cSrcweir         {
253cdf0e10cSrcweir             aStart->transform(rMatrix);
254cdf0e10cSrcweir         }
255cdf0e10cSrcweir     }
256cdf0e10cSrcweir };
257cdf0e10cSrcweir 
258cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
259cdf0e10cSrcweir 
260cdf0e10cSrcweir class BColorArray
261cdf0e10cSrcweir {
262cdf0e10cSrcweir     typedef ::std::vector< ::basegfx::BColor > BColorDataVector;
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     BColorDataVector                                    maVector;
265cdf0e10cSrcweir     sal_uInt32                                          mnUsedEntries;
266cdf0e10cSrcweir 
267cdf0e10cSrcweir public:
BColorArray(sal_uInt32 nCount)268cdf0e10cSrcweir     explicit BColorArray(sal_uInt32 nCount)
269cdf0e10cSrcweir     :   maVector(nCount),
270cdf0e10cSrcweir         mnUsedEntries(0L)
271cdf0e10cSrcweir     {
272cdf0e10cSrcweir     }
273cdf0e10cSrcweir 
BColorArray(const BColorArray & rOriginal)274cdf0e10cSrcweir     explicit BColorArray(const BColorArray& rOriginal)
275cdf0e10cSrcweir     :   maVector(rOriginal.maVector),
276cdf0e10cSrcweir         mnUsedEntries(rOriginal.mnUsedEntries)
277cdf0e10cSrcweir     {
278cdf0e10cSrcweir     }
279cdf0e10cSrcweir 
BColorArray(const BColorArray & rOriginal,sal_uInt32 nIndex,sal_uInt32 nCount)280cdf0e10cSrcweir     BColorArray(const BColorArray& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount)
281cdf0e10cSrcweir     :   maVector(),
282cdf0e10cSrcweir         mnUsedEntries(0L)
283cdf0e10cSrcweir     {
284cdf0e10cSrcweir         BColorDataVector::const_iterator aStart(rOriginal.maVector.begin());
285cdf0e10cSrcweir         aStart += nIndex;
286cdf0e10cSrcweir         BColorDataVector::const_iterator aEnd(aStart);
287cdf0e10cSrcweir         aEnd += nCount;
288cdf0e10cSrcweir         maVector.reserve(nCount);
289cdf0e10cSrcweir 
290cdf0e10cSrcweir         for(; aStart != aEnd; aStart++)
291cdf0e10cSrcweir         {
292cdf0e10cSrcweir             if(!aStart->equalZero())
293cdf0e10cSrcweir                 mnUsedEntries++;
294cdf0e10cSrcweir 
295cdf0e10cSrcweir             maVector.push_back(*aStart);
296cdf0e10cSrcweir         }
297cdf0e10cSrcweir     }
298cdf0e10cSrcweir 
~BColorArray()299cdf0e10cSrcweir     ~BColorArray()
300cdf0e10cSrcweir     {
301cdf0e10cSrcweir     }
302cdf0e10cSrcweir 
count() const303cdf0e10cSrcweir     sal_uInt32 count() const
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         return maVector.size();
306cdf0e10cSrcweir     }
307cdf0e10cSrcweir 
operator ==(const BColorArray & rCandidate) const308cdf0e10cSrcweir     bool operator==(const BColorArray& rCandidate) const
309cdf0e10cSrcweir     {
310cdf0e10cSrcweir         return (maVector == rCandidate.maVector);
311cdf0e10cSrcweir     }
312cdf0e10cSrcweir 
isUsed() const313cdf0e10cSrcweir     bool isUsed() const
314cdf0e10cSrcweir     {
315cdf0e10cSrcweir         return (0L != mnUsedEntries);
316cdf0e10cSrcweir     }
317cdf0e10cSrcweir 
getBColor(sal_uInt32 nIndex) const318cdf0e10cSrcweir     const ::basegfx::BColor& getBColor(sal_uInt32 nIndex) const
319cdf0e10cSrcweir     {
320cdf0e10cSrcweir         return maVector[nIndex];
321cdf0e10cSrcweir     }
322cdf0e10cSrcweir 
setBColor(sal_uInt32 nIndex,const::basegfx::BColor & rValue)323cdf0e10cSrcweir     void setBColor(sal_uInt32 nIndex, const ::basegfx::BColor& rValue)
324cdf0e10cSrcweir     {
325cdf0e10cSrcweir         bool bWasUsed(mnUsedEntries && !maVector[nIndex].equalZero());
326cdf0e10cSrcweir         bool bIsUsed(!rValue.equalZero());
327cdf0e10cSrcweir 
328cdf0e10cSrcweir         if(bWasUsed)
329cdf0e10cSrcweir         {
330cdf0e10cSrcweir             if(bIsUsed)
331cdf0e10cSrcweir             {
332cdf0e10cSrcweir                 maVector[nIndex] = rValue;
333cdf0e10cSrcweir             }
334cdf0e10cSrcweir             else
335cdf0e10cSrcweir             {
336cdf0e10cSrcweir                 maVector[nIndex] = ::basegfx::BColor::getEmptyBColor();
337cdf0e10cSrcweir                 mnUsedEntries--;
338cdf0e10cSrcweir             }
339cdf0e10cSrcweir         }
340cdf0e10cSrcweir         else
341cdf0e10cSrcweir         {
342cdf0e10cSrcweir             if(bIsUsed)
343cdf0e10cSrcweir             {
344cdf0e10cSrcweir                 maVector[nIndex] = rValue;
345cdf0e10cSrcweir                 mnUsedEntries++;
346cdf0e10cSrcweir             }
347cdf0e10cSrcweir         }
348cdf0e10cSrcweir     }
349cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const::basegfx::BColor & rValue,sal_uInt32 nCount)350cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const ::basegfx::BColor& rValue, sal_uInt32 nCount)
351cdf0e10cSrcweir     {
352cdf0e10cSrcweir         if(nCount)
353cdf0e10cSrcweir         {
354cdf0e10cSrcweir             // add nCount copies of rValue
355cdf0e10cSrcweir             BColorDataVector::iterator aIndex(maVector.begin());
356cdf0e10cSrcweir             aIndex += nIndex;
357cdf0e10cSrcweir             maVector.insert(aIndex, nCount, rValue);
358cdf0e10cSrcweir 
359cdf0e10cSrcweir             if(!rValue.equalZero())
360cdf0e10cSrcweir                 mnUsedEntries += nCount;
361cdf0e10cSrcweir         }
362cdf0e10cSrcweir     }
363cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const BColorArray & rSource)364cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const BColorArray& rSource)
365cdf0e10cSrcweir     {
366cdf0e10cSrcweir         const sal_uInt32 nCount(rSource.maVector.size());
367cdf0e10cSrcweir 
368cdf0e10cSrcweir         if(nCount)
369cdf0e10cSrcweir         {
370cdf0e10cSrcweir             // insert data
371cdf0e10cSrcweir             BColorDataVector::iterator aIndex(maVector.begin());
372cdf0e10cSrcweir             aIndex += nIndex;
373cdf0e10cSrcweir             BColorDataVector::const_iterator aStart(rSource.maVector.begin());
374cdf0e10cSrcweir             BColorDataVector::const_iterator aEnd(rSource.maVector.end());
375cdf0e10cSrcweir             maVector.insert(aIndex, aStart, aEnd);
376cdf0e10cSrcweir 
377cdf0e10cSrcweir             for(; aStart != aEnd; aStart++)
378cdf0e10cSrcweir             {
379cdf0e10cSrcweir                 if(!aStart->equalZero())
380cdf0e10cSrcweir                     mnUsedEntries++;
381cdf0e10cSrcweir             }
382cdf0e10cSrcweir         }
383cdf0e10cSrcweir     }
384cdf0e10cSrcweir 
remove(sal_uInt32 nIndex,sal_uInt32 nCount)385cdf0e10cSrcweir     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
386cdf0e10cSrcweir     {
387cdf0e10cSrcweir         if(nCount)
388cdf0e10cSrcweir         {
389cdf0e10cSrcweir             const BColorDataVector::iterator aDeleteStart(maVector.begin() + nIndex);
390cdf0e10cSrcweir             const BColorDataVector::iterator aDeleteEnd(aDeleteStart + nCount);
391cdf0e10cSrcweir             BColorDataVector::const_iterator aStart(aDeleteStart);
392cdf0e10cSrcweir 
393cdf0e10cSrcweir             for(; mnUsedEntries && aStart != aDeleteEnd; aStart++)
394cdf0e10cSrcweir             {
395cdf0e10cSrcweir                 if(!aStart->equalZero())
396cdf0e10cSrcweir                     mnUsedEntries--;
397cdf0e10cSrcweir             }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir             // remove point data
400cdf0e10cSrcweir             maVector.erase(aDeleteStart, aDeleteEnd);
401cdf0e10cSrcweir         }
402cdf0e10cSrcweir     }
403cdf0e10cSrcweir 
flip()404cdf0e10cSrcweir     void flip()
405cdf0e10cSrcweir     {
406cdf0e10cSrcweir         if(maVector.size() > 1)
407cdf0e10cSrcweir         {
408cdf0e10cSrcweir             const sal_uInt32 nHalfSize(maVector.size() >> 1L);
409cdf0e10cSrcweir             BColorDataVector::iterator aStart(maVector.begin());
410cdf0e10cSrcweir             BColorDataVector::iterator aEnd(maVector.end() - 1L);
411cdf0e10cSrcweir 
412cdf0e10cSrcweir             for(sal_uInt32 a(0); a < nHalfSize; a++)
413cdf0e10cSrcweir             {
414cdf0e10cSrcweir                 ::std::swap(*aStart, *aEnd);
415cdf0e10cSrcweir                 aStart++;
416cdf0e10cSrcweir                 aEnd--;
417cdf0e10cSrcweir             }
418cdf0e10cSrcweir         }
419cdf0e10cSrcweir     }
420cdf0e10cSrcweir };
421cdf0e10cSrcweir 
422cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
423cdf0e10cSrcweir 
424cdf0e10cSrcweir class NormalsArray3D
425cdf0e10cSrcweir {
426cdf0e10cSrcweir     typedef ::std::vector< ::basegfx::B3DVector > NormalsData3DVector;
427cdf0e10cSrcweir 
428cdf0e10cSrcweir     NormalsData3DVector                                 maVector;
429cdf0e10cSrcweir     sal_uInt32                                          mnUsedEntries;
430cdf0e10cSrcweir 
431cdf0e10cSrcweir public:
NormalsArray3D(sal_uInt32 nCount)432cdf0e10cSrcweir     explicit NormalsArray3D(sal_uInt32 nCount)
433cdf0e10cSrcweir     :   maVector(nCount),
434cdf0e10cSrcweir         mnUsedEntries(0L)
435cdf0e10cSrcweir     {
436cdf0e10cSrcweir     }
437cdf0e10cSrcweir 
NormalsArray3D(const NormalsArray3D & rOriginal)438cdf0e10cSrcweir     explicit NormalsArray3D(const NormalsArray3D& rOriginal)
439cdf0e10cSrcweir     :   maVector(rOriginal.maVector),
440cdf0e10cSrcweir         mnUsedEntries(rOriginal.mnUsedEntries)
441cdf0e10cSrcweir     {
442cdf0e10cSrcweir     }
443cdf0e10cSrcweir 
NormalsArray3D(const NormalsArray3D & rOriginal,sal_uInt32 nIndex,sal_uInt32 nCount)444cdf0e10cSrcweir     NormalsArray3D(const NormalsArray3D& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount)
445cdf0e10cSrcweir     :   maVector(),
446cdf0e10cSrcweir         mnUsedEntries(0L)
447cdf0e10cSrcweir     {
448cdf0e10cSrcweir         NormalsData3DVector::const_iterator aStart(rOriginal.maVector.begin());
449cdf0e10cSrcweir         aStart += nIndex;
450cdf0e10cSrcweir         NormalsData3DVector::const_iterator aEnd(aStart);
451cdf0e10cSrcweir         aEnd += nCount;
452cdf0e10cSrcweir         maVector.reserve(nCount);
453cdf0e10cSrcweir 
454cdf0e10cSrcweir         for(; aStart != aEnd; aStart++)
455cdf0e10cSrcweir         {
456cdf0e10cSrcweir             if(!aStart->equalZero())
457cdf0e10cSrcweir                 mnUsedEntries++;
458cdf0e10cSrcweir 
459cdf0e10cSrcweir             maVector.push_back(*aStart);
460cdf0e10cSrcweir         }
461cdf0e10cSrcweir     }
462cdf0e10cSrcweir 
~NormalsArray3D()463cdf0e10cSrcweir     ~NormalsArray3D()
464cdf0e10cSrcweir     {
465cdf0e10cSrcweir     }
466cdf0e10cSrcweir 
count() const467cdf0e10cSrcweir     sal_uInt32 count() const
468cdf0e10cSrcweir     {
469cdf0e10cSrcweir         return maVector.size();
470cdf0e10cSrcweir     }
471cdf0e10cSrcweir 
operator ==(const NormalsArray3D & rCandidate) const472cdf0e10cSrcweir     bool operator==(const NormalsArray3D& rCandidate) const
473cdf0e10cSrcweir     {
474cdf0e10cSrcweir         return (maVector == rCandidate.maVector);
475cdf0e10cSrcweir     }
476cdf0e10cSrcweir 
isUsed() const477cdf0e10cSrcweir     bool isUsed() const
478cdf0e10cSrcweir     {
479cdf0e10cSrcweir         return (0L != mnUsedEntries);
480cdf0e10cSrcweir     }
481cdf0e10cSrcweir 
getNormal(sal_uInt32 nIndex) const482cdf0e10cSrcweir     const ::basegfx::B3DVector& getNormal(sal_uInt32 nIndex) const
483cdf0e10cSrcweir     {
484cdf0e10cSrcweir         return maVector[nIndex];
485cdf0e10cSrcweir     }
486cdf0e10cSrcweir 
setNormal(sal_uInt32 nIndex,const::basegfx::B3DVector & rValue)487cdf0e10cSrcweir     void setNormal(sal_uInt32 nIndex, const ::basegfx::B3DVector& rValue)
488cdf0e10cSrcweir     {
489cdf0e10cSrcweir         bool bWasUsed(mnUsedEntries && !maVector[nIndex].equalZero());
490cdf0e10cSrcweir         bool bIsUsed(!rValue.equalZero());
491cdf0e10cSrcweir 
492cdf0e10cSrcweir         if(bWasUsed)
493cdf0e10cSrcweir         {
494cdf0e10cSrcweir             if(bIsUsed)
495cdf0e10cSrcweir             {
496cdf0e10cSrcweir                 maVector[nIndex] = rValue;
497cdf0e10cSrcweir             }
498cdf0e10cSrcweir             else
499cdf0e10cSrcweir             {
500cdf0e10cSrcweir                 maVector[nIndex] = ::basegfx::B3DVector::getEmptyVector();
501cdf0e10cSrcweir                 mnUsedEntries--;
502cdf0e10cSrcweir             }
503cdf0e10cSrcweir         }
504cdf0e10cSrcweir         else
505cdf0e10cSrcweir         {
506cdf0e10cSrcweir             if(bIsUsed)
507cdf0e10cSrcweir             {
508cdf0e10cSrcweir                 maVector[nIndex] = rValue;
509cdf0e10cSrcweir                 mnUsedEntries++;
510cdf0e10cSrcweir             }
511cdf0e10cSrcweir         }
512cdf0e10cSrcweir     }
513cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const::basegfx::B3DVector & rValue,sal_uInt32 nCount)514cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const ::basegfx::B3DVector& rValue, sal_uInt32 nCount)
515cdf0e10cSrcweir     {
516cdf0e10cSrcweir         if(nCount)
517cdf0e10cSrcweir         {
518cdf0e10cSrcweir             // add nCount copies of rValue
519cdf0e10cSrcweir             NormalsData3DVector::iterator aIndex(maVector.begin());
520cdf0e10cSrcweir             aIndex += nIndex;
521cdf0e10cSrcweir             maVector.insert(aIndex, nCount, rValue);
522cdf0e10cSrcweir 
523cdf0e10cSrcweir             if(!rValue.equalZero())
524cdf0e10cSrcweir                 mnUsedEntries += nCount;
525cdf0e10cSrcweir         }
526cdf0e10cSrcweir     }
527cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const NormalsArray3D & rSource)528cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const NormalsArray3D& rSource)
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir         const sal_uInt32 nCount(rSource.maVector.size());
531cdf0e10cSrcweir 
532cdf0e10cSrcweir         if(nCount)
533cdf0e10cSrcweir         {
534cdf0e10cSrcweir             // insert data
535cdf0e10cSrcweir             NormalsData3DVector::iterator aIndex(maVector.begin());
536cdf0e10cSrcweir             aIndex += nIndex;
537cdf0e10cSrcweir             NormalsData3DVector::const_iterator aStart(rSource.maVector.begin());
538cdf0e10cSrcweir             NormalsData3DVector::const_iterator aEnd(rSource.maVector.end());
539cdf0e10cSrcweir             maVector.insert(aIndex, aStart, aEnd);
540cdf0e10cSrcweir 
541cdf0e10cSrcweir             for(; aStart != aEnd; aStart++)
542cdf0e10cSrcweir             {
543cdf0e10cSrcweir                 if(!aStart->equalZero())
544cdf0e10cSrcweir                     mnUsedEntries++;
545cdf0e10cSrcweir             }
546cdf0e10cSrcweir         }
547cdf0e10cSrcweir     }
548cdf0e10cSrcweir 
remove(sal_uInt32 nIndex,sal_uInt32 nCount)549cdf0e10cSrcweir     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
550cdf0e10cSrcweir     {
551cdf0e10cSrcweir         if(nCount)
552cdf0e10cSrcweir         {
553cdf0e10cSrcweir             const NormalsData3DVector::iterator aDeleteStart(maVector.begin() + nIndex);
554cdf0e10cSrcweir             const NormalsData3DVector::iterator aDeleteEnd(aDeleteStart + nCount);
555cdf0e10cSrcweir             NormalsData3DVector::const_iterator aStart(aDeleteStart);
556cdf0e10cSrcweir 
557cdf0e10cSrcweir             for(; mnUsedEntries && aStart != aDeleteEnd; aStart++)
558cdf0e10cSrcweir             {
559cdf0e10cSrcweir                 if(!aStart->equalZero())
560cdf0e10cSrcweir                     mnUsedEntries--;
561cdf0e10cSrcweir             }
562cdf0e10cSrcweir 
563cdf0e10cSrcweir             // remove point data
564cdf0e10cSrcweir             maVector.erase(aDeleteStart, aDeleteEnd);
565cdf0e10cSrcweir         }
566cdf0e10cSrcweir     }
567cdf0e10cSrcweir 
flip()568cdf0e10cSrcweir     void flip()
569cdf0e10cSrcweir     {
570cdf0e10cSrcweir         if(maVector.size() > 1)
571cdf0e10cSrcweir         {
572cdf0e10cSrcweir             const sal_uInt32 nHalfSize(maVector.size() >> 1L);
573cdf0e10cSrcweir             NormalsData3DVector::iterator aStart(maVector.begin());
574cdf0e10cSrcweir             NormalsData3DVector::iterator aEnd(maVector.end() - 1L);
575cdf0e10cSrcweir 
576cdf0e10cSrcweir             for(sal_uInt32 a(0); a < nHalfSize; a++)
577cdf0e10cSrcweir             {
578cdf0e10cSrcweir                 ::std::swap(*aStart, *aEnd);
579cdf0e10cSrcweir                 aStart++;
580cdf0e10cSrcweir                 aEnd--;
581cdf0e10cSrcweir             }
582cdf0e10cSrcweir         }
583cdf0e10cSrcweir     }
584cdf0e10cSrcweir 
transform(const basegfx::B3DHomMatrix & rMatrix)585cdf0e10cSrcweir     void transform(const basegfx::B3DHomMatrix& rMatrix)
586cdf0e10cSrcweir     {
587cdf0e10cSrcweir         NormalsData3DVector::iterator aStart(maVector.begin());
588cdf0e10cSrcweir         NormalsData3DVector::iterator aEnd(maVector.end());
589cdf0e10cSrcweir 
590cdf0e10cSrcweir         for(; aStart != aEnd; aStart++)
591cdf0e10cSrcweir         {
592cdf0e10cSrcweir             (*aStart) *= rMatrix;
593cdf0e10cSrcweir         }
594cdf0e10cSrcweir     }
595cdf0e10cSrcweir };
596cdf0e10cSrcweir 
597cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
598cdf0e10cSrcweir 
599cdf0e10cSrcweir class TextureCoordinate2D
600cdf0e10cSrcweir {
601cdf0e10cSrcweir     typedef ::std::vector< ::basegfx::B2DPoint > TextureData2DVector;
602cdf0e10cSrcweir 
603cdf0e10cSrcweir     TextureData2DVector                                 maVector;
604cdf0e10cSrcweir     sal_uInt32                                          mnUsedEntries;
605cdf0e10cSrcweir 
606cdf0e10cSrcweir public:
TextureCoordinate2D(sal_uInt32 nCount)607cdf0e10cSrcweir     explicit TextureCoordinate2D(sal_uInt32 nCount)
608cdf0e10cSrcweir     :   maVector(nCount),
609cdf0e10cSrcweir         mnUsedEntries(0L)
610cdf0e10cSrcweir     {
611cdf0e10cSrcweir     }
612cdf0e10cSrcweir 
TextureCoordinate2D(const TextureCoordinate2D & rOriginal)613cdf0e10cSrcweir     explicit TextureCoordinate2D(const TextureCoordinate2D& rOriginal)
614cdf0e10cSrcweir     :   maVector(rOriginal.maVector),
615cdf0e10cSrcweir         mnUsedEntries(rOriginal.mnUsedEntries)
616cdf0e10cSrcweir     {
617cdf0e10cSrcweir     }
618cdf0e10cSrcweir 
TextureCoordinate2D(const TextureCoordinate2D & rOriginal,sal_uInt32 nIndex,sal_uInt32 nCount)619cdf0e10cSrcweir     TextureCoordinate2D(const TextureCoordinate2D& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount)
620cdf0e10cSrcweir     :   maVector(),
621cdf0e10cSrcweir         mnUsedEntries(0L)
622cdf0e10cSrcweir     {
623cdf0e10cSrcweir         TextureData2DVector::const_iterator aStart(rOriginal.maVector.begin());
624cdf0e10cSrcweir         aStart += nIndex;
625cdf0e10cSrcweir         TextureData2DVector::const_iterator aEnd(aStart);
626cdf0e10cSrcweir         aEnd += nCount;
627cdf0e10cSrcweir         maVector.reserve(nCount);
628cdf0e10cSrcweir 
629cdf0e10cSrcweir         for(; aStart != aEnd; aStart++)
630cdf0e10cSrcweir         {
631cdf0e10cSrcweir             if(!aStart->equalZero())
632cdf0e10cSrcweir                 mnUsedEntries++;
633cdf0e10cSrcweir 
634cdf0e10cSrcweir             maVector.push_back(*aStart);
635cdf0e10cSrcweir         }
636cdf0e10cSrcweir     }
637cdf0e10cSrcweir 
~TextureCoordinate2D()638cdf0e10cSrcweir     ~TextureCoordinate2D()
639cdf0e10cSrcweir     {
640cdf0e10cSrcweir     }
641cdf0e10cSrcweir 
count() const642cdf0e10cSrcweir     sal_uInt32 count() const
643cdf0e10cSrcweir     {
644cdf0e10cSrcweir         return maVector.size();
645cdf0e10cSrcweir     }
646cdf0e10cSrcweir 
operator ==(const TextureCoordinate2D & rCandidate) const647cdf0e10cSrcweir     bool operator==(const TextureCoordinate2D& rCandidate) const
648cdf0e10cSrcweir     {
649cdf0e10cSrcweir         return (maVector == rCandidate.maVector);
650cdf0e10cSrcweir     }
651cdf0e10cSrcweir 
isUsed() const652cdf0e10cSrcweir     bool isUsed() const
653cdf0e10cSrcweir     {
654cdf0e10cSrcweir         return (0L != mnUsedEntries);
655cdf0e10cSrcweir     }
656cdf0e10cSrcweir 
getTextureCoordinate(sal_uInt32 nIndex) const657cdf0e10cSrcweir     const ::basegfx::B2DPoint& getTextureCoordinate(sal_uInt32 nIndex) const
658cdf0e10cSrcweir     {
659cdf0e10cSrcweir         return maVector[nIndex];
660cdf0e10cSrcweir     }
661cdf0e10cSrcweir 
setTextureCoordinate(sal_uInt32 nIndex,const::basegfx::B2DPoint & rValue)662cdf0e10cSrcweir     void setTextureCoordinate(sal_uInt32 nIndex, const ::basegfx::B2DPoint& rValue)
663cdf0e10cSrcweir     {
664cdf0e10cSrcweir         bool bWasUsed(mnUsedEntries && !maVector[nIndex].equalZero());
665cdf0e10cSrcweir         bool bIsUsed(!rValue.equalZero());
666cdf0e10cSrcweir 
667cdf0e10cSrcweir         if(bWasUsed)
668cdf0e10cSrcweir         {
669cdf0e10cSrcweir             if(bIsUsed)
670cdf0e10cSrcweir             {
671cdf0e10cSrcweir                 maVector[nIndex] = rValue;
672cdf0e10cSrcweir             }
673cdf0e10cSrcweir             else
674cdf0e10cSrcweir             {
675cdf0e10cSrcweir                 maVector[nIndex] = ::basegfx::B2DPoint::getEmptyPoint();
676cdf0e10cSrcweir                 mnUsedEntries--;
677cdf0e10cSrcweir             }
678cdf0e10cSrcweir         }
679cdf0e10cSrcweir         else
680cdf0e10cSrcweir         {
681cdf0e10cSrcweir             if(bIsUsed)
682cdf0e10cSrcweir             {
683cdf0e10cSrcweir                 maVector[nIndex] = rValue;
684cdf0e10cSrcweir                 mnUsedEntries++;
685cdf0e10cSrcweir             }
686cdf0e10cSrcweir         }
687cdf0e10cSrcweir     }
688cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const::basegfx::B2DPoint & rValue,sal_uInt32 nCount)689cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const ::basegfx::B2DPoint& rValue, sal_uInt32 nCount)
690cdf0e10cSrcweir     {
691cdf0e10cSrcweir         if(nCount)
692cdf0e10cSrcweir         {
693cdf0e10cSrcweir             // add nCount copies of rValue
694cdf0e10cSrcweir             TextureData2DVector::iterator aIndex(maVector.begin());
695cdf0e10cSrcweir             aIndex += nIndex;
696cdf0e10cSrcweir             maVector.insert(aIndex, nCount, rValue);
697cdf0e10cSrcweir 
698cdf0e10cSrcweir             if(!rValue.equalZero())
699cdf0e10cSrcweir                 mnUsedEntries += nCount;
700cdf0e10cSrcweir         }
701cdf0e10cSrcweir     }
702cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const TextureCoordinate2D & rSource)703cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const TextureCoordinate2D& rSource)
704cdf0e10cSrcweir     {
705cdf0e10cSrcweir         const sal_uInt32 nCount(rSource.maVector.size());
706cdf0e10cSrcweir 
707cdf0e10cSrcweir         if(nCount)
708cdf0e10cSrcweir         {
709cdf0e10cSrcweir             // insert data
710cdf0e10cSrcweir             TextureData2DVector::iterator aIndex(maVector.begin());
711cdf0e10cSrcweir             aIndex += nIndex;
712cdf0e10cSrcweir             TextureData2DVector::const_iterator aStart(rSource.maVector.begin());
713cdf0e10cSrcweir             TextureData2DVector::const_iterator aEnd(rSource.maVector.end());
714cdf0e10cSrcweir             maVector.insert(aIndex, aStart, aEnd);
715cdf0e10cSrcweir 
716cdf0e10cSrcweir             for(; aStart != aEnd; aStart++)
717cdf0e10cSrcweir             {
718cdf0e10cSrcweir                 if(!aStart->equalZero())
719cdf0e10cSrcweir                     mnUsedEntries++;
720cdf0e10cSrcweir             }
721cdf0e10cSrcweir         }
722cdf0e10cSrcweir     }
723cdf0e10cSrcweir 
remove(sal_uInt32 nIndex,sal_uInt32 nCount)724cdf0e10cSrcweir     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
725cdf0e10cSrcweir     {
726cdf0e10cSrcweir         if(nCount)
727cdf0e10cSrcweir         {
728cdf0e10cSrcweir             const TextureData2DVector::iterator aDeleteStart(maVector.begin() + nIndex);
729cdf0e10cSrcweir             const TextureData2DVector::iterator aDeleteEnd(aDeleteStart + nCount);
730cdf0e10cSrcweir             TextureData2DVector::const_iterator aStart(aDeleteStart);
731cdf0e10cSrcweir 
732cdf0e10cSrcweir             for(; mnUsedEntries && aStart != aDeleteEnd; aStart++)
733cdf0e10cSrcweir             {
734cdf0e10cSrcweir                 if(!aStart->equalZero())
735cdf0e10cSrcweir                     mnUsedEntries--;
736cdf0e10cSrcweir             }
737cdf0e10cSrcweir 
738cdf0e10cSrcweir             // remove point data
739cdf0e10cSrcweir             maVector.erase(aDeleteStart, aDeleteEnd);
740cdf0e10cSrcweir         }
741cdf0e10cSrcweir     }
742cdf0e10cSrcweir 
flip()743cdf0e10cSrcweir     void flip()
744cdf0e10cSrcweir     {
745cdf0e10cSrcweir         if(maVector.size() > 1)
746cdf0e10cSrcweir         {
747cdf0e10cSrcweir             const sal_uInt32 nHalfSize(maVector.size() >> 1L);
748cdf0e10cSrcweir             TextureData2DVector::iterator aStart(maVector.begin());
749cdf0e10cSrcweir             TextureData2DVector::iterator aEnd(maVector.end() - 1L);
750cdf0e10cSrcweir 
751cdf0e10cSrcweir             for(sal_uInt32 a(0); a < nHalfSize; a++)
752cdf0e10cSrcweir             {
753cdf0e10cSrcweir                 ::std::swap(*aStart, *aEnd);
754cdf0e10cSrcweir                 aStart++;
755cdf0e10cSrcweir                 aEnd--;
756cdf0e10cSrcweir             }
757cdf0e10cSrcweir         }
758cdf0e10cSrcweir     }
759cdf0e10cSrcweir 
transform(const::basegfx::B2DHomMatrix & rMatrix)760cdf0e10cSrcweir     void transform(const ::basegfx::B2DHomMatrix& rMatrix)
761cdf0e10cSrcweir     {
762cdf0e10cSrcweir         TextureData2DVector::iterator aStart(maVector.begin());
763cdf0e10cSrcweir         TextureData2DVector::iterator aEnd(maVector.end());
764cdf0e10cSrcweir 
765cdf0e10cSrcweir         for(; aStart != aEnd; aStart++)
766cdf0e10cSrcweir         {
767cdf0e10cSrcweir             (*aStart) *= rMatrix;
768cdf0e10cSrcweir         }
769cdf0e10cSrcweir     }
770cdf0e10cSrcweir };
771cdf0e10cSrcweir 
772cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
773cdf0e10cSrcweir 
774cdf0e10cSrcweir class ImplB3DPolygon
775cdf0e10cSrcweir {
776cdf0e10cSrcweir     // The point vector. This vector exists always and defines the
777cdf0e10cSrcweir     // count of members.
778cdf0e10cSrcweir     CoordinateDataArray3D                           maPoints;
779cdf0e10cSrcweir 
780cdf0e10cSrcweir     // The BColor vector. This vectors are created on demand
781cdf0e10cSrcweir     // and may be zero.
782cdf0e10cSrcweir     BColorArray*                                    mpBColors;
783cdf0e10cSrcweir 
784cdf0e10cSrcweir     // The Normals vector. This vectors are created on demand
785cdf0e10cSrcweir     // and may be zero.
786cdf0e10cSrcweir     NormalsArray3D*                                 mpNormals;
787cdf0e10cSrcweir 
788cdf0e10cSrcweir     // The TextureCoordinates vector. This vectors are created on demand
789cdf0e10cSrcweir     // and may be zero.
790cdf0e10cSrcweir     TextureCoordinate2D*                            mpTextureCoordiantes;
791cdf0e10cSrcweir 
792cdf0e10cSrcweir     // The calculated plane normal. mbPlaneNormalValid says if it's valid.
793cdf0e10cSrcweir     ::basegfx::B3DVector                            maPlaneNormal;
794cdf0e10cSrcweir 
795cdf0e10cSrcweir     // bitfield
796cdf0e10cSrcweir     // flag which decides if this polygon is opened or closed
797cdf0e10cSrcweir     unsigned                                        mbIsClosed : 1;
798cdf0e10cSrcweir 
799cdf0e10cSrcweir     // flag which says if maPlaneNormal is up-to-date
800cdf0e10cSrcweir     unsigned                                        mbPlaneNormalValid : 1;
801cdf0e10cSrcweir 
802cdf0e10cSrcweir protected:
invalidatePlaneNormal()803cdf0e10cSrcweir     void invalidatePlaneNormal()
804cdf0e10cSrcweir     {
805cdf0e10cSrcweir         if(mbPlaneNormalValid)
806cdf0e10cSrcweir         {
807cdf0e10cSrcweir             mbPlaneNormalValid = false;
808cdf0e10cSrcweir         }
809cdf0e10cSrcweir     }
810cdf0e10cSrcweir 
811cdf0e10cSrcweir public:
812cdf0e10cSrcweir     // This constructor is only used from the static identity polygon, thus
813cdf0e10cSrcweir     // the RefCount is set to 1 to never 'delete' this static incarnation.
ImplB3DPolygon()814cdf0e10cSrcweir     ImplB3DPolygon()
815cdf0e10cSrcweir     :   maPoints(0L),
816cdf0e10cSrcweir         mpBColors(0L),
817cdf0e10cSrcweir         mpNormals(0L),
818cdf0e10cSrcweir         mpTextureCoordiantes(0L),
819cdf0e10cSrcweir         maPlaneNormal(::basegfx::B3DVector::getEmptyVector()),
820cdf0e10cSrcweir         mbIsClosed(false),
821cdf0e10cSrcweir         mbPlaneNormalValid(true)
822cdf0e10cSrcweir     {
823cdf0e10cSrcweir         // complete initialization with defaults
824cdf0e10cSrcweir     }
825cdf0e10cSrcweir 
ImplB3DPolygon(const ImplB3DPolygon & rToBeCopied)826cdf0e10cSrcweir     ImplB3DPolygon(const ImplB3DPolygon& rToBeCopied)
827cdf0e10cSrcweir     :   maPoints(rToBeCopied.maPoints),
828cdf0e10cSrcweir         mpBColors(0L),
829cdf0e10cSrcweir         mpNormals(0L),
830cdf0e10cSrcweir         mpTextureCoordiantes(0L),
831cdf0e10cSrcweir         maPlaneNormal(rToBeCopied.maPlaneNormal),
832cdf0e10cSrcweir         mbIsClosed(rToBeCopied.mbIsClosed),
833cdf0e10cSrcweir         mbPlaneNormalValid(rToBeCopied.mbPlaneNormalValid)
834cdf0e10cSrcweir     {
835cdf0e10cSrcweir         // complete initialization using copy
836cdf0e10cSrcweir         if(rToBeCopied.mpBColors && rToBeCopied.mpBColors->isUsed())
837cdf0e10cSrcweir         {
838cdf0e10cSrcweir             mpBColors = new BColorArray(*rToBeCopied.mpBColors);
839cdf0e10cSrcweir         }
840cdf0e10cSrcweir 
841cdf0e10cSrcweir         if(rToBeCopied.mpNormals && rToBeCopied.mpNormals->isUsed())
842cdf0e10cSrcweir         {
843cdf0e10cSrcweir             mpNormals = new NormalsArray3D(*rToBeCopied.mpNormals);
844cdf0e10cSrcweir         }
845cdf0e10cSrcweir 
846cdf0e10cSrcweir         if(rToBeCopied.mpTextureCoordiantes && rToBeCopied.mpTextureCoordiantes->isUsed())
847cdf0e10cSrcweir         {
848cdf0e10cSrcweir             mpTextureCoordiantes = new TextureCoordinate2D(*rToBeCopied.mpTextureCoordiantes);
849cdf0e10cSrcweir         }
850cdf0e10cSrcweir     }
851cdf0e10cSrcweir 
ImplB3DPolygon(const ImplB3DPolygon & rToBeCopied,sal_uInt32 nIndex,sal_uInt32 nCount)852cdf0e10cSrcweir     ImplB3DPolygon(const ImplB3DPolygon& rToBeCopied, sal_uInt32 nIndex, sal_uInt32 nCount)
853cdf0e10cSrcweir     :   maPoints(rToBeCopied.maPoints, nIndex, nCount),
854cdf0e10cSrcweir         mpBColors(0L),
855cdf0e10cSrcweir         mpNormals(0L),
856cdf0e10cSrcweir         mpTextureCoordiantes(0L),
857cdf0e10cSrcweir         maPlaneNormal(::basegfx::B3DVector::getEmptyVector()),
858cdf0e10cSrcweir         mbIsClosed(rToBeCopied.mbIsClosed),
859cdf0e10cSrcweir         mbPlaneNormalValid(false)
860cdf0e10cSrcweir     {
861cdf0e10cSrcweir         // complete initialization using partly copy
862cdf0e10cSrcweir         if(rToBeCopied.mpBColors && rToBeCopied.mpBColors->isUsed())
863cdf0e10cSrcweir         {
864cdf0e10cSrcweir             mpBColors = new BColorArray(*rToBeCopied.mpBColors, nIndex, nCount);
865cdf0e10cSrcweir 
866cdf0e10cSrcweir             if(!mpBColors->isUsed())
867cdf0e10cSrcweir             {
868cdf0e10cSrcweir                 delete mpBColors;
869cdf0e10cSrcweir                 mpBColors = 0L;
870cdf0e10cSrcweir             }
871cdf0e10cSrcweir         }
872cdf0e10cSrcweir 
873cdf0e10cSrcweir         if(rToBeCopied.mpNormals && rToBeCopied.mpNormals->isUsed())
874cdf0e10cSrcweir         {
875cdf0e10cSrcweir             mpNormals = new NormalsArray3D(*rToBeCopied.mpNormals, nIndex, nCount);
876cdf0e10cSrcweir 
877cdf0e10cSrcweir             if(!mpNormals->isUsed())
878cdf0e10cSrcweir             {
879cdf0e10cSrcweir                 delete mpNormals;
880cdf0e10cSrcweir                 mpNormals = 0L;
881cdf0e10cSrcweir             }
882cdf0e10cSrcweir         }
883cdf0e10cSrcweir 
884cdf0e10cSrcweir         if(rToBeCopied.mpTextureCoordiantes && rToBeCopied.mpTextureCoordiantes->isUsed())
885cdf0e10cSrcweir         {
886cdf0e10cSrcweir             mpTextureCoordiantes = new TextureCoordinate2D(*rToBeCopied.mpTextureCoordiantes, nIndex, nCount);
887cdf0e10cSrcweir 
888cdf0e10cSrcweir             if(!mpTextureCoordiantes->isUsed())
889cdf0e10cSrcweir             {
890cdf0e10cSrcweir                 delete mpTextureCoordiantes;
891cdf0e10cSrcweir                 mpTextureCoordiantes = 0L;
892cdf0e10cSrcweir             }
893cdf0e10cSrcweir         }
894cdf0e10cSrcweir     }
895cdf0e10cSrcweir 
~ImplB3DPolygon()896cdf0e10cSrcweir     ~ImplB3DPolygon()
897cdf0e10cSrcweir     {
898cdf0e10cSrcweir         if(mpBColors)
899cdf0e10cSrcweir         {
900cdf0e10cSrcweir             delete mpBColors;
901cdf0e10cSrcweir             mpBColors = 0L;
902cdf0e10cSrcweir         }
903cdf0e10cSrcweir 
904cdf0e10cSrcweir         if(mpNormals)
905cdf0e10cSrcweir         {
906cdf0e10cSrcweir             delete mpNormals;
907cdf0e10cSrcweir             mpNormals = 0L;
908cdf0e10cSrcweir         }
909cdf0e10cSrcweir 
910cdf0e10cSrcweir         if(mpTextureCoordiantes)
911cdf0e10cSrcweir         {
912cdf0e10cSrcweir             delete mpTextureCoordiantes;
913cdf0e10cSrcweir             mpTextureCoordiantes = 0L;
914cdf0e10cSrcweir         }
915cdf0e10cSrcweir     }
916cdf0e10cSrcweir 
count() const917cdf0e10cSrcweir     sal_uInt32 count() const
918cdf0e10cSrcweir     {
919cdf0e10cSrcweir         return maPoints.count();
920cdf0e10cSrcweir     }
921cdf0e10cSrcweir 
isClosed() const922cdf0e10cSrcweir     bool isClosed() const
923cdf0e10cSrcweir     {
924cdf0e10cSrcweir         return mbIsClosed;
925cdf0e10cSrcweir     }
926cdf0e10cSrcweir 
setClosed(bool bNew)927cdf0e10cSrcweir     void setClosed(bool bNew)
928cdf0e10cSrcweir     {
929cdf0e10cSrcweir         if(bNew != (bool)mbIsClosed)
930cdf0e10cSrcweir         {
931cdf0e10cSrcweir             mbIsClosed = bNew;
932cdf0e10cSrcweir         }
933cdf0e10cSrcweir     }
934cdf0e10cSrcweir 
impBColorsAreEqual(const ImplB3DPolygon & rCandidate) const935cdf0e10cSrcweir     inline bool impBColorsAreEqual(const ImplB3DPolygon& rCandidate) const
936cdf0e10cSrcweir     {
937cdf0e10cSrcweir         bool bBColorsAreEqual(true);
938cdf0e10cSrcweir 
939cdf0e10cSrcweir         if(mpBColors)
940cdf0e10cSrcweir         {
941cdf0e10cSrcweir             if(rCandidate.mpBColors)
942cdf0e10cSrcweir             {
943cdf0e10cSrcweir                 bBColorsAreEqual = (*mpBColors == *rCandidate.mpBColors);
944cdf0e10cSrcweir             }
945cdf0e10cSrcweir             else
946cdf0e10cSrcweir             {
947cdf0e10cSrcweir                 // candidate has no BColors, so it's assumed all unused.
948cdf0e10cSrcweir                 bBColorsAreEqual = !mpBColors->isUsed();
949cdf0e10cSrcweir             }
950cdf0e10cSrcweir         }
951cdf0e10cSrcweir         else
952cdf0e10cSrcweir         {
953cdf0e10cSrcweir             if(rCandidate.mpBColors)
954cdf0e10cSrcweir             {
955cdf0e10cSrcweir                 // we have no TextureCoordiantes, so it's assumed all unused.
956cdf0e10cSrcweir                 bBColorsAreEqual = !rCandidate.mpBColors->isUsed();
957cdf0e10cSrcweir             }
958cdf0e10cSrcweir         }
959cdf0e10cSrcweir 
960cdf0e10cSrcweir         return bBColorsAreEqual;
961cdf0e10cSrcweir     }
962cdf0e10cSrcweir 
impNormalsAreEqual(const ImplB3DPolygon & rCandidate) const963cdf0e10cSrcweir     inline bool impNormalsAreEqual(const ImplB3DPolygon& rCandidate) const
964cdf0e10cSrcweir     {
965cdf0e10cSrcweir         bool bNormalsAreEqual(true);
966cdf0e10cSrcweir 
967cdf0e10cSrcweir         if(mpNormals)
968cdf0e10cSrcweir         {
969cdf0e10cSrcweir             if(rCandidate.mpNormals)
970cdf0e10cSrcweir             {
971cdf0e10cSrcweir                 bNormalsAreEqual = (*mpNormals == *rCandidate.mpNormals);
972cdf0e10cSrcweir             }
973cdf0e10cSrcweir             else
974cdf0e10cSrcweir             {
975cdf0e10cSrcweir                 // candidate has no normals, so it's assumed all unused.
976cdf0e10cSrcweir                 bNormalsAreEqual = !mpNormals->isUsed();
977cdf0e10cSrcweir             }
978cdf0e10cSrcweir         }
979cdf0e10cSrcweir         else
980cdf0e10cSrcweir         {
981cdf0e10cSrcweir             if(rCandidate.mpNormals)
982cdf0e10cSrcweir             {
983cdf0e10cSrcweir                 // we have no normals, so it's assumed all unused.
984cdf0e10cSrcweir                 bNormalsAreEqual = !rCandidate.mpNormals->isUsed();
985cdf0e10cSrcweir             }
986cdf0e10cSrcweir         }
987cdf0e10cSrcweir 
988cdf0e10cSrcweir         return bNormalsAreEqual;
989cdf0e10cSrcweir     }
990cdf0e10cSrcweir 
impTextureCoordinatesAreEqual(const ImplB3DPolygon & rCandidate) const991cdf0e10cSrcweir     inline bool impTextureCoordinatesAreEqual(const ImplB3DPolygon& rCandidate) const
992cdf0e10cSrcweir     {
993cdf0e10cSrcweir         bool bTextureCoordinatesAreEqual(true);
994cdf0e10cSrcweir 
995cdf0e10cSrcweir         if(mpTextureCoordiantes)
996cdf0e10cSrcweir         {
997cdf0e10cSrcweir             if(rCandidate.mpTextureCoordiantes)
998cdf0e10cSrcweir             {
999cdf0e10cSrcweir                 bTextureCoordinatesAreEqual = (*mpTextureCoordiantes == *rCandidate.mpTextureCoordiantes);
1000cdf0e10cSrcweir             }
1001cdf0e10cSrcweir             else
1002cdf0e10cSrcweir             {
1003cdf0e10cSrcweir                 // candidate has no TextureCoordinates, so it's assumed all unused.
1004cdf0e10cSrcweir                 bTextureCoordinatesAreEqual = !mpTextureCoordiantes->isUsed();
1005cdf0e10cSrcweir             }
1006cdf0e10cSrcweir         }
1007cdf0e10cSrcweir         else
1008cdf0e10cSrcweir         {
1009cdf0e10cSrcweir             if(rCandidate.mpTextureCoordiantes)
1010cdf0e10cSrcweir             {
1011cdf0e10cSrcweir                 // we have no TextureCoordiantes, so it's assumed all unused.
1012cdf0e10cSrcweir                 bTextureCoordinatesAreEqual = !rCandidate.mpTextureCoordiantes->isUsed();
1013cdf0e10cSrcweir             }
1014cdf0e10cSrcweir         }
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir         return bTextureCoordinatesAreEqual;
1017cdf0e10cSrcweir     }
1018cdf0e10cSrcweir 
operator ==(const ImplB3DPolygon & rCandidate) const1019cdf0e10cSrcweir     bool operator==(const ImplB3DPolygon& rCandidate) const
1020cdf0e10cSrcweir     {
1021cdf0e10cSrcweir         if(mbIsClosed == rCandidate.mbIsClosed)
1022cdf0e10cSrcweir         {
1023cdf0e10cSrcweir             if(maPoints == rCandidate.maPoints)
1024cdf0e10cSrcweir             {
1025cdf0e10cSrcweir                 if(impBColorsAreEqual(rCandidate))
1026cdf0e10cSrcweir                 {
1027cdf0e10cSrcweir                     if(impNormalsAreEqual(rCandidate))
1028cdf0e10cSrcweir                     {
1029cdf0e10cSrcweir                         if(impTextureCoordinatesAreEqual(rCandidate))
1030cdf0e10cSrcweir                         {
1031cdf0e10cSrcweir                             return true;
1032cdf0e10cSrcweir                         }
1033cdf0e10cSrcweir                     }
1034cdf0e10cSrcweir                 }
1035cdf0e10cSrcweir             }
1036cdf0e10cSrcweir         }
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir         return false;
1039cdf0e10cSrcweir     }
1040cdf0e10cSrcweir 
getPoint(sal_uInt32 nIndex) const1041cdf0e10cSrcweir     const ::basegfx::B3DPoint& getPoint(sal_uInt32 nIndex) const
1042cdf0e10cSrcweir     {
1043cdf0e10cSrcweir         return maPoints.getCoordinate(nIndex);
1044cdf0e10cSrcweir     }
1045cdf0e10cSrcweir 
setPoint(sal_uInt32 nIndex,const::basegfx::B3DPoint & rValue)1046cdf0e10cSrcweir     void setPoint(sal_uInt32 nIndex, const ::basegfx::B3DPoint& rValue)
1047cdf0e10cSrcweir     {
1048cdf0e10cSrcweir         maPoints.setCoordinate(nIndex, rValue);
1049cdf0e10cSrcweir         invalidatePlaneNormal();
1050cdf0e10cSrcweir     }
1051cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const::basegfx::B3DPoint & rPoint,sal_uInt32 nCount)1052cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const ::basegfx::B3DPoint& rPoint, sal_uInt32 nCount)
1053cdf0e10cSrcweir     {
1054cdf0e10cSrcweir         if(nCount)
1055cdf0e10cSrcweir         {
1056cdf0e10cSrcweir             CoordinateData3D aCoordinate(rPoint);
1057cdf0e10cSrcweir             maPoints.insert(nIndex, aCoordinate, nCount);
1058cdf0e10cSrcweir             invalidatePlaneNormal();
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir             if(mpBColors)
1061cdf0e10cSrcweir             {
1062cdf0e10cSrcweir                 mpBColors->insert(nIndex, ::basegfx::BColor::getEmptyBColor(), nCount);
1063cdf0e10cSrcweir             }
1064cdf0e10cSrcweir 
1065cdf0e10cSrcweir             if(mpNormals)
1066cdf0e10cSrcweir             {
1067cdf0e10cSrcweir                 mpNormals->insert(nIndex, ::basegfx::B3DVector::getEmptyVector(), nCount);
1068cdf0e10cSrcweir             }
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir             if(mpTextureCoordiantes)
1071cdf0e10cSrcweir             {
1072cdf0e10cSrcweir                 mpTextureCoordiantes->insert(nIndex, ::basegfx::B2DPoint::getEmptyPoint(), nCount);
1073cdf0e10cSrcweir             }
1074cdf0e10cSrcweir         }
1075cdf0e10cSrcweir     }
1076cdf0e10cSrcweir 
getBColor(sal_uInt32 nIndex) const1077cdf0e10cSrcweir     const ::basegfx::BColor& getBColor(sal_uInt32 nIndex) const
1078cdf0e10cSrcweir     {
1079cdf0e10cSrcweir         if(mpBColors)
1080cdf0e10cSrcweir         {
1081cdf0e10cSrcweir             return mpBColors->getBColor(nIndex);
1082cdf0e10cSrcweir         }
1083cdf0e10cSrcweir         else
1084cdf0e10cSrcweir         {
1085cdf0e10cSrcweir             return ::basegfx::BColor::getEmptyBColor();
1086cdf0e10cSrcweir         }
1087cdf0e10cSrcweir     }
1088cdf0e10cSrcweir 
setBColor(sal_uInt32 nIndex,const::basegfx::BColor & rValue)1089cdf0e10cSrcweir     void setBColor(sal_uInt32 nIndex, const ::basegfx::BColor& rValue)
1090cdf0e10cSrcweir     {
1091cdf0e10cSrcweir         if(!mpBColors)
1092cdf0e10cSrcweir         {
1093cdf0e10cSrcweir             if(!rValue.equalZero())
1094cdf0e10cSrcweir             {
1095cdf0e10cSrcweir                 mpBColors = new BColorArray(maPoints.count());
1096cdf0e10cSrcweir                 mpBColors->setBColor(nIndex, rValue);
1097cdf0e10cSrcweir             }
1098cdf0e10cSrcweir         }
1099cdf0e10cSrcweir         else
1100cdf0e10cSrcweir         {
1101cdf0e10cSrcweir             mpBColors->setBColor(nIndex, rValue);
1102cdf0e10cSrcweir 
1103cdf0e10cSrcweir             if(!mpBColors->isUsed())
1104cdf0e10cSrcweir             {
1105cdf0e10cSrcweir                 delete mpBColors;
1106cdf0e10cSrcweir                 mpBColors = 0L;
1107cdf0e10cSrcweir             }
1108cdf0e10cSrcweir         }
1109cdf0e10cSrcweir     }
1110cdf0e10cSrcweir 
areBColorsUsed() const1111cdf0e10cSrcweir     bool areBColorsUsed() const
1112cdf0e10cSrcweir     {
1113cdf0e10cSrcweir         return (mpBColors && mpBColors->isUsed());
1114cdf0e10cSrcweir     }
1115cdf0e10cSrcweir 
clearBColors()1116cdf0e10cSrcweir     void clearBColors()
1117cdf0e10cSrcweir     {
1118cdf0e10cSrcweir         if(mpBColors)
1119cdf0e10cSrcweir         {
1120cdf0e10cSrcweir             delete mpBColors;
1121cdf0e10cSrcweir             mpBColors = 0L;
1122cdf0e10cSrcweir         }
1123cdf0e10cSrcweir     }
1124cdf0e10cSrcweir 
getNormal() const1125cdf0e10cSrcweir     const ::basegfx::B3DVector& getNormal() const
1126cdf0e10cSrcweir     {
1127cdf0e10cSrcweir         if(!mbPlaneNormalValid)
1128cdf0e10cSrcweir         {
1129cdf0e10cSrcweir             const_cast< ImplB3DPolygon* >(this)->maPlaneNormal = maPoints.getNormal();
1130cdf0e10cSrcweir             const_cast< ImplB3DPolygon* >(this)->mbPlaneNormalValid = true;
1131cdf0e10cSrcweir         }
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir         return maPlaneNormal;
1134cdf0e10cSrcweir     }
1135cdf0e10cSrcweir 
getNormal(sal_uInt32 nIndex) const1136cdf0e10cSrcweir     const ::basegfx::B3DVector& getNormal(sal_uInt32 nIndex) const
1137cdf0e10cSrcweir     {
1138cdf0e10cSrcweir         if(mpNormals)
1139cdf0e10cSrcweir         {
1140cdf0e10cSrcweir             return mpNormals->getNormal(nIndex);
1141cdf0e10cSrcweir         }
1142cdf0e10cSrcweir         else
1143cdf0e10cSrcweir         {
1144cdf0e10cSrcweir             return ::basegfx::B3DVector::getEmptyVector();
1145cdf0e10cSrcweir         }
1146cdf0e10cSrcweir     }
1147cdf0e10cSrcweir 
setNormal(sal_uInt32 nIndex,const::basegfx::B3DVector & rValue)1148cdf0e10cSrcweir     void setNormal(sal_uInt32 nIndex, const ::basegfx::B3DVector& rValue)
1149cdf0e10cSrcweir     {
1150cdf0e10cSrcweir         if(!mpNormals)
1151cdf0e10cSrcweir         {
1152cdf0e10cSrcweir             if(!rValue.equalZero())
1153cdf0e10cSrcweir             {
1154cdf0e10cSrcweir                 mpNormals = new NormalsArray3D(maPoints.count());
1155cdf0e10cSrcweir                 mpNormals->setNormal(nIndex, rValue);
1156cdf0e10cSrcweir             }
1157cdf0e10cSrcweir         }
1158cdf0e10cSrcweir         else
1159cdf0e10cSrcweir         {
1160cdf0e10cSrcweir             mpNormals->setNormal(nIndex, rValue);
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir             if(!mpNormals->isUsed())
1163cdf0e10cSrcweir             {
1164cdf0e10cSrcweir                 delete mpNormals;
1165cdf0e10cSrcweir                 mpNormals = 0L;
1166cdf0e10cSrcweir             }
1167cdf0e10cSrcweir         }
1168cdf0e10cSrcweir     }
1169cdf0e10cSrcweir 
transformNormals(const::basegfx::B3DHomMatrix & rMatrix)1170cdf0e10cSrcweir     void transformNormals(const ::basegfx::B3DHomMatrix& rMatrix)
1171cdf0e10cSrcweir     {
1172cdf0e10cSrcweir         if(mpNormals)
1173cdf0e10cSrcweir         {
1174cdf0e10cSrcweir             mpNormals->transform(rMatrix);
1175cdf0e10cSrcweir         }
1176cdf0e10cSrcweir     }
1177cdf0e10cSrcweir 
areNormalsUsed() const1178cdf0e10cSrcweir     bool areNormalsUsed() const
1179cdf0e10cSrcweir     {
1180cdf0e10cSrcweir         return (mpNormals && mpNormals->isUsed());
1181cdf0e10cSrcweir     }
1182cdf0e10cSrcweir 
clearNormals()1183cdf0e10cSrcweir     void clearNormals()
1184cdf0e10cSrcweir     {
1185cdf0e10cSrcweir         if(mpNormals)
1186cdf0e10cSrcweir         {
1187cdf0e10cSrcweir             delete mpNormals;
1188cdf0e10cSrcweir             mpNormals = 0L;
1189cdf0e10cSrcweir         }
1190cdf0e10cSrcweir     }
1191cdf0e10cSrcweir 
getTextureCoordinate(sal_uInt32 nIndex) const1192cdf0e10cSrcweir     const ::basegfx::B2DPoint& getTextureCoordinate(sal_uInt32 nIndex) const
1193cdf0e10cSrcweir     {
1194cdf0e10cSrcweir         if(mpTextureCoordiantes)
1195cdf0e10cSrcweir         {
1196cdf0e10cSrcweir             return mpTextureCoordiantes->getTextureCoordinate(nIndex);
1197cdf0e10cSrcweir         }
1198cdf0e10cSrcweir         else
1199cdf0e10cSrcweir         {
1200cdf0e10cSrcweir             return ::basegfx::B2DPoint::getEmptyPoint();
1201cdf0e10cSrcweir         }
1202cdf0e10cSrcweir     }
1203cdf0e10cSrcweir 
setTextureCoordinate(sal_uInt32 nIndex,const::basegfx::B2DPoint & rValue)1204cdf0e10cSrcweir     void setTextureCoordinate(sal_uInt32 nIndex, const ::basegfx::B2DPoint& rValue)
1205cdf0e10cSrcweir     {
1206cdf0e10cSrcweir         if(!mpTextureCoordiantes)
1207cdf0e10cSrcweir         {
1208cdf0e10cSrcweir             if(!rValue.equalZero())
1209cdf0e10cSrcweir             {
1210cdf0e10cSrcweir                 mpTextureCoordiantes = new TextureCoordinate2D(maPoints.count());
1211cdf0e10cSrcweir                 mpTextureCoordiantes->setTextureCoordinate(nIndex, rValue);
1212cdf0e10cSrcweir             }
1213cdf0e10cSrcweir         }
1214cdf0e10cSrcweir         else
1215cdf0e10cSrcweir         {
1216cdf0e10cSrcweir             mpTextureCoordiantes->setTextureCoordinate(nIndex, rValue);
1217cdf0e10cSrcweir 
1218cdf0e10cSrcweir             if(!mpTextureCoordiantes->isUsed())
1219cdf0e10cSrcweir             {
1220cdf0e10cSrcweir                 delete mpTextureCoordiantes;
1221cdf0e10cSrcweir                 mpTextureCoordiantes = 0L;
1222cdf0e10cSrcweir             }
1223cdf0e10cSrcweir         }
1224cdf0e10cSrcweir     }
1225cdf0e10cSrcweir 
areTextureCoordinatesUsed() const1226cdf0e10cSrcweir     bool areTextureCoordinatesUsed() const
1227cdf0e10cSrcweir     {
1228cdf0e10cSrcweir         return (mpTextureCoordiantes && mpTextureCoordiantes->isUsed());
1229cdf0e10cSrcweir     }
1230cdf0e10cSrcweir 
clearTextureCoordinates()1231cdf0e10cSrcweir     void clearTextureCoordinates()
1232cdf0e10cSrcweir     {
1233cdf0e10cSrcweir         if(mpTextureCoordiantes)
1234cdf0e10cSrcweir         {
1235cdf0e10cSrcweir             delete mpTextureCoordiantes;
1236cdf0e10cSrcweir             mpTextureCoordiantes = 0L;
1237cdf0e10cSrcweir         }
1238cdf0e10cSrcweir     }
1239cdf0e10cSrcweir 
transformTextureCoordinates(const::basegfx::B2DHomMatrix & rMatrix)1240cdf0e10cSrcweir     void transformTextureCoordinates(const ::basegfx::B2DHomMatrix& rMatrix)
1241cdf0e10cSrcweir     {
1242cdf0e10cSrcweir         if(mpTextureCoordiantes)
1243cdf0e10cSrcweir         {
1244cdf0e10cSrcweir             mpTextureCoordiantes->transform(rMatrix);
1245cdf0e10cSrcweir         }
1246cdf0e10cSrcweir     }
1247cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const ImplB3DPolygon & rSource)1248cdf0e10cSrcweir     void insert(sal_uInt32 nIndex, const ImplB3DPolygon& rSource)
1249cdf0e10cSrcweir     {
1250cdf0e10cSrcweir         const sal_uInt32 nCount(rSource.maPoints.count());
1251cdf0e10cSrcweir 
1252cdf0e10cSrcweir         if(nCount)
1253cdf0e10cSrcweir         {
1254cdf0e10cSrcweir             maPoints.insert(nIndex, rSource.maPoints);
1255cdf0e10cSrcweir             invalidatePlaneNormal();
1256cdf0e10cSrcweir 
1257cdf0e10cSrcweir             if(rSource.mpBColors && rSource.mpBColors->isUsed())
1258cdf0e10cSrcweir             {
1259cdf0e10cSrcweir                 if(!mpBColors)
1260cdf0e10cSrcweir                 {
1261cdf0e10cSrcweir                     mpBColors = new BColorArray(maPoints.count());
1262cdf0e10cSrcweir                 }
1263cdf0e10cSrcweir 
1264cdf0e10cSrcweir                 mpBColors->insert(nIndex, *rSource.mpBColors);
1265cdf0e10cSrcweir             }
1266cdf0e10cSrcweir             else
1267cdf0e10cSrcweir             {
1268cdf0e10cSrcweir                 if(mpBColors)
1269cdf0e10cSrcweir                 {
1270cdf0e10cSrcweir                     mpBColors->insert(nIndex, ::basegfx::BColor::getEmptyBColor(), nCount);
1271cdf0e10cSrcweir                 }
1272cdf0e10cSrcweir             }
1273cdf0e10cSrcweir 
1274cdf0e10cSrcweir             if(rSource.mpNormals && rSource.mpNormals->isUsed())
1275cdf0e10cSrcweir             {
1276cdf0e10cSrcweir                 if(!mpNormals)
1277cdf0e10cSrcweir                 {
1278cdf0e10cSrcweir                     mpNormals = new NormalsArray3D(maPoints.count());
1279cdf0e10cSrcweir                 }
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir                 mpNormals->insert(nIndex, *rSource.mpNormals);
1282cdf0e10cSrcweir             }
1283cdf0e10cSrcweir             else
1284cdf0e10cSrcweir             {
1285cdf0e10cSrcweir                 if(mpNormals)
1286cdf0e10cSrcweir                 {
1287cdf0e10cSrcweir                     mpNormals->insert(nIndex, ::basegfx::B3DVector::getEmptyVector(), nCount);
1288cdf0e10cSrcweir                 }
1289cdf0e10cSrcweir             }
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir             if(rSource.mpTextureCoordiantes && rSource.mpTextureCoordiantes->isUsed())
1292cdf0e10cSrcweir             {
1293cdf0e10cSrcweir                 if(!mpTextureCoordiantes)
1294cdf0e10cSrcweir                 {
1295cdf0e10cSrcweir                     mpTextureCoordiantes = new TextureCoordinate2D(maPoints.count());
1296cdf0e10cSrcweir                 }
1297cdf0e10cSrcweir 
1298cdf0e10cSrcweir                 mpTextureCoordiantes->insert(nIndex, *rSource.mpTextureCoordiantes);
1299cdf0e10cSrcweir             }
1300cdf0e10cSrcweir             else
1301cdf0e10cSrcweir             {
1302cdf0e10cSrcweir                 if(mpTextureCoordiantes)
1303cdf0e10cSrcweir                 {
1304cdf0e10cSrcweir                     mpTextureCoordiantes->insert(nIndex, ::basegfx::B2DPoint::getEmptyPoint(), nCount);
1305cdf0e10cSrcweir                 }
1306cdf0e10cSrcweir             }
1307cdf0e10cSrcweir         }
1308cdf0e10cSrcweir     }
1309cdf0e10cSrcweir 
remove(sal_uInt32 nIndex,sal_uInt32 nCount)1310cdf0e10cSrcweir     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
1311cdf0e10cSrcweir     {
1312cdf0e10cSrcweir         if(nCount)
1313cdf0e10cSrcweir         {
1314cdf0e10cSrcweir             maPoints.remove(nIndex, nCount);
1315cdf0e10cSrcweir             invalidatePlaneNormal();
1316cdf0e10cSrcweir 
1317cdf0e10cSrcweir             if(mpBColors)
1318cdf0e10cSrcweir             {
1319cdf0e10cSrcweir                 mpBColors->remove(nIndex, nCount);
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir                 if(!mpBColors->isUsed())
1322cdf0e10cSrcweir                 {
1323cdf0e10cSrcweir                     delete mpBColors;
1324cdf0e10cSrcweir                     mpBColors = 0L;
1325cdf0e10cSrcweir                 }
1326cdf0e10cSrcweir             }
1327cdf0e10cSrcweir 
1328cdf0e10cSrcweir             if(mpNormals)
1329cdf0e10cSrcweir             {
1330cdf0e10cSrcweir                 mpNormals->remove(nIndex, nCount);
1331cdf0e10cSrcweir 
1332cdf0e10cSrcweir                 if(!mpNormals->isUsed())
1333cdf0e10cSrcweir                 {
1334cdf0e10cSrcweir                     delete mpNormals;
1335cdf0e10cSrcweir                     mpNormals = 0L;
1336cdf0e10cSrcweir                 }
1337cdf0e10cSrcweir             }
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir             if(mpTextureCoordiantes)
1340cdf0e10cSrcweir             {
1341cdf0e10cSrcweir                 mpTextureCoordiantes->remove(nIndex, nCount);
1342cdf0e10cSrcweir 
1343cdf0e10cSrcweir                 if(!mpTextureCoordiantes->isUsed())
1344cdf0e10cSrcweir                 {
1345cdf0e10cSrcweir                     delete mpTextureCoordiantes;
1346cdf0e10cSrcweir                     mpTextureCoordiantes = 0L;
1347cdf0e10cSrcweir                 }
1348cdf0e10cSrcweir             }
1349cdf0e10cSrcweir         }
1350cdf0e10cSrcweir     }
1351cdf0e10cSrcweir 
flip()1352cdf0e10cSrcweir     void flip()
1353cdf0e10cSrcweir     {
1354cdf0e10cSrcweir         if(maPoints.count() > 1)
1355cdf0e10cSrcweir         {
1356cdf0e10cSrcweir             maPoints.flip();
1357cdf0e10cSrcweir 
1358cdf0e10cSrcweir             if(mbPlaneNormalValid)
1359cdf0e10cSrcweir             {
1360cdf0e10cSrcweir                 // mirror plane normal
1361cdf0e10cSrcweir                 maPlaneNormal = -maPlaneNormal;
1362cdf0e10cSrcweir             }
1363cdf0e10cSrcweir 
1364cdf0e10cSrcweir             if(mpBColors)
1365cdf0e10cSrcweir             {
1366cdf0e10cSrcweir                 mpBColors->flip();
1367cdf0e10cSrcweir             }
1368cdf0e10cSrcweir 
1369cdf0e10cSrcweir             if(mpNormals)
1370cdf0e10cSrcweir             {
1371cdf0e10cSrcweir                 mpNormals->flip();
1372cdf0e10cSrcweir             }
1373cdf0e10cSrcweir 
1374cdf0e10cSrcweir             if(mpTextureCoordiantes)
1375cdf0e10cSrcweir             {
1376cdf0e10cSrcweir                 mpTextureCoordiantes->flip();
1377cdf0e10cSrcweir             }
1378cdf0e10cSrcweir         }
1379cdf0e10cSrcweir     }
1380cdf0e10cSrcweir 
hasDoublePoints() const1381cdf0e10cSrcweir     bool hasDoublePoints() const
1382cdf0e10cSrcweir     {
1383cdf0e10cSrcweir         if(mbIsClosed)
1384cdf0e10cSrcweir         {
1385cdf0e10cSrcweir             // check for same start and end point
1386cdf0e10cSrcweir             const sal_uInt32 nIndex(maPoints.count() - 1L);
1387cdf0e10cSrcweir 
1388cdf0e10cSrcweir             if(maPoints.getCoordinate(0L) == maPoints.getCoordinate(nIndex))
1389cdf0e10cSrcweir             {
1390cdf0e10cSrcweir                 const bool bBColorEqual(!mpBColors || (mpBColors->getBColor(0L) == mpBColors->getBColor(nIndex)));
1391cdf0e10cSrcweir 
1392cdf0e10cSrcweir                 if(bBColorEqual)
1393cdf0e10cSrcweir                 {
1394cdf0e10cSrcweir                     const bool bNormalsEqual(!mpNormals || (mpNormals->getNormal(0L) == mpNormals->getNormal(nIndex)));
1395cdf0e10cSrcweir 
1396cdf0e10cSrcweir                     if(bNormalsEqual)
1397cdf0e10cSrcweir                     {
1398cdf0e10cSrcweir                         const bool bTextureCoordinatesEqual(!mpTextureCoordiantes || (mpTextureCoordiantes->getTextureCoordinate(0L) == mpTextureCoordiantes->getTextureCoordinate(nIndex)));
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir                         if(bTextureCoordinatesEqual)
1401cdf0e10cSrcweir                         {
1402cdf0e10cSrcweir                             return true;
1403cdf0e10cSrcweir                         }
1404cdf0e10cSrcweir                     }
1405cdf0e10cSrcweir                 }
1406cdf0e10cSrcweir             }
1407cdf0e10cSrcweir         }
1408cdf0e10cSrcweir 
1409cdf0e10cSrcweir         // test for range
1410cdf0e10cSrcweir         for(sal_uInt32 a(0L); a < maPoints.count() - 1L; a++)
1411cdf0e10cSrcweir         {
1412cdf0e10cSrcweir             if(maPoints.getCoordinate(a) == maPoints.getCoordinate(a + 1L))
1413cdf0e10cSrcweir             {
1414cdf0e10cSrcweir                 const bool bBColorEqual(!mpBColors || (mpBColors->getBColor(a) == mpBColors->getBColor(a + 1L)));
1415cdf0e10cSrcweir 
1416cdf0e10cSrcweir                 if(bBColorEqual)
1417cdf0e10cSrcweir                 {
1418cdf0e10cSrcweir                     const bool bNormalsEqual(!mpNormals || (mpNormals->getNormal(a) == mpNormals->getNormal(a + 1L)));
1419cdf0e10cSrcweir 
1420cdf0e10cSrcweir                     if(bNormalsEqual)
1421cdf0e10cSrcweir                     {
1422cdf0e10cSrcweir                         const bool bTextureCoordinatesEqual(!mpTextureCoordiantes || (mpTextureCoordiantes->getTextureCoordinate(a) == mpTextureCoordiantes->getTextureCoordinate(a + 1L)));
1423cdf0e10cSrcweir 
1424cdf0e10cSrcweir                         if(bTextureCoordinatesEqual)
1425cdf0e10cSrcweir                         {
1426cdf0e10cSrcweir                             return true;
1427cdf0e10cSrcweir                         }
1428cdf0e10cSrcweir                     }
1429cdf0e10cSrcweir                 }
1430cdf0e10cSrcweir             }
1431cdf0e10cSrcweir         }
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir         return false;
1434cdf0e10cSrcweir     }
1435cdf0e10cSrcweir 
removeDoublePointsAtBeginEnd()1436cdf0e10cSrcweir     void removeDoublePointsAtBeginEnd()
1437cdf0e10cSrcweir     {
1438cdf0e10cSrcweir         // Only remove DoublePoints at Begin and End when poly is closed
1439cdf0e10cSrcweir         if(mbIsClosed)
1440cdf0e10cSrcweir         {
1441cdf0e10cSrcweir             bool bRemove;
1442cdf0e10cSrcweir 
1443cdf0e10cSrcweir             do
1444cdf0e10cSrcweir             {
1445cdf0e10cSrcweir                 bRemove = false;
1446cdf0e10cSrcweir 
1447cdf0e10cSrcweir                 if(maPoints.count() > 1L)
1448cdf0e10cSrcweir                 {
1449cdf0e10cSrcweir                     const sal_uInt32 nIndex(maPoints.count() - 1L);
1450cdf0e10cSrcweir                     bRemove = (maPoints.getCoordinate(0L) == maPoints.getCoordinate(nIndex));
1451cdf0e10cSrcweir 
1452cdf0e10cSrcweir                     if(bRemove && mpBColors && !(mpBColors->getBColor(0L) == mpBColors->getBColor(nIndex)))
1453cdf0e10cSrcweir                     {
1454cdf0e10cSrcweir                         bRemove = false;
1455cdf0e10cSrcweir                     }
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir                     if(bRemove && mpNormals && !(mpNormals->getNormal(0L) == mpNormals->getNormal(nIndex)))
1458cdf0e10cSrcweir                     {
1459cdf0e10cSrcweir                         bRemove = false;
1460cdf0e10cSrcweir                     }
1461cdf0e10cSrcweir 
1462cdf0e10cSrcweir                     if(bRemove && mpTextureCoordiantes && !(mpTextureCoordiantes->getTextureCoordinate(0L) == mpTextureCoordiantes->getTextureCoordinate(nIndex)))
1463cdf0e10cSrcweir                     {
1464cdf0e10cSrcweir                         bRemove = false;
1465cdf0e10cSrcweir                     }
1466cdf0e10cSrcweir                 }
1467cdf0e10cSrcweir 
1468cdf0e10cSrcweir                 if(bRemove)
1469cdf0e10cSrcweir                 {
1470cdf0e10cSrcweir                     const sal_uInt32 nIndex(maPoints.count() - 1L);
1471cdf0e10cSrcweir                     remove(nIndex, 1L);
1472cdf0e10cSrcweir                 }
1473cdf0e10cSrcweir             } while(bRemove);
1474cdf0e10cSrcweir         }
1475cdf0e10cSrcweir     }
1476cdf0e10cSrcweir 
removeDoublePointsWholeTrack()1477cdf0e10cSrcweir     void removeDoublePointsWholeTrack()
1478cdf0e10cSrcweir     {
1479cdf0e10cSrcweir         sal_uInt32 nIndex(0L);
1480cdf0e10cSrcweir 
1481cdf0e10cSrcweir         // test as long as there are at least two points and as long as the index
1482cdf0e10cSrcweir         // is smaller or equal second last point
1483cdf0e10cSrcweir         while((maPoints.count() > 1L) && (nIndex <= maPoints.count() - 2L))
1484cdf0e10cSrcweir         {
1485cdf0e10cSrcweir             const sal_uInt32 nNextIndex(nIndex + 1L);
1486cdf0e10cSrcweir             bool bRemove(maPoints.getCoordinate(nIndex) == maPoints.getCoordinate(nNextIndex));
1487cdf0e10cSrcweir 
1488cdf0e10cSrcweir             if(bRemove && mpBColors && !(mpBColors->getBColor(nIndex) == mpBColors->getBColor(nNextIndex)))
1489cdf0e10cSrcweir             {
1490cdf0e10cSrcweir                 bRemove = false;
1491cdf0e10cSrcweir             }
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir             if(bRemove && mpNormals && !(mpNormals->getNormal(nIndex) == mpNormals->getNormal(nNextIndex)))
1494cdf0e10cSrcweir             {
1495cdf0e10cSrcweir                 bRemove = false;
1496cdf0e10cSrcweir             }
1497cdf0e10cSrcweir 
1498cdf0e10cSrcweir             if(bRemove && mpTextureCoordiantes && !(mpTextureCoordiantes->getTextureCoordinate(nIndex) == mpTextureCoordiantes->getTextureCoordinate(nNextIndex)))
1499cdf0e10cSrcweir             {
1500cdf0e10cSrcweir                 bRemove = false;
1501cdf0e10cSrcweir             }
1502cdf0e10cSrcweir 
1503cdf0e10cSrcweir             if(bRemove)
1504cdf0e10cSrcweir             {
1505cdf0e10cSrcweir                 // if next is same as index and the control vectors are unused, delete index
1506cdf0e10cSrcweir                 remove(nIndex, 1L);
1507cdf0e10cSrcweir             }
1508cdf0e10cSrcweir             else
1509cdf0e10cSrcweir             {
1510cdf0e10cSrcweir                 // if different, step forward
1511cdf0e10cSrcweir                 nIndex++;
1512cdf0e10cSrcweir             }
1513cdf0e10cSrcweir         }
1514cdf0e10cSrcweir     }
1515cdf0e10cSrcweir 
transform(const::basegfx::B3DHomMatrix & rMatrix)1516cdf0e10cSrcweir     void transform(const ::basegfx::B3DHomMatrix& rMatrix)
1517cdf0e10cSrcweir     {
1518cdf0e10cSrcweir         maPoints.transform(rMatrix);
1519cdf0e10cSrcweir 
1520cdf0e10cSrcweir         // Here, it seems to be possible to transform a valid plane normal and to avoid
1521cdf0e10cSrcweir         // invalidation, but it's not true. If the transformation contains shears or e.g.
1522cdf0e10cSrcweir         // perspective projection, the orthogonality to the transformed plane will not
1523cdf0e10cSrcweir         // be preserved. It may be possible to test that at the matrix to not invalidate in
1524cdf0e10cSrcweir         // all cases or to extract a matrix which does not 'shear' the vector which is
1525cdf0e10cSrcweir         // a normal in this case. As long as this is not sure, i will just invalidate.
1526cdf0e10cSrcweir         invalidatePlaneNormal();
1527cdf0e10cSrcweir     }
1528cdf0e10cSrcweir };
1529cdf0e10cSrcweir 
1530cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1531cdf0e10cSrcweir 
1532cdf0e10cSrcweir namespace basegfx
1533cdf0e10cSrcweir {
1534cdf0e10cSrcweir     namespace { struct DefaultPolygon : public rtl::Static< B3DPolygon::ImplType,
1535cdf0e10cSrcweir                                                             DefaultPolygon > {}; }
1536cdf0e10cSrcweir 
B3DPolygon()1537cdf0e10cSrcweir     B3DPolygon::B3DPolygon() :
1538cdf0e10cSrcweir         mpPolygon(DefaultPolygon::get())
1539cdf0e10cSrcweir     {
1540cdf0e10cSrcweir     }
1541cdf0e10cSrcweir 
B3DPolygon(const B3DPolygon & rPolygon)1542cdf0e10cSrcweir     B3DPolygon::B3DPolygon(const B3DPolygon& rPolygon) :
1543cdf0e10cSrcweir         mpPolygon(rPolygon.mpPolygon)
1544cdf0e10cSrcweir     {
1545cdf0e10cSrcweir     }
1546cdf0e10cSrcweir 
B3DPolygon(const B3DPolygon & rPolygon,sal_uInt32 nIndex,sal_uInt32 nCount)1547cdf0e10cSrcweir     B3DPolygon::B3DPolygon(const B3DPolygon& rPolygon, sal_uInt32 nIndex, sal_uInt32 nCount) :
1548cdf0e10cSrcweir         mpPolygon(ImplB3DPolygon(*rPolygon.mpPolygon, nIndex, nCount))
1549cdf0e10cSrcweir     {
1550cdf0e10cSrcweir         // TODO(P2): one extra temporary here (cow_wrapper copies
1551cdf0e10cSrcweir         // given ImplB3DPolygon into its internal impl_t wrapper type)
1552cdf0e10cSrcweir         OSL_ENSURE(nIndex + nCount > rPolygon.mpPolygon->count(), "B3DPolygon constructor outside range (!)");
1553cdf0e10cSrcweir     }
1554cdf0e10cSrcweir 
~B3DPolygon()1555cdf0e10cSrcweir     B3DPolygon::~B3DPolygon()
1556cdf0e10cSrcweir     {
1557cdf0e10cSrcweir     }
1558cdf0e10cSrcweir 
operator =(const B3DPolygon & rPolygon)1559cdf0e10cSrcweir     B3DPolygon& B3DPolygon::operator=(const B3DPolygon& rPolygon)
1560cdf0e10cSrcweir     {
1561cdf0e10cSrcweir         mpPolygon = rPolygon.mpPolygon;
1562cdf0e10cSrcweir         return *this;
1563cdf0e10cSrcweir     }
1564cdf0e10cSrcweir 
makeUnique()1565cdf0e10cSrcweir     void B3DPolygon::makeUnique()
1566cdf0e10cSrcweir     {
1567cdf0e10cSrcweir         mpPolygon.make_unique();
1568cdf0e10cSrcweir     }
1569cdf0e10cSrcweir 
operator ==(const B3DPolygon & rPolygon) const1570cdf0e10cSrcweir     bool B3DPolygon::operator==(const B3DPolygon& rPolygon) const
1571cdf0e10cSrcweir     {
1572cdf0e10cSrcweir         if(mpPolygon.same_object(rPolygon.mpPolygon))
1573cdf0e10cSrcweir             return true;
1574cdf0e10cSrcweir 
1575cdf0e10cSrcweir         return (*mpPolygon == *rPolygon.mpPolygon);
1576cdf0e10cSrcweir     }
1577cdf0e10cSrcweir 
operator !=(const B3DPolygon & rPolygon) const1578cdf0e10cSrcweir     bool B3DPolygon::operator!=(const B3DPolygon& rPolygon) const
1579cdf0e10cSrcweir     {
1580cdf0e10cSrcweir         return !(*this == rPolygon);
1581cdf0e10cSrcweir     }
1582cdf0e10cSrcweir 
count() const1583cdf0e10cSrcweir     sal_uInt32 B3DPolygon::count() const
1584cdf0e10cSrcweir     {
1585cdf0e10cSrcweir         return mpPolygon->count();
1586cdf0e10cSrcweir     }
1587cdf0e10cSrcweir 
getB3DPoint(sal_uInt32 nIndex) const1588cdf0e10cSrcweir     basegfx::B3DPoint B3DPolygon::getB3DPoint(sal_uInt32 nIndex) const
1589cdf0e10cSrcweir     {
1590cdf0e10cSrcweir         OSL_ENSURE(nIndex < mpPolygon->count(), "B3DPolygon access outside range (!)");
1591cdf0e10cSrcweir 
1592cdf0e10cSrcweir         return mpPolygon->getPoint(nIndex);
1593cdf0e10cSrcweir     }
1594cdf0e10cSrcweir 
setB3DPoint(sal_uInt32 nIndex,const basegfx::B3DPoint & rValue)1595cdf0e10cSrcweir     void B3DPolygon::setB3DPoint(sal_uInt32 nIndex, const basegfx::B3DPoint& rValue)
1596cdf0e10cSrcweir     {
1597cdf0e10cSrcweir         OSL_ENSURE(nIndex < mpPolygon->count(), "B3DPolygon access outside range (!)");
1598cdf0e10cSrcweir 
1599cdf0e10cSrcweir         if(getB3DPoint(nIndex) != rValue)
1600cdf0e10cSrcweir             mpPolygon->setPoint(nIndex, rValue);
1601cdf0e10cSrcweir     }
1602cdf0e10cSrcweir 
getBColor(sal_uInt32 nIndex) const1603cdf0e10cSrcweir     BColor B3DPolygon::getBColor(sal_uInt32 nIndex) const
1604cdf0e10cSrcweir     {
1605cdf0e10cSrcweir         OSL_ENSURE(nIndex < mpPolygon->count(), "B3DPolygon access outside range (!)");
1606cdf0e10cSrcweir 
1607cdf0e10cSrcweir         return mpPolygon->getBColor(nIndex);
1608cdf0e10cSrcweir     }
1609cdf0e10cSrcweir 
setBColor(sal_uInt32 nIndex,const BColor & rValue)1610cdf0e10cSrcweir     void B3DPolygon::setBColor(sal_uInt32 nIndex, const BColor& rValue)
1611cdf0e10cSrcweir     {
1612cdf0e10cSrcweir         OSL_ENSURE(nIndex < mpPolygon->count(), "B3DPolygon access outside range (!)");
1613cdf0e10cSrcweir 
1614cdf0e10cSrcweir         if(mpPolygon->getBColor(nIndex) != rValue)
1615cdf0e10cSrcweir             mpPolygon->setBColor(nIndex, rValue);
1616cdf0e10cSrcweir     }
1617cdf0e10cSrcweir 
areBColorsUsed() const1618cdf0e10cSrcweir     bool B3DPolygon::areBColorsUsed() const
1619cdf0e10cSrcweir     {
1620cdf0e10cSrcweir         return mpPolygon->areBColorsUsed();
1621cdf0e10cSrcweir     }
1622cdf0e10cSrcweir 
clearBColors()1623cdf0e10cSrcweir     void B3DPolygon::clearBColors()
1624cdf0e10cSrcweir     {
1625cdf0e10cSrcweir         if(mpPolygon->areBColorsUsed())
1626cdf0e10cSrcweir             mpPolygon->clearBColors();
1627cdf0e10cSrcweir     }
1628cdf0e10cSrcweir 
getNormal() const1629cdf0e10cSrcweir     B3DVector B3DPolygon::getNormal() const
1630cdf0e10cSrcweir     {
1631cdf0e10cSrcweir         return mpPolygon->getNormal();
1632cdf0e10cSrcweir     }
1633cdf0e10cSrcweir 
getNormal(sal_uInt32 nIndex) const1634cdf0e10cSrcweir     B3DVector B3DPolygon::getNormal(sal_uInt32 nIndex) const
1635cdf0e10cSrcweir     {
1636cdf0e10cSrcweir         OSL_ENSURE(nIndex < mpPolygon->count(), "B3DPolygon access outside range (!)");
1637cdf0e10cSrcweir 
1638cdf0e10cSrcweir         return mpPolygon->getNormal(nIndex);
1639cdf0e10cSrcweir     }
1640cdf0e10cSrcweir 
setNormal(sal_uInt32 nIndex,const B3DVector & rValue)1641cdf0e10cSrcweir     void B3DPolygon::setNormal(sal_uInt32 nIndex, const B3DVector& rValue)
1642cdf0e10cSrcweir     {
1643cdf0e10cSrcweir         OSL_ENSURE(nIndex < mpPolygon->count(), "B3DPolygon access outside range (!)");
1644cdf0e10cSrcweir 
1645cdf0e10cSrcweir         if(mpPolygon->getNormal(nIndex) != rValue)
1646cdf0e10cSrcweir             mpPolygon->setNormal(nIndex, rValue);
1647cdf0e10cSrcweir     }
1648cdf0e10cSrcweir 
transformNormals(const B3DHomMatrix & rMatrix)1649cdf0e10cSrcweir     void B3DPolygon::transformNormals(const B3DHomMatrix& rMatrix)
1650cdf0e10cSrcweir     {
1651cdf0e10cSrcweir         if(mpPolygon->areNormalsUsed() && !rMatrix.isIdentity())
1652cdf0e10cSrcweir             mpPolygon->transformNormals(rMatrix);
1653cdf0e10cSrcweir     }
1654cdf0e10cSrcweir 
areNormalsUsed() const1655cdf0e10cSrcweir     bool B3DPolygon::areNormalsUsed() const
1656cdf0e10cSrcweir     {
1657cdf0e10cSrcweir         return mpPolygon->areNormalsUsed();
1658cdf0e10cSrcweir     }
1659cdf0e10cSrcweir 
clearNormals()1660cdf0e10cSrcweir     void B3DPolygon::clearNormals()
1661cdf0e10cSrcweir     {
1662cdf0e10cSrcweir         if(mpPolygon->areNormalsUsed())
1663cdf0e10cSrcweir             mpPolygon->clearNormals();
1664cdf0e10cSrcweir     }
1665cdf0e10cSrcweir 
getTextureCoordinate(sal_uInt32 nIndex) const1666cdf0e10cSrcweir     B2DPoint B3DPolygon::getTextureCoordinate(sal_uInt32 nIndex) const
1667cdf0e10cSrcweir     {
1668cdf0e10cSrcweir         OSL_ENSURE(nIndex < mpPolygon->count(), "B3DPolygon access outside range (!)");
1669cdf0e10cSrcweir 
1670cdf0e10cSrcweir         return mpPolygon->getTextureCoordinate(nIndex);
1671cdf0e10cSrcweir     }
1672cdf0e10cSrcweir 
setTextureCoordinate(sal_uInt32 nIndex,const B2DPoint & rValue)1673cdf0e10cSrcweir     void B3DPolygon::setTextureCoordinate(sal_uInt32 nIndex, const B2DPoint& rValue)
1674cdf0e10cSrcweir     {
1675cdf0e10cSrcweir         OSL_ENSURE(nIndex < mpPolygon->count(), "B3DPolygon access outside range (!)");
1676cdf0e10cSrcweir 
1677cdf0e10cSrcweir         if(mpPolygon->getTextureCoordinate(nIndex) != rValue)
1678cdf0e10cSrcweir             mpPolygon->setTextureCoordinate(nIndex, rValue);
1679cdf0e10cSrcweir     }
1680cdf0e10cSrcweir 
transformTextureCoordiantes(const B2DHomMatrix & rMatrix)1681cdf0e10cSrcweir     void B3DPolygon::transformTextureCoordiantes(const B2DHomMatrix& rMatrix)
1682cdf0e10cSrcweir     {
1683cdf0e10cSrcweir         if(mpPolygon->areTextureCoordinatesUsed() && !rMatrix.isIdentity())
1684cdf0e10cSrcweir             mpPolygon->transformTextureCoordinates(rMatrix);
1685cdf0e10cSrcweir     }
1686cdf0e10cSrcweir 
areTextureCoordinatesUsed() const1687cdf0e10cSrcweir     bool B3DPolygon::areTextureCoordinatesUsed() const
1688cdf0e10cSrcweir     {
1689cdf0e10cSrcweir         return mpPolygon->areTextureCoordinatesUsed();
1690cdf0e10cSrcweir     }
1691cdf0e10cSrcweir 
clearTextureCoordinates()1692cdf0e10cSrcweir     void B3DPolygon::clearTextureCoordinates()
1693cdf0e10cSrcweir     {
1694cdf0e10cSrcweir         if(mpPolygon->areTextureCoordinatesUsed())
1695cdf0e10cSrcweir             mpPolygon->clearTextureCoordinates();
1696cdf0e10cSrcweir     }
1697cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const::basegfx::B3DPoint & rPoint,sal_uInt32 nCount)1698cdf0e10cSrcweir     void B3DPolygon::insert(sal_uInt32 nIndex, const ::basegfx::B3DPoint& rPoint, sal_uInt32 nCount)
1699cdf0e10cSrcweir     {
1700cdf0e10cSrcweir         OSL_ENSURE(nIndex <= mpPolygon->count(), "B3DPolygon Insert outside range (!)");
1701cdf0e10cSrcweir 
1702cdf0e10cSrcweir         if(nCount)
1703cdf0e10cSrcweir             mpPolygon->insert(nIndex, rPoint, nCount);
1704cdf0e10cSrcweir     }
1705cdf0e10cSrcweir 
append(const basegfx::B3DPoint & rPoint,sal_uInt32 nCount)1706cdf0e10cSrcweir     void B3DPolygon::append(const basegfx::B3DPoint& rPoint, sal_uInt32 nCount)
1707cdf0e10cSrcweir     {
1708cdf0e10cSrcweir         if(nCount)
1709cdf0e10cSrcweir             mpPolygon->insert(mpPolygon->count(), rPoint, nCount);
1710cdf0e10cSrcweir     }
1711cdf0e10cSrcweir 
insert(sal_uInt32 nIndex,const B3DPolygon & rPoly,sal_uInt32 nIndex2,sal_uInt32 nCount)1712cdf0e10cSrcweir     void B3DPolygon::insert(sal_uInt32 nIndex, const B3DPolygon& rPoly, sal_uInt32 nIndex2, sal_uInt32 nCount)
1713cdf0e10cSrcweir     {
1714cdf0e10cSrcweir         OSL_ENSURE(nIndex <= mpPolygon->count(), "B3DPolygon Insert outside range (!)");
1715cdf0e10cSrcweir 
1716cdf0e10cSrcweir         if(rPoly.count())
1717cdf0e10cSrcweir         {
1718cdf0e10cSrcweir             if(!nCount)
1719cdf0e10cSrcweir             {
1720cdf0e10cSrcweir                 nCount = rPoly.count();
1721cdf0e10cSrcweir             }
1722cdf0e10cSrcweir 
1723cdf0e10cSrcweir             if(0L == nIndex2 && nCount == rPoly.count())
1724cdf0e10cSrcweir             {
1725cdf0e10cSrcweir                 mpPolygon->insert(nIndex, *rPoly.mpPolygon);
1726cdf0e10cSrcweir             }
1727cdf0e10cSrcweir             else
1728cdf0e10cSrcweir             {
1729cdf0e10cSrcweir                 OSL_ENSURE(nIndex2 + nCount <= rPoly.mpPolygon->count(), "B3DPolygon Insert outside range (!)");
1730cdf0e10cSrcweir                 ImplB3DPolygon aTempPoly(*rPoly.mpPolygon, nIndex2, nCount);
1731cdf0e10cSrcweir                 mpPolygon->insert(nIndex, aTempPoly);
1732cdf0e10cSrcweir             }
1733cdf0e10cSrcweir         }
1734cdf0e10cSrcweir     }
1735cdf0e10cSrcweir 
append(const B3DPolygon & rPoly,sal_uInt32 nIndex,sal_uInt32 nCount)1736cdf0e10cSrcweir     void B3DPolygon::append(const B3DPolygon& rPoly, sal_uInt32 nIndex, sal_uInt32 nCount)
1737cdf0e10cSrcweir     {
1738cdf0e10cSrcweir         if(rPoly.count())
1739cdf0e10cSrcweir         {
1740cdf0e10cSrcweir             if(!nCount)
1741cdf0e10cSrcweir             {
1742cdf0e10cSrcweir                 nCount = rPoly.count();
1743cdf0e10cSrcweir             }
1744cdf0e10cSrcweir 
1745cdf0e10cSrcweir             if(0L == nIndex && nCount == rPoly.count())
1746cdf0e10cSrcweir             {
1747cdf0e10cSrcweir                 mpPolygon->insert(mpPolygon->count(), *rPoly.mpPolygon);
1748cdf0e10cSrcweir             }
1749cdf0e10cSrcweir             else
1750cdf0e10cSrcweir             {
1751cdf0e10cSrcweir                 OSL_ENSURE(nIndex + nCount <= rPoly.mpPolygon->count(), "B3DPolygon Append outside range (!)");
1752cdf0e10cSrcweir                 ImplB3DPolygon aTempPoly(*rPoly.mpPolygon, nIndex, nCount);
1753cdf0e10cSrcweir                 mpPolygon->insert(mpPolygon->count(), aTempPoly);
1754cdf0e10cSrcweir             }
1755cdf0e10cSrcweir         }
1756cdf0e10cSrcweir     }
1757cdf0e10cSrcweir 
remove(sal_uInt32 nIndex,sal_uInt32 nCount)1758cdf0e10cSrcweir     void B3DPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
1759cdf0e10cSrcweir     {
1760cdf0e10cSrcweir         OSL_ENSURE(nIndex + nCount <= mpPolygon->count(), "B3DPolygon Remove outside range (!)");
1761cdf0e10cSrcweir 
1762cdf0e10cSrcweir         if(nCount)
1763cdf0e10cSrcweir             mpPolygon->remove(nIndex, nCount);
1764cdf0e10cSrcweir     }
1765cdf0e10cSrcweir 
clear()1766cdf0e10cSrcweir     void B3DPolygon::clear()
1767cdf0e10cSrcweir     {
1768cdf0e10cSrcweir         mpPolygon = DefaultPolygon::get();
1769cdf0e10cSrcweir     }
1770cdf0e10cSrcweir 
isClosed() const1771cdf0e10cSrcweir     bool B3DPolygon::isClosed() const
1772cdf0e10cSrcweir     {
1773cdf0e10cSrcweir         return mpPolygon->isClosed();
1774cdf0e10cSrcweir     }
1775cdf0e10cSrcweir 
setClosed(bool bNew)1776cdf0e10cSrcweir     void B3DPolygon::setClosed(bool bNew)
1777cdf0e10cSrcweir     {
1778cdf0e10cSrcweir         if(isClosed() != bNew)
1779cdf0e10cSrcweir             mpPolygon->setClosed(bNew);
1780cdf0e10cSrcweir     }
1781cdf0e10cSrcweir 
flip()1782cdf0e10cSrcweir     void B3DPolygon::flip()
1783cdf0e10cSrcweir     {
1784cdf0e10cSrcweir         if(count() > 1)
1785cdf0e10cSrcweir             mpPolygon->flip();
1786cdf0e10cSrcweir     }
1787cdf0e10cSrcweir 
hasDoublePoints() const1788cdf0e10cSrcweir     bool B3DPolygon::hasDoublePoints() const
1789cdf0e10cSrcweir     {
1790cdf0e10cSrcweir         return (mpPolygon->count() > 1L && mpPolygon->hasDoublePoints());
1791cdf0e10cSrcweir     }
1792cdf0e10cSrcweir 
removeDoublePoints()1793cdf0e10cSrcweir     void B3DPolygon::removeDoublePoints()
1794cdf0e10cSrcweir     {
1795cdf0e10cSrcweir         if(hasDoublePoints())
1796cdf0e10cSrcweir         {
1797cdf0e10cSrcweir             mpPolygon->removeDoublePointsAtBeginEnd();
1798cdf0e10cSrcweir             mpPolygon->removeDoublePointsWholeTrack();
1799cdf0e10cSrcweir         }
1800cdf0e10cSrcweir     }
1801cdf0e10cSrcweir 
transform(const basegfx::B3DHomMatrix & rMatrix)1802cdf0e10cSrcweir     void B3DPolygon::transform(const basegfx::B3DHomMatrix& rMatrix)
1803cdf0e10cSrcweir     {
1804cdf0e10cSrcweir         if(mpPolygon->count() && !rMatrix.isIdentity())
1805cdf0e10cSrcweir         {
1806cdf0e10cSrcweir             mpPolygon->transform(rMatrix);
1807cdf0e10cSrcweir         }
1808cdf0e10cSrcweir     }
1809cdf0e10cSrcweir } // end of namespace basegfx
1810cdf0e10cSrcweir 
1811cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1812cdf0e10cSrcweir // eof
1813