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