xref: /trunk/main/basegfx/source/polygon/b3dpolypolygon.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basegfx.hxx"
30 #include <osl/diagnose.h>
31 #include <basegfx/polygon/b3dpolypolygon.hxx>
32 #include <basegfx/polygon/b3dpolygon.hxx>
33 #include <rtl/instance.hxx>
34 #include <basegfx/matrix/b2dhommatrix.hxx>
35 #include <basegfx/matrix/b3dhommatrix.hxx>
36 #include <functional>
37 #include <vector>
38 #include <algorithm>
39 
40 //////////////////////////////////////////////////////////////////////////////
41 
42 class ImplB3DPolyPolygon
43 {
44     typedef ::std::vector< ::basegfx::B3DPolygon >  PolygonVector;
45 
46     PolygonVector                                   maPolygons;
47 
48 public:
49     ImplB3DPolyPolygon() : maPolygons()
50     {
51     }
52 
53     ImplB3DPolyPolygon(const ::basegfx::B3DPolygon& rToBeCopied) :
54         maPolygons(1,rToBeCopied)
55     {
56     }
57 
58     bool operator==(const ImplB3DPolyPolygon& rPolygonList) const
59     {
60         // same polygon count?
61         if(maPolygons.size() != rPolygonList.maPolygons.size())
62             return false;
63 
64         // compare polygon content
65         if(maPolygons != rPolygonList.maPolygons)
66             return false;
67 
68         return true;
69     }
70 
71     const ::basegfx::B3DPolygon& getB3DPolygon(sal_uInt32 nIndex) const
72     {
73         return maPolygons[nIndex];
74     }
75 
76     void setB3DPolygon(sal_uInt32 nIndex, const ::basegfx::B3DPolygon& rPolygon)
77     {
78         maPolygons[nIndex] = rPolygon;
79     }
80 
81     void insert(sal_uInt32 nIndex, const ::basegfx::B3DPolygon& rPolygon, sal_uInt32 nCount)
82     {
83         if(nCount)
84         {
85             // add nCount copies of rPolygon
86             PolygonVector::iterator aIndex(maPolygons.begin());
87             aIndex += nIndex;
88             maPolygons.insert(aIndex, nCount, rPolygon);
89         }
90     }
91 
92     void insert(sal_uInt32 nIndex, const ::basegfx::B3DPolyPolygon& rPolyPolygon)
93     {
94         const sal_uInt32 nCount = rPolyPolygon.count();
95 
96         if(nCount)
97         {
98             // add nCount polygons from rPolyPolygon
99             maPolygons.reserve(maPolygons.size() + nCount);
100             PolygonVector::iterator aIndex(maPolygons.begin());
101             aIndex += nIndex;
102 
103             for(sal_uInt32 a(0L); a < nCount; a++)
104             {
105                 maPolygons.insert(aIndex, rPolyPolygon.getB3DPolygon(a));
106                 aIndex++;
107             }
108         }
109     }
110 
111     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
112     {
113         if(nCount)
114         {
115             // remove polygon data
116             PolygonVector::iterator aStart(maPolygons.begin());
117             aStart += nIndex;
118             const PolygonVector::iterator aEnd(aStart + nCount);
119 
120             maPolygons.erase(aStart, aEnd);
121         }
122     }
123 
124     sal_uInt32 count() const
125     {
126         return maPolygons.size();
127     }
128 
129     void setClosed(bool bNew)
130     {
131         for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
132         {
133             maPolygons[a].setClosed(bNew);
134         }
135     }
136 
137     void flip()
138     {
139         std::for_each( maPolygons.begin(),
140                        maPolygons.end(),
141                        std::mem_fun_ref( &::basegfx::B3DPolygon::flip ));
142     }
143 
144     void removeDoublePoints()
145     {
146         std::for_each( maPolygons.begin(),
147                        maPolygons.end(),
148                        std::mem_fun_ref( &::basegfx::B3DPolygon::removeDoublePoints ));
149     }
150 
151     void transform(const ::basegfx::B3DHomMatrix& rMatrix)
152     {
153         for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
154         {
155             maPolygons[a].transform(rMatrix);
156         }
157     }
158 
159     void clearBColors()
160     {
161         for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
162         {
163             maPolygons[a].clearBColors();
164         }
165     }
166 
167     void transformNormals(const ::basegfx::B3DHomMatrix& rMatrix)
168     {
169         for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
170         {
171             maPolygons[a].transformNormals(rMatrix);
172         }
173     }
174 
175     void clearNormals()
176     {
177         for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
178         {
179             maPolygons[a].clearNormals();
180         }
181     }
182 
183     void transformTextureCoordiantes(const ::basegfx::B2DHomMatrix& rMatrix)
184     {
185         for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
186         {
187             maPolygons[a].transformTextureCoordiantes(rMatrix);
188         }
189     }
190 
191     void clearTextureCoordinates()
192     {
193         for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
194         {
195             maPolygons[a].clearTextureCoordinates();
196         }
197     }
198 
199     void makeUnique()
200     {
201         std::for_each( maPolygons.begin(),
202                        maPolygons.end(),
203                        std::mem_fun_ref( &::basegfx::B3DPolygon::makeUnique ));
204     }
205 };
206 
207 //////////////////////////////////////////////////////////////////////////////
208 
209 namespace basegfx
210 {
211     namespace { struct DefaultPolyPolygon : public rtl::Static<B3DPolyPolygon::ImplType,
212                                                                DefaultPolyPolygon> {}; }
213 
214     B3DPolyPolygon::B3DPolyPolygon() :
215         mpPolyPolygon(DefaultPolyPolygon::get())
216     {
217     }
218 
219     B3DPolyPolygon::B3DPolyPolygon(const B3DPolyPolygon& rPolyPolygon) :
220         mpPolyPolygon(rPolyPolygon.mpPolyPolygon)
221     {
222     }
223 
224     B3DPolyPolygon::B3DPolyPolygon(const B3DPolygon& rPolygon) :
225         mpPolyPolygon( ImplB3DPolyPolygon(rPolygon) )
226     {
227     }
228 
229     B3DPolyPolygon::~B3DPolyPolygon()
230     {
231     }
232 
233     B3DPolyPolygon& B3DPolyPolygon::operator=(const B3DPolyPolygon& rPolyPolygon)
234     {
235         mpPolyPolygon = rPolyPolygon.mpPolyPolygon;
236         return *this;
237     }
238 
239     void B3DPolyPolygon::makeUnique()
240     {
241         mpPolyPolygon.make_unique();
242         mpPolyPolygon->makeUnique();
243     }
244 
245     bool B3DPolyPolygon::operator==(const B3DPolyPolygon& rPolyPolygon) const
246     {
247         if(mpPolyPolygon.same_object(rPolyPolygon.mpPolyPolygon))
248             return true;
249 
250         return ((*mpPolyPolygon) == (*rPolyPolygon.mpPolyPolygon));
251     }
252 
253     bool B3DPolyPolygon::operator!=(const B3DPolyPolygon& rPolyPolygon) const
254     {
255         return !(*this == rPolyPolygon);
256     }
257 
258     sal_uInt32 B3DPolyPolygon::count() const
259     {
260         return mpPolyPolygon->count();
261     }
262 
263     B3DPolygon B3DPolyPolygon::getB3DPolygon(sal_uInt32 nIndex) const
264     {
265         OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B3DPolyPolygon access outside range (!)");
266 
267         return mpPolyPolygon->getB3DPolygon(nIndex);
268     }
269 
270     void B3DPolyPolygon::setB3DPolygon(sal_uInt32 nIndex, const B3DPolygon& rPolygon)
271     {
272         OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B3DPolyPolygon access outside range (!)");
273 
274         if(getB3DPolygon(nIndex) != rPolygon)
275             mpPolyPolygon->setB3DPolygon(nIndex, rPolygon);
276     }
277 
278     bool B3DPolyPolygon::areBColorsUsed() const
279     {
280         for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
281         {
282             if((mpPolyPolygon->getB3DPolygon(a)).areBColorsUsed())
283             {
284                 return true;
285             }
286         }
287 
288         return false;
289     }
290 
291     void B3DPolyPolygon::clearBColors()
292     {
293         if(areBColorsUsed())
294             mpPolyPolygon->clearBColors();
295     }
296 
297     void B3DPolyPolygon::transformNormals(const B3DHomMatrix& rMatrix)
298     {
299         if(!rMatrix.isIdentity())
300             mpPolyPolygon->transformNormals(rMatrix);
301     }
302 
303     bool B3DPolyPolygon::areNormalsUsed() const
304     {
305         for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
306         {
307             if((mpPolyPolygon->getB3DPolygon(a)).areNormalsUsed())
308             {
309                 return true;
310             }
311         }
312 
313         return false;
314     }
315 
316     void B3DPolyPolygon::clearNormals()
317     {
318         if(areNormalsUsed())
319             mpPolyPolygon->clearNormals();
320     }
321 
322     void B3DPolyPolygon::transformTextureCoordiantes(const B2DHomMatrix& rMatrix)
323     {
324         if(!rMatrix.isIdentity())
325             mpPolyPolygon->transformTextureCoordiantes(rMatrix);
326     }
327 
328     bool B3DPolyPolygon::areTextureCoordinatesUsed() const
329     {
330         for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
331         {
332             if((mpPolyPolygon->getB3DPolygon(a)).areTextureCoordinatesUsed())
333             {
334                 return true;
335             }
336         }
337 
338         return false;
339     }
340 
341     void B3DPolyPolygon::clearTextureCoordinates()
342     {
343         if(areTextureCoordinatesUsed())
344             mpPolyPolygon->clearTextureCoordinates();
345     }
346 
347     void B3DPolyPolygon::insert(sal_uInt32 nIndex, const B3DPolygon& rPolygon, sal_uInt32 nCount)
348     {
349         OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B3DPolyPolygon Insert outside range (!)");
350 
351         if(nCount)
352             mpPolyPolygon->insert(nIndex, rPolygon, nCount);
353     }
354 
355     void B3DPolyPolygon::append(const B3DPolygon& rPolygon, sal_uInt32 nCount)
356     {
357         if(nCount)
358             mpPolyPolygon->insert(mpPolyPolygon->count(), rPolygon, nCount);
359     }
360 
361     void B3DPolyPolygon::insert(sal_uInt32 nIndex, const B3DPolyPolygon& rPolyPolygon)
362     {
363         OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B3DPolyPolygon Insert outside range (!)");
364 
365         if(rPolyPolygon.count())
366             mpPolyPolygon->insert(nIndex, rPolyPolygon);
367     }
368 
369     void B3DPolyPolygon::append(const B3DPolyPolygon& rPolyPolygon)
370     {
371         if(rPolyPolygon.count())
372             mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon);
373     }
374 
375     void B3DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
376     {
377         OSL_ENSURE(nIndex + nCount <= mpPolyPolygon->count(), "B3DPolyPolygon Remove outside range (!)");
378 
379         if(nCount)
380             mpPolyPolygon->remove(nIndex, nCount);
381     }
382 
383     void B3DPolyPolygon::clear()
384     {
385         mpPolyPolygon = DefaultPolyPolygon::get();
386     }
387 
388     bool B3DPolyPolygon::isClosed() const
389     {
390         bool bRetval(true);
391 
392         // PolyPOlygon is closed when all contained Polygons are closed or
393         // no Polygon exists.
394         for(sal_uInt32 a(0L); bRetval && a < mpPolyPolygon->count(); a++)
395         {
396             if(!(mpPolyPolygon->getB3DPolygon(a)).isClosed())
397             {
398                 bRetval = false;
399             }
400         }
401 
402         return bRetval;
403     }
404 
405     void B3DPolyPolygon::setClosed(bool bNew)
406     {
407         if(bNew != isClosed())
408             mpPolyPolygon->setClosed(bNew);
409     }
410 
411     void B3DPolyPolygon::flip()
412     {
413         mpPolyPolygon->flip();
414     }
415 
416     bool B3DPolyPolygon::hasDoublePoints() const
417     {
418         bool bRetval(false);
419 
420         for(sal_uInt32 a(0L); !bRetval && a < mpPolyPolygon->count(); a++)
421         {
422             if((mpPolyPolygon->getB3DPolygon(a)).hasDoublePoints())
423             {
424                 bRetval = true;
425             }
426         }
427 
428         return bRetval;
429     }
430 
431     void B3DPolyPolygon::removeDoublePoints()
432     {
433         if(hasDoublePoints())
434             mpPolyPolygon->removeDoublePoints();
435     }
436 
437     void B3DPolyPolygon::transform(const B3DHomMatrix& rMatrix)
438     {
439         if(mpPolyPolygon->count() && !rMatrix.isIdentity())
440         {
441             mpPolyPolygon->transform(rMatrix);
442         }
443     }
444 } // end of namespace basegfx
445 
446 // eof
447