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