Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <rtl/instance.hxx>
21 : #include <osl/diagnose.h>
22 : #include <basegfx/polygon/b3dpolypolygontools.hxx>
23 : #include <basegfx/range/b3drange.hxx>
24 : #include <basegfx/polygon/b3dpolypolygon.hxx>
25 : #include <basegfx/polygon/b3dpolygon.hxx>
26 : #include <basegfx/polygon/b3dpolygontools.hxx>
27 : #include <numeric>
28 : #include <basegfx/matrix/b3dhommatrix.hxx>
29 : #include <basegfx/numeric/ftools.hxx>
30 : #include <com/sun/star/drawing/DoubleSequence.hpp>
31 :
32 : // predefines
33 : #define nMinSegments sal_uInt32(1)
34 : #define nMaxSegments sal_uInt32(512)
35 :
36 : namespace basegfx
37 : {
38 : namespace tools
39 : {
40 : // B3DPolyPolygon tools
41 95278 : B3DRange getRange(const B3DPolyPolygon& rCandidate)
42 : {
43 95278 : B3DRange aRetval;
44 95278 : const sal_uInt32 nPolygonCount(rCandidate.count());
45 :
46 224842 : for(sal_uInt32 a(0L); a < nPolygonCount; a++)
47 : {
48 129564 : B3DPolygon aCandidate = rCandidate.getB3DPolygon(a);
49 129564 : aRetval.expand(getRange(aCandidate));
50 129564 : }
51 :
52 95278 : return aRetval;
53 : }
54 :
55 : namespace
56 : {
57 : struct theUnitCubePolyPolygon : public rtl::StaticWithInit<B3DPolyPolygon,
58 : theUnitCubePolyPolygon>
59 : {
60 0 : B3DPolyPolygon operator()()
61 : {
62 0 : B3DPolyPolygon aRetval;
63 0 : B3DPolygon aTemp;
64 0 : aTemp.append(B3DPoint(0.0, 0.0, 1.0));
65 0 : aTemp.append(B3DPoint(0.0, 1.0, 1.0));
66 0 : aTemp.append(B3DPoint(1.0, 1.0, 1.0));
67 0 : aTemp.append(B3DPoint(1.0, 0.0, 1.0));
68 0 : aTemp.setClosed(true);
69 0 : aRetval.append(aTemp);
70 :
71 0 : aTemp.clear();
72 0 : aTemp.append(B3DPoint(0.0, 0.0, 0.0));
73 0 : aTemp.append(B3DPoint(0.0, 1.0, 0.0));
74 0 : aTemp.append(B3DPoint(1.0, 1.0, 0.0));
75 0 : aTemp.append(B3DPoint(1.0, 0.0, 0.0));
76 0 : aTemp.setClosed(true);
77 0 : aRetval.append(aTemp);
78 :
79 0 : aTemp.clear();
80 0 : aTemp.append(B3DPoint(0.0, 0.0, 0.0));
81 0 : aTemp.append(B3DPoint(0.0, 0.0, 1.0));
82 0 : aRetval.append(aTemp);
83 :
84 0 : aTemp.clear();
85 0 : aTemp.append(B3DPoint(0.0, 1.0, 0.0));
86 0 : aTemp.append(B3DPoint(0.0, 1.0, 1.0));
87 0 : aRetval.append(aTemp);
88 :
89 0 : aTemp.clear();
90 0 : aTemp.append(B3DPoint(1.0, 1.0, 0.0));
91 0 : aTemp.append(B3DPoint(1.0, 1.0, 1.0));
92 0 : aRetval.append(aTemp);
93 :
94 0 : aTemp.clear();
95 0 : aTemp.append(B3DPoint(1.0, 0.0, 0.0));
96 0 : aTemp.append(B3DPoint(1.0, 0.0, 1.0));
97 0 : aRetval.append(aTemp);
98 0 : return aRetval;
99 : }
100 : };
101 : }
102 :
103 0 : B3DPolyPolygon createUnitCubePolyPolygon()
104 : {
105 0 : return theUnitCubePolyPolygon::get();
106 : }
107 :
108 : namespace
109 : {
110 : struct theUnitCubeFillPolyPolygon : public rtl::StaticWithInit<B3DPolyPolygon,
111 : theUnitCubeFillPolyPolygon>
112 : {
113 0 : B3DPolyPolygon operator()()
114 : {
115 0 : B3DPolyPolygon aRetval;
116 0 : B3DPolygon aTemp;
117 :
118 : // all points
119 0 : const B3DPoint A(0.0, 0.0, 0.0);
120 0 : const B3DPoint B(0.0, 1.0, 0.0);
121 0 : const B3DPoint C(1.0, 1.0, 0.0);
122 0 : const B3DPoint D(1.0, 0.0, 0.0);
123 0 : const B3DPoint E(0.0, 0.0, 1.0);
124 0 : const B3DPoint F(0.0, 1.0, 1.0);
125 0 : const B3DPoint G(1.0, 1.0, 1.0);
126 0 : const B3DPoint H(1.0, 0.0, 1.0);
127 :
128 : // create bottom
129 0 : aTemp.append(D);
130 0 : aTemp.append(A);
131 0 : aTemp.append(E);
132 0 : aTemp.append(H);
133 0 : aTemp.setClosed(true);
134 0 : aRetval.append(aTemp);
135 :
136 : // create front
137 0 : aTemp.clear();
138 0 : aTemp.append(B);
139 0 : aTemp.append(A);
140 0 : aTemp.append(D);
141 0 : aTemp.append(C);
142 0 : aTemp.setClosed(true);
143 0 : aRetval.append(aTemp);
144 :
145 : // create left
146 0 : aTemp.clear();
147 0 : aTemp.append(E);
148 0 : aTemp.append(A);
149 0 : aTemp.append(B);
150 0 : aTemp.append(F);
151 0 : aTemp.setClosed(true);
152 0 : aRetval.append(aTemp);
153 :
154 : // create top
155 0 : aTemp.clear();
156 0 : aTemp.append(C);
157 0 : aTemp.append(G);
158 0 : aTemp.append(F);
159 0 : aTemp.append(B);
160 0 : aTemp.setClosed(true);
161 0 : aRetval.append(aTemp);
162 :
163 : // create right
164 0 : aTemp.clear();
165 0 : aTemp.append(H);
166 0 : aTemp.append(G);
167 0 : aTemp.append(C);
168 0 : aTemp.append(D);
169 0 : aTemp.setClosed(true);
170 0 : aRetval.append(aTemp);
171 :
172 : // create back
173 0 : aTemp.clear();
174 0 : aTemp.append(F);
175 0 : aTemp.append(G);
176 0 : aTemp.append(H);
177 0 : aTemp.append(E);
178 0 : aTemp.setClosed(true);
179 0 : aRetval.append(aTemp);
180 0 : return aRetval;
181 : }
182 : };
183 : }
184 :
185 0 : B3DPolyPolygon createUnitCubeFillPolyPolygon()
186 : {
187 0 : return theUnitCubeFillPolyPolygon::get();
188 : }
189 :
190 0 : B3DPolyPolygon createCubePolyPolygonFromB3DRange( const B3DRange& rRange)
191 : {
192 0 : B3DPolyPolygon aRetval;
193 :
194 0 : if(!rRange.isEmpty())
195 : {
196 0 : aRetval = createUnitCubePolyPolygon();
197 0 : B3DHomMatrix aTrans;
198 0 : aTrans.scale(rRange.getWidth(), rRange.getHeight(), rRange.getDepth());
199 0 : aTrans.translate(rRange.getMinX(), rRange.getMinY(), rRange.getMinZ());
200 0 : aRetval.transform(aTrans);
201 0 : aRetval.removeDoublePoints();
202 : }
203 :
204 0 : return aRetval;
205 : }
206 :
207 0 : B3DPolyPolygon createCubeFillPolyPolygonFromB3DRange( const B3DRange& rRange)
208 : {
209 0 : B3DPolyPolygon aRetval;
210 :
211 0 : if(!rRange.isEmpty())
212 : {
213 0 : aRetval = createUnitCubeFillPolyPolygon();
214 0 : B3DHomMatrix aTrans;
215 0 : aTrans.scale(rRange.getWidth(), rRange.getHeight(), rRange.getDepth());
216 0 : aTrans.translate(rRange.getMinX(), rRange.getMinY(), rRange.getMinZ());
217 0 : aRetval.transform(aTrans);
218 0 : aRetval.removeDoublePoints();
219 : }
220 :
221 0 : return aRetval;
222 : }
223 :
224 : // helper for getting the 3D Point from given cartesian coordiantes. fHor is defined from
225 : // [F_PI2 .. -F_PI2], fVer from [0.0 .. F_2PI]
226 4288 : inline B3DPoint getPointFromCartesian(double fHor, double fVer)
227 : {
228 4288 : const double fCosVer(cos(fVer));
229 4288 : return B3DPoint(fCosVer * cos(fHor), sin(fVer), fCosVer * -sin(fHor));
230 : }
231 :
232 0 : B3DPolyPolygon createUnitSpherePolyPolygon(
233 : sal_uInt32 nHorSeg, sal_uInt32 nVerSeg,
234 : double fVerStart, double fVerStop,
235 : double fHorStart, double fHorStop)
236 : {
237 0 : B3DPolyPolygon aRetval;
238 : sal_uInt32 a, b;
239 :
240 0 : if(!nHorSeg)
241 : {
242 0 : nHorSeg = fround(fabs(fHorStop - fHorStart) / (F_2PI / 24.0));
243 : }
244 :
245 : // min/max limitations
246 0 : nHorSeg = ::std::min(nMaxSegments, ::std::max(nMinSegments, nHorSeg));
247 :
248 0 : if(!nVerSeg)
249 : {
250 0 : nVerSeg = fround(fabs(fVerStop - fVerStart) / (F_2PI / 24.0));
251 : }
252 :
253 : // min/max limitations
254 0 : nVerSeg = ::std::min(nMaxSegments, ::std::max(nMinSegments, nVerSeg));
255 :
256 : // create constants
257 0 : const double fVerDiffPerStep((fVerStop - fVerStart) / (double)nVerSeg);
258 0 : const double fHorDiffPerStep((fHorStop - fHorStart) / (double)nHorSeg);
259 0 : bool bHorClosed(fTools::equal(fHorStop - fHorStart, F_2PI));
260 0 : bool bVerFromTop(fTools::equal(fVerStart, F_PI2));
261 0 : bool bVerToBottom(fTools::equal(fVerStop, -F_PI2));
262 :
263 : // create horizontal rings
264 0 : const sal_uInt32 nLoopVerInit(bVerFromTop ? 1L : 0L);
265 0 : const sal_uInt32 nLoopVerLimit(bVerToBottom ? nVerSeg : nVerSeg + 1L);
266 0 : const sal_uInt32 nLoopHorLimit(bHorClosed ? nHorSeg : nHorSeg + 1L);
267 :
268 0 : for(a = nLoopVerInit; a < nLoopVerLimit; a++)
269 : {
270 0 : const double fVer(fVerStart + ((double)(a) * fVerDiffPerStep));
271 0 : B3DPolygon aNew;
272 :
273 0 : for(b = 0L; b < nLoopHorLimit; b++)
274 : {
275 0 : const double fHor(fHorStart + ((double)(b) * fHorDiffPerStep));
276 0 : aNew.append(getPointFromCartesian(fHor, fVer));
277 : }
278 :
279 0 : aNew.setClosed(bHorClosed);
280 0 : aRetval.append(aNew);
281 0 : }
282 :
283 : // create vertical half-rings
284 0 : for(a = 0L; a < nLoopHorLimit; a++)
285 : {
286 0 : const double fHor(fHorStart + ((double)(a) * fHorDiffPerStep));
287 0 : B3DPolygon aNew;
288 :
289 0 : if(bVerFromTop)
290 : {
291 0 : aNew.append(B3DPoint(0.0, 1.0, 0.0));
292 : }
293 :
294 0 : for(b = nLoopVerInit; b < nLoopVerLimit; b++)
295 : {
296 0 : const double fVer(fVerStart + ((double)(b) * fVerDiffPerStep));
297 0 : aNew.append(getPointFromCartesian(fHor, fVer));
298 : }
299 :
300 0 : if(bVerToBottom)
301 : {
302 0 : aNew.append(B3DPoint(0.0, -1.0, 0.0));
303 : }
304 :
305 0 : aRetval.append(aNew);
306 0 : }
307 :
308 0 : return aRetval;
309 : }
310 :
311 0 : B3DPolyPolygon createSpherePolyPolygonFromB3DRange( const B3DRange& rRange,
312 : sal_uInt32 nHorSeg, sal_uInt32 nVerSeg,
313 : double fVerStart, double fVerStop,
314 : double fHorStart, double fHorStop)
315 : {
316 0 : B3DPolyPolygon aRetval(createUnitSpherePolyPolygon(nHorSeg, nVerSeg, fVerStart, fVerStop, fHorStart, fHorStop));
317 :
318 0 : if(aRetval.count())
319 : {
320 : // move and scale whole construct which is now in [-1.0 .. 1.0] in all directions
321 0 : B3DHomMatrix aTrans;
322 0 : aTrans.translate(1.0, 1.0, 1.0);
323 0 : aTrans.scale(rRange.getWidth() / 2.0, rRange.getHeight() / 2.0, rRange.getDepth() / 2.0);
324 0 : aTrans.translate(rRange.getMinX(), rRange.getMinY(), rRange.getMinZ());
325 0 : aRetval.transform(aTrans);
326 : }
327 :
328 0 : return aRetval;
329 : }
330 :
331 134 : B3DPolyPolygon createUnitSphereFillPolyPolygon(
332 : sal_uInt32 nHorSeg, sal_uInt32 nVerSeg,
333 : bool bNormals,
334 : double fVerStart, double fVerStop,
335 : double fHorStart, double fHorStop)
336 : {
337 134 : B3DPolyPolygon aRetval;
338 :
339 134 : if(!nHorSeg)
340 : {
341 0 : nHorSeg = fround(fabs(fHorStop - fHorStart) / (F_2PI / 24.0));
342 : }
343 :
344 : // min/max limitations
345 134 : nHorSeg = ::std::min(nMaxSegments, ::std::max(nMinSegments, nHorSeg));
346 :
347 134 : if(!nVerSeg)
348 : {
349 0 : nVerSeg = fround(fabs(fVerStop - fVerStart) / (F_2PI / 24.0));
350 : }
351 :
352 : // min/max limitations
353 134 : nVerSeg = ::std::min(nMaxSegments, ::std::max(nMinSegments, nVerSeg));
354 :
355 : // vertical loop
356 670 : for(sal_uInt32 a(0L); a < nVerSeg; a++)
357 : {
358 536 : const double fVer1(fVerStart + (((fVerStop - fVerStart) * a) / nVerSeg));
359 536 : const double fVer2(fVerStart + (((fVerStop - fVerStart) * (a + 1)) / nVerSeg));
360 :
361 : // horizontal loop
362 1608 : for(sal_uInt32 b(0L); b < nHorSeg; b++)
363 : {
364 1072 : const double fHor1(fHorStart + (((fHorStop - fHorStart) * b) / nHorSeg));
365 1072 : const double fHor2(fHorStart + (((fHorStop - fHorStart) * (b + 1)) / nHorSeg));
366 1072 : B3DPolygon aNew;
367 :
368 1072 : aNew.append(getPointFromCartesian(fHor1, fVer1));
369 1072 : aNew.append(getPointFromCartesian(fHor2, fVer1));
370 1072 : aNew.append(getPointFromCartesian(fHor2, fVer2));
371 1072 : aNew.append(getPointFromCartesian(fHor1, fVer2));
372 :
373 1072 : if(bNormals)
374 : {
375 5360 : for(sal_uInt32 c(0L); c < aNew.count(); c++)
376 : {
377 4288 : aNew.setNormal(c, ::basegfx::B3DVector(aNew.getB3DPoint(c)));
378 : }
379 : }
380 :
381 1072 : aNew.setClosed(true);
382 1072 : aRetval.append(aNew);
383 1072 : }
384 : }
385 :
386 134 : return aRetval;
387 : }
388 :
389 0 : B3DPolyPolygon createSphereFillPolyPolygonFromB3DRange( const B3DRange& rRange,
390 : sal_uInt32 nHorSeg, sal_uInt32 nVerSeg,
391 : bool bNormals,
392 : double fVerStart, double fVerStop,
393 : double fHorStart, double fHorStop)
394 : {
395 0 : B3DPolyPolygon aRetval(createUnitSphereFillPolyPolygon(nHorSeg, nVerSeg, bNormals, fVerStart, fVerStop, fHorStart, fHorStop));
396 :
397 0 : if(aRetval.count())
398 : {
399 : // move and scale whole construct which is now in [-1.0 .. 1.0] in all directions
400 0 : B3DHomMatrix aTrans;
401 0 : aTrans.translate(1.0, 1.0, 1.0);
402 0 : aTrans.scale(rRange.getWidth() / 2.0, rRange.getHeight() / 2.0, rRange.getDepth() / 2.0);
403 0 : aTrans.translate(rRange.getMinX(), rRange.getMinY(), rRange.getMinZ());
404 0 : aRetval.transform(aTrans);
405 : }
406 :
407 0 : return aRetval;
408 : }
409 :
410 0 : B3DPolyPolygon applyDefaultNormalsSphere( const B3DPolyPolygon& rCandidate, const B3DPoint& rCenter)
411 : {
412 0 : B3DPolyPolygon aRetval;
413 :
414 0 : for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
415 : {
416 0 : aRetval.append(applyDefaultNormalsSphere(rCandidate.getB3DPolygon(a), rCenter));
417 : }
418 :
419 0 : return aRetval;
420 : }
421 :
422 0 : B3DPolyPolygon invertNormals( const B3DPolyPolygon& rCandidate)
423 : {
424 0 : B3DPolyPolygon aRetval;
425 :
426 0 : for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
427 : {
428 0 : aRetval.append(invertNormals(rCandidate.getB3DPolygon(a)));
429 : }
430 :
431 0 : return aRetval;
432 : }
433 :
434 462 : B3DPolyPolygon applyDefaultTextureCoordinatesParallel( const B3DPolyPolygon& rCandidate, const B3DRange& rRange, bool bChangeX, bool bChangeY)
435 : {
436 462 : B3DPolyPolygon aRetval;
437 :
438 924 : for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
439 : {
440 462 : aRetval.append(applyDefaultTextureCoordinatesParallel(rCandidate.getB3DPolygon(a), rRange, bChangeX, bChangeY));
441 : }
442 :
443 462 : return aRetval;
444 : }
445 :
446 0 : B3DPolyPolygon applyDefaultTextureCoordinatesSphere( const B3DPolyPolygon& rCandidate, const B3DPoint& rCenter, bool bChangeX, bool bChangeY)
447 : {
448 0 : B3DPolyPolygon aRetval;
449 :
450 0 : for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
451 : {
452 0 : aRetval.append(applyDefaultTextureCoordinatesSphere(rCandidate.getB3DPolygon(a), rCenter, bChangeX, bChangeY));
453 : }
454 :
455 0 : return aRetval;
456 : }
457 :
458 0 : bool isInside(const B3DPolyPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder)
459 : {
460 0 : const sal_uInt32 nPolygonCount(rCandidate.count());
461 :
462 0 : if(1L == nPolygonCount)
463 : {
464 0 : return isInside(rCandidate.getB3DPolygon(0), rPoint, bWithBorder);
465 : }
466 : else
467 : {
468 0 : sal_Int32 nInsideCount(0);
469 :
470 0 : for(sal_uInt32 a(0); a < nPolygonCount; a++)
471 : {
472 0 : const B3DPolygon aPolygon(rCandidate.getB3DPolygon(a));
473 0 : const bool bInside(isInside(aPolygon, rPoint, bWithBorder));
474 :
475 0 : if(bInside)
476 : {
477 0 : nInsideCount++;
478 : }
479 0 : }
480 :
481 0 : return (nInsideCount % 2L);
482 : }
483 : }
484 :
485 : /// converters for com::sun::star::drawing::PolyPolygonShape3D
486 0 : B3DPolyPolygon UnoPolyPolygonShape3DToB3DPolyPolygon(
487 : const com::sun::star::drawing::PolyPolygonShape3D& rPolyPolygonShape3DSource,
488 : bool bCheckClosed)
489 : {
490 0 : B3DPolyPolygon aRetval;
491 0 : const sal_Int32 nOuterSequenceCount(rPolyPolygonShape3DSource.SequenceX.getLength());
492 :
493 0 : if(nOuterSequenceCount)
494 : {
495 : OSL_ENSURE(nOuterSequenceCount == rPolyPolygonShape3DSource.SequenceY.getLength()
496 : && nOuterSequenceCount == rPolyPolygonShape3DSource.SequenceZ.getLength(),
497 : "UnoPolyPolygonShape3DToB3DPolygon: Not all double sequences have the same length (!)");
498 :
499 0 : const com::sun::star::drawing::DoubleSequence* pInnerSequenceX = rPolyPolygonShape3DSource.SequenceX.getConstArray();
500 0 : const com::sun::star::drawing::DoubleSequence* pInnerSequenceY = rPolyPolygonShape3DSource.SequenceY.getConstArray();
501 0 : const com::sun::star::drawing::DoubleSequence* pInnerSequenceZ = rPolyPolygonShape3DSource.SequenceZ.getConstArray();
502 :
503 0 : for(sal_Int32 a(0); a < nOuterSequenceCount; a++)
504 : {
505 0 : basegfx::B3DPolygon aNewPolygon;
506 0 : const sal_Int32 nInnerSequenceCount(pInnerSequenceX->getLength());
507 : OSL_ENSURE(nInnerSequenceCount == pInnerSequenceY->getLength()
508 : && nInnerSequenceCount == pInnerSequenceZ->getLength(),
509 : "UnoPolyPolygonShape3DToB3DPolygon: Not all double sequences have the same length (!)");
510 :
511 0 : const double* pArrayX = pInnerSequenceX->getConstArray();
512 0 : const double* pArrayY = pInnerSequenceY->getConstArray();
513 0 : const double* pArrayZ = pInnerSequenceZ->getConstArray();
514 :
515 0 : for(sal_Int32 b(0); b < nInnerSequenceCount; b++)
516 : {
517 0 : aNewPolygon.append(basegfx::B3DPoint(*pArrayX++,*pArrayY++,*pArrayZ++));
518 : }
519 :
520 0 : pInnerSequenceX++;
521 0 : pInnerSequenceY++;
522 0 : pInnerSequenceZ++;
523 :
524 : // #i101520# correction is needed for imported polygons of old format,
525 : // see callers
526 0 : if(bCheckClosed)
527 : {
528 0 : basegfx::tools::checkClosed(aNewPolygon);
529 : }
530 :
531 0 : aRetval.append(aNewPolygon);
532 0 : }
533 : }
534 :
535 0 : return aRetval;
536 : }
537 :
538 0 : void B3DPolyPolygonToUnoPolyPolygonShape3D(
539 : const B3DPolyPolygon& rPolyPolygonSource,
540 : com::sun::star::drawing::PolyPolygonShape3D& rPolyPolygonShape3DRetval)
541 : {
542 0 : const sal_uInt32 nPolygonCount(rPolyPolygonSource.count());
543 :
544 0 : if(nPolygonCount)
545 : {
546 0 : rPolyPolygonShape3DRetval.SequenceX.realloc(nPolygonCount);
547 0 : rPolyPolygonShape3DRetval.SequenceY.realloc(nPolygonCount);
548 0 : rPolyPolygonShape3DRetval.SequenceZ.realloc(nPolygonCount);
549 :
550 0 : com::sun::star::drawing::DoubleSequence* pOuterSequenceX = rPolyPolygonShape3DRetval.SequenceX.getArray();
551 0 : com::sun::star::drawing::DoubleSequence* pOuterSequenceY = rPolyPolygonShape3DRetval.SequenceY.getArray();
552 0 : com::sun::star::drawing::DoubleSequence* pOuterSequenceZ = rPolyPolygonShape3DRetval.SequenceZ.getArray();
553 :
554 0 : for(sal_uInt32 a(0); a < nPolygonCount; a++)
555 : {
556 0 : const basegfx::B3DPolygon aPoly(rPolyPolygonSource.getB3DPolygon(a));
557 0 : const sal_uInt32 nPointCount(aPoly.count());
558 :
559 0 : if(nPointCount)
560 : {
561 0 : const bool bIsClosed(aPoly.isClosed());
562 0 : const sal_uInt32 nTargetCount(bIsClosed ? nPointCount + 1 : nPointCount);
563 0 : pOuterSequenceX->realloc(nTargetCount);
564 0 : pOuterSequenceY->realloc(nTargetCount);
565 0 : pOuterSequenceZ->realloc(nTargetCount);
566 :
567 0 : double* pInnerSequenceX = pOuterSequenceX->getArray();
568 0 : double* pInnerSequenceY = pOuterSequenceY->getArray();
569 0 : double* pInnerSequenceZ = pOuterSequenceZ->getArray();
570 :
571 0 : for(sal_uInt32 b(0); b < nPointCount; b++)
572 : {
573 0 : const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(b));
574 :
575 0 : *pInnerSequenceX++ = aPoint.getX();
576 0 : *pInnerSequenceY++ = aPoint.getY();
577 0 : *pInnerSequenceZ++ = aPoint.getZ();
578 0 : }
579 :
580 0 : if(bIsClosed)
581 : {
582 0 : const basegfx::B3DPoint aPoint(aPoly.getB3DPoint(0));
583 :
584 0 : *pInnerSequenceX++ = aPoint.getX();
585 0 : *pInnerSequenceY++ = aPoint.getY();
586 0 : *pInnerSequenceZ++ = aPoint.getZ();
587 : }
588 : }
589 : else
590 : {
591 0 : pOuterSequenceX->realloc(0);
592 0 : pOuterSequenceY->realloc(0);
593 0 : pOuterSequenceZ->realloc(0);
594 : }
595 :
596 0 : pOuterSequenceX++;
597 0 : pOuterSequenceY++;
598 0 : pOuterSequenceZ++;
599 0 : }
600 : }
601 : else
602 : {
603 0 : rPolyPolygonShape3DRetval.SequenceX.realloc(0);
604 0 : rPolyPolygonShape3DRetval.SequenceY.realloc(0);
605 0 : rPolyPolygonShape3DRetval.SequenceZ.realloc(0);
606 : }
607 0 : }
608 :
609 : } // end of namespace tools
610 : } // end of namespace basegfx
611 :
612 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|