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