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