Geant4 Cross Reference |
1 // Created by Laurent Garnier on Fri Jan 30 2004. 2 3 //#define TOOLS_HATCHER_DEBUG 4 5 #ifdef TOOLS_HATCHER_DEBUG 6 #include <cstdio> 7 #endif 8 9 namespace tools { 10 11 ////////////////////////////////////////////////////////////////////////////// 12 // test if the polygone given is correct for hatching 13 // return FALSE if : 14 // - All points are not in the same plan 15 // - Number of points <3 16 // - Offset point is not in the same plan 17 // - There is less than three different points 18 // - The vector from point[0],point[1] is colinear to point[0],lastPoint 19 ////////////////////////////////////////////////////////////////////////////// 20 21 inline bool hatcher::check_polyline(vec3f* listPoints,unsigned int aNumber){ 22 23 unsigned int firstOffset =0; 24 25 if ( listPoints[0].equals(listPoints[1],FLT_EPSILON*FLT_EPSILON*10)) { 26 firstOffset =1; 27 } 28 29 if ( listPoints[0].equals(listPoints[aNumber-1],FLT_EPSILON*FLT_EPSILON*10)) { 30 aNumber --; 31 } 32 33 if ((int)aNumber-firstOffset <3) { 34 #ifdef TOOLS_HATCHER_DEBUG 35 ::printf("hatcher::check_polyline : ERROR the polygone you give have not enought points!\n\n"); 36 #endif 37 return false; 38 } 39 40 41 // use to test the polyline and to build the shift vector. A is the first point, 42 // B second and C the last (in fact, the last-1)! 43 vec3f AB,AC; 44 AB.setValue(listPoints[1+firstOffset].getValue()[0]-listPoints[0].getValue()[0], 45 listPoints[1+firstOffset].getValue()[1]-listPoints[0].getValue()[1], 46 listPoints[1+firstOffset].getValue()[2]-listPoints[0].getValue()[2]); // Vector A->B 47 48 49 fResolveResult = RESOLVE_COLINEAR; 50 unsigned int test = aNumber; 51 while ((fResolveResult !=0) && (test>2+firstOffset)) { 52 test--; 53 AC.setValue(listPoints[test].getValue()[0]-listPoints[0].getValue()[0], 54 listPoints[test].getValue()[1]-listPoints[0].getValue()[1], 55 listPoints[test].getValue()[2]-listPoints[0].getValue()[2]); 56 57 // test if AB != AC*i 58 resolve_system( AB, 59 AC, 60 vec3f(.0f,.0f,.0f)); 61 } 62 if (fResolveResult == RESOLVE_COLINEAR) { 63 #ifdef TOOLS_HATCHER_DEBUG 64 ::printf("hatcher::check_polyline : ERROR all the point you give are colinear!\n\n"); 65 for (unsigned int a =0;a<aNumber;a++) { 66 printf(" %f %f %f \n",listPoints[a][0],listPoints[a][1],listPoints[a][2]); } 67 #endif 68 return false; 69 } 70 71 /////////////////////////////////////////////////////////////// 72 // test if all points of the polyline are on the same plan 73 /////////////////////////////////////////////////////////////// 74 75 int falsePoints =0; 76 for (unsigned int a=2+firstOffset;a<aNumber;a++) { 77 resolve_system( AB, 78 AC, 79 vec3f((listPoints[a].getValue()[0]-listPoints[0].getValue()[0]), 80 (listPoints[a].getValue()[1]-listPoints[0].getValue()[1]), 81 (listPoints[a].getValue()[2]-listPoints[0].getValue()[2]))); 82 if (fResolveResult != 0){ 83 falsePoints++; 84 } 85 } 86 87 if (falsePoints !=0) { 88 #ifdef TOOLS_HATCHER_DEBUG 89 ::printf("hatcher::check_polyline : ERROR there is %d points on the polyline witch are not on the same plan!\n\n",falsePoints); 90 #endif 91 return false; 92 } 93 94 // test offset 95 if (! ((fOffset[0] == FLT_MAX) && (fOffset[1] == FLT_MAX) && (fOffset[2] == FLT_MAX))){ 96 resolve_system( AB, 97 AC, 98 fOffset-listPoints[0]); 99 if (fResolveResult != 0) { 100 #ifdef TOOLS_HATCHER_DEBUG 101 ::printf("hatcher::check_polyline : ERROR Offset vector has to be on the same plan!\n\n"); 102 #endif 103 return false; 104 } 105 } 106 return true; 107 } 108 109 110 ////////////////////////////////////////////////////////////////////////////// 111 // draw the hatch into the polyline bounding box giving in argument 112 // return false if : 113 // - All points are not in the same plan 114 // - There is a precision error on one or more point 115 // Compute a first sequence of hacth, store results, compute a second sequence 116 // and match all results to get the correct strip points 117 ////////////////////////////////////////////////////////////////////////////// 118 /** Compute stripWidth 119 * We have to use the conflictNumHatchLineTab, hatchNumber,listHatchStartPoint tables 120 * also the HatchShiftToMacthPoint tab. 121 * and the hatch line just compute below 122 * We try to made a polyline with all points witch are on the current hatch and on the next hacth 123 * (distant of stripwidth form current hatch) 124 * conflictNumHatchLineTab give us something like this for current and next hatch 125 * current next current next 126 * 4 4 if we consider that ,4 ,4 127 * 0 5 we know the compute hatch '0 '5 128 * 1 3 lines, we could link ,1 ,3 129 * 3 2 some of theses line numbers '3 '2 130 * 5 so ->> ,5 131 * 2 '2 132 * And we have to add some points when HatchShiftToMacthPoint(point) is between current 133 * and next hatch : We add a point B on intersection of line 0 and 1 134 * current next current next 135 * ,4 ,4 136 * '0 B(0,1) '5 137 * ,1 138 * '3 ,3 139 * ,5 '2 140 * '2 141 * 142 * Now we have to match a way to traverse all of theses lines. We have 3 solutions to go from 143 * one line to another : 144 * - go to the next point if there is one between current and next hatch 145 * - go to the same line but on another hatch 146 * - go to the next tach point 147 * If there is no solution, we have to close the polyline strip and go to another point until 148 * all are compute 149 */ 150 151 /** first, we have to match 7 different cases 152 * 1- all strip hatch are entirely in the polyline 153 * 2- the first strip begin before the polyline and the last end in the polyline 154 * 3- the first strip begin before the polyline and the last ends after 155 * 4- the first strip is entierly in the polyline and the last ends after 156 * 5- the strip has only an intersection with the second hatch sequence (if it has only an intersection 157 * with the first hatch sequence, it is case 2 158 * 6- the strip has a full intersection 159 * 7- the strip has no intersection ! 160 */ 161 162 inline bool hatcher::compute_polyline (vec3f* tabPoints,unsigned int aNumber) { 163 std::vector<vec3f> firstComputePoints; // copy first Points in 164 std::vector<vec3f> secondComputePoints; // copy first Points in 165 std::vector<bool> firstComputePointsEnable; // table of already compute points for first hatch 166 std::vector<bool> secondComputePointsEnable;// table of already compute points for second hatch 167 std::vector< std::vector<int> > firstComputeConflictNumHatchLineTab; // copy firstComputeConflictNumHatchLineTab in 168 169 int firstComputeFirstNumHatch =0; 170 unsigned int firstComputeNumberHatchToDraw =0; 171 float firstHatchShiftToMatchFirstPoint = FLT_MAX; // use in one case when there is no intersection points: to test we have to fill all the polygone 172 float secondHatchShiftToMatchFirstPoint = FLT_MAX; // use in one case when there is no intersection points: to test we have to fill all the polygone 173 //call compute for first set of hatch 174 if ( !compute_single_polyline (tabPoints,aNumber)) 175 return false; 176 if (fStripWidth ==0) 177 return true; 178 179 180 //save values 181 for (unsigned int a =0;a<fPoints.size();a++){ 182 firstComputePoints.push_back(fPoints[a]); 183 } 184 185 firstComputeConflictNumHatchLineTab.resize(fConflictNumHatchLineTab.size()); 186 for (unsigned int a=0;a<fConflictNumHatchLineTab.size();a++){ 187 firstComputeConflictNumHatchLineTab[a].clear(); 188 for (unsigned int b=0;b<fConflictNumHatchLineTab[a].size();b++){ 189 firstComputeConflictNumHatchLineTab[a].push_back(fConflictNumHatchLineTab[a][b]); 190 } 191 } 192 firstComputeFirstNumHatch = fFirstNumHatch; 193 firstComputeNumberHatchToDraw = fNumberHatchToDraw; 194 firstHatchShiftToMatchFirstPoint = fHatchShiftToMatchPointVec[0]; 195 //change the offset vector 196 fOffset = fOffset+fShiftVec*fStripWidth; 197 198 //call compute for second set of hatch 199 if ( !compute_single_polyline (tabPoints,aNumber)) 200 return false; 201 202 //save values 203 for (unsigned int a =0;a<fPoints.size();a++){ 204 secondComputePoints.push_back(fPoints[a]); 205 } 206 207 secondHatchShiftToMatchFirstPoint = fHatchShiftToMatchPointVec[0]; 208 209 210 // initialize values 211 fPoints.clear(); 212 fVertices.clear(); 213 214 int specialCase=1; 215 216 //first hatch, case 1 217 if ((firstComputeFirstNumHatch == fFirstNumHatch) && (firstComputeNumberHatchToDraw == fNumberHatchToDraw) && (firstComputeNumberHatchToDraw !=0)) { 218 specialCase =1; 219 } 220 //first hatch, case 2 221 else if ((firstComputeFirstNumHatch > fFirstNumHatch) && (firstComputeNumberHatchToDraw < fNumberHatchToDraw) && (firstComputeNumberHatchToDraw !=0)) { 222 //insert a empty element at the beginning 223 firstComputeConflictNumHatchLineTab.insert(firstComputeConflictNumHatchLineTab.begin(), firstComputeConflictNumHatchLineTab.back()); 224 firstComputeConflictNumHatchLineTab[0].resize(0); 225 firstComputeFirstNumHatch--; 226 firstComputeNumberHatchToDraw ++; 227 firstComputeConflictNumHatchLineTab[0].clear(); 228 specialCase =2; 229 230 } //second hatch, case 3 231 else if (((firstComputeFirstNumHatch > fFirstNumHatch) && (firstComputeNumberHatchToDraw == fNumberHatchToDraw)) && (firstComputeNumberHatchToDraw !=0)) { 232 //insert a empty element at the beginning 233 firstComputeConflictNumHatchLineTab.insert(firstComputeConflictNumHatchLineTab.begin(),firstComputeConflictNumHatchLineTab.back()); 234 firstComputeConflictNumHatchLineTab[0].resize(0); 235 firstComputeConflictNumHatchLineTab[0].clear(); 236 //insert a empty element at the end 237 fConflictNumHatchLineTab.push_back(firstComputeConflictNumHatchLineTab.back()); 238 fConflictNumHatchLineTab.back().resize(0); 239 fConflictNumHatchLineTab.back().clear(); 240 firstComputeFirstNumHatch--; 241 firstComputeNumberHatchToDraw ++; 242 specialCase =3; 243 } //second hatch, case 4 244 else if (((firstComputeFirstNumHatch == fFirstNumHatch) && (firstComputeNumberHatchToDraw > fNumberHatchToDraw)) && (firstComputeNumberHatchToDraw !=0)) { 245 //insert a empty element at the end 246 fConflictNumHatchLineTab.push_back(firstComputeConflictNumHatchLineTab.back()); 247 fConflictNumHatchLineTab.back().resize(0); 248 fConflictNumHatchLineTab.back().clear(); 249 specialCase =4; 250 251 } //second hatch, case 5 252 else if ((firstComputeNumberHatchToDraw ==0) && (fNumberHatchToDraw !=0)) { 253 //insert a empty element at the beginning 254 firstComputeConflictNumHatchLineTab.insert(firstComputeConflictNumHatchLineTab.begin(),firstComputeConflictNumHatchLineTab.back()); 255 firstComputeConflictNumHatchLineTab[0].resize(0); 256 firstComputeConflictNumHatchLineTab[0].clear(); 257 firstComputeNumberHatchToDraw ++; 258 specialCase =5; 259 260 } //second hatch, case 6 261 else if (floorf(firstHatchShiftToMatchFirstPoint) != floorf(secondHatchShiftToMatchFirstPoint)) { 262 specialCase =6; 263 264 //fill all the polygone ! 265 fVertices.push_back(aNumber); 266 for (unsigned int a =0;a<aNumber;a++){ 267 fPoints.push_back(tabPoints[a]); 268 } 269 return true; 270 } 271 else if (floorf(firstHatchShiftToMatchFirstPoint) == floorf(secondHatchShiftToMatchFirstPoint)) { 272 specialCase =7; 273 return true; 274 } else { 275 #ifdef TOOLS_HATCHER_DEBUG 276 ::printf("hatcher::drawStripPolyline : WARNING there is a case witch was not done in the algotithm...possibly some drawing problems.\n\n"); 277 #endif 278 279 } 280 281 282 bool result; 283 bool find; // temp variable 284 int firstHatchComputePoint = 0; //first point number 285 int secondHatchComputePoint = 0; //first point number 286 unsigned int lineNumber; 287 unsigned int firstPointTabInd =0; 288 unsigned int secondPointTabInd=0; 289 unsigned int currentHatch; // 0 is first, 1 is second, 2 is one or other !! 290 unsigned int solution; //default for beginning 291 unsigned int indTmp; 292 unsigned int oldSolution; 293 for (unsigned int indHatch =0;indHatch<firstComputeNumberHatchToDraw;indHatch++) { 294 295 296 currentHatch =0; // 0 is first, 1 is second 297 solution =99; //default for beginning 298 indTmp = 0; 299 lineNumber = 0; 300 secondComputePointsEnable.clear(); 301 firstComputePointsEnable.clear(); 302 for (unsigned int a=0;a<firstComputeConflictNumHatchLineTab[indHatch].size();a++){ 303 firstComputePointsEnable.push_back(false);} 304 for (unsigned int a=0;a<fConflictNumHatchLineTab[indHatch].size();a++){ 305 secondComputePointsEnable.push_back(false);} 306 307 if ((indHatch == 0) && ((specialCase ==2) || (specialCase ==3) || (specialCase ==5))) { 308 for (unsigned int a=0;a<firstComputeConflictNumHatchLineTab[indHatch].size();a++){ 309 firstComputePointsEnable[a] = true; 310 } 311 } 312 if ((indHatch == (firstComputeNumberHatchToDraw-1)) && ((specialCase ==3) || (specialCase ==4))) { 313 for (unsigned int a=0;a<fConflictNumHatchLineTab[indHatch].size();a++){ 314 secondComputePointsEnable[a] = true; 315 } 316 } 317 318 result = false; 319 while (result == false) { 320 321 322 //find a uncompute point for this set of hatch 323 result =true; 324 unsigned int b=0; 325 while ((result == true) && (b<firstComputeConflictNumHatchLineTab[indHatch].size())) { 326 if (firstComputePointsEnable[b] == false) { 327 result =false; 328 firstHatchComputePoint = b; 329 lineNumber = firstComputeConflictNumHatchLineTab[indHatch][b]; 330 fPoints.push_back(firstComputePoints[b+firstPointTabInd]); 331 fVertices.push_back(1); 332 firstComputePointsEnable[b] = true; 333 currentHatch = 0; 334 } 335 b++; 336 } 337 if (result ==true) { 338 //find a uncompute point for this set of hatch 339 340 while ((result == true) && (b<fConflictNumHatchLineTab[indHatch].size())) { 341 if (secondComputePointsEnable[b] == false) { 342 result =false; 343 secondHatchComputePoint = b; 344 lineNumber = fConflictNumHatchLineTab[indHatch][b]; 345 fPoints.push_back(secondComputePoints[b+secondPointTabInd]); 346 fVertices.push_back(1); 347 secondComputePointsEnable[b] = true; 348 currentHatch = 1; 349 } 350 b++; 351 } 352 } 353 if (result == true) { 354 } 355 solution =99; // to enter in the while 356 while (solution !=0) { 357 oldSolution = solution; 358 solution =0; //default 359 // get the line number for this point 360 /** Now we have to match a way to traverse all of theses lines. We have 3 solutions to go from 361 * one line to another : 362 * - go to the next point if there is one between current and next hatch 363 * - go to the same line but on another hatch 364 * - go to the next hatch point 365 */ 366 if (currentHatch != 1) { 367 368 if (oldSolution != 3) { // could go to first solution 369 int index =0; 370 if ((firstHatchComputePoint % 2 == 0) && (firstComputePointsEnable[firstHatchComputePoint+1] == false)) index =1; 371 else if ((firstHatchComputePoint % 2 != 0) && (firstComputePointsEnable[firstHatchComputePoint-1] == false)) index = -1; 372 if (index !=0) { 373 solution = 1; 374 oldSolution = 0; 375 firstHatchComputePoint = firstHatchComputePoint+index; 376 fPoints.push_back(firstComputePoints[firstHatchComputePoint+firstPointTabInd]); 377 fVertices.back() ++; 378 firstComputePointsEnable[firstHatchComputePoint] = true; 379 lineNumber = firstComputeConflictNumHatchLineTab[indHatch][firstHatchComputePoint]; 380 } 381 } 382 if (solution == 0) { // could go to second solution 383 indTmp = 0; 384 while ((solution == 0) && (indTmp < fConflictNumHatchLineTab[indHatch].size())) { 385 if ((fConflictNumHatchLineTab[indHatch][indTmp] == (int)lineNumber) && (secondComputePointsEnable[indTmp] == false)) { 386 solution =2; 387 oldSolution = 0; 388 fPoints.push_back(secondComputePoints[indTmp+secondPointTabInd]); 389 fVertices.back() ++; 390 secondComputePointsEnable[indTmp] = true; 391 lineNumber = fConflictNumHatchLineTab[indHatch][indTmp]; 392 secondHatchComputePoint = indTmp; 393 currentHatch =1; 394 } 395 indTmp ++; 396 } 397 } 398 if (solution == 0) { // could go to first solution 399 indTmp = 0; 400 while ((solution == 0) && (indTmp < aNumber)) { 401 402 if ((fHatchShiftToMatchPointVec[indTmp] > ((float)firstComputeFirstNumHatch+(float)indHatch-fStripWidth)) 403 && (fHatchShiftToMatchPointVec[indTmp] < ((float)firstComputeFirstNumHatch+(float)indHatch)) 404 && ((indTmp == lineNumber) || (indTmp==lineNumber+1) || ((lineNumber == (aNumber-1)) && (indTmp ==0)))) { 405 find = false; 406 unsigned a =0; 407 while ((a<fVertices.back()) && (find == false)) { 408 if ((tabPoints[indTmp][0] == fPoints[a][0]) && (tabPoints[indTmp][1] == fPoints[a][1]) && (tabPoints[indTmp][2] == fPoints[a][2])) find = true; 409 a++; 410 } 411 if (find == false){ 412 solution = 3; 413 oldSolution = 0; 414 currentHatch =2; 415 fPoints.push_back(tabPoints[indTmp]); 416 fVertices.back() ++; 417 if (lineNumber == indTmp) { 418 if (indTmp >0) lineNumber = indTmp-1; 419 else lineNumber = aNumber-1; 420 } 421 else { 422 if (indTmp < aNumber-1) lineNumber = indTmp; 423 else lineNumber = 0; 424 } 425 } 426 } 427 indTmp++; 428 } 429 } 430 } // end of current hatch 431 432 //test of second hatch if currentHatch is second 433 if ((oldSolution != 0) && (solution !=2) && (currentHatch !=0)) { 434 435 if (oldSolution != 3){ // could go to first solution 436 int index =0; 437 if ((secondHatchComputePoint % 2 == 0) && (secondComputePointsEnable[secondHatchComputePoint+1] == false)) index =1; 438 else if ((secondHatchComputePoint % 2 != 0) && (secondComputePointsEnable[secondHatchComputePoint-1] == false)) index = -1; 439 if (index !=0){ 440 solution = 1; 441 secondHatchComputePoint = secondHatchComputePoint+index; 442 fPoints.push_back(secondComputePoints[secondHatchComputePoint+secondPointTabInd]); 443 fVertices.back() ++; 444 secondComputePointsEnable[secondHatchComputePoint] = true; 445 lineNumber = fConflictNumHatchLineTab[indHatch][secondHatchComputePoint]; 446 } 447 } 448 if (solution == 0) { // could go to second solution 449 indTmp = 0; 450 while ((solution == 0) && (indTmp < firstComputeConflictNumHatchLineTab[indHatch].size())) { 451 if ((firstComputeConflictNumHatchLineTab[indHatch][indTmp] == (int)lineNumber) && (firstComputePointsEnable[indTmp] == false)) { 452 solution =2; 453 fPoints.push_back(firstComputePoints[indTmp+firstPointTabInd]); 454 fVertices.back() ++; 455 firstComputePointsEnable[indTmp] = true; 456 lineNumber = firstComputeConflictNumHatchLineTab[indHatch][indTmp]; 457 firstHatchComputePoint = indTmp; 458 currentHatch =0; 459 } 460 indTmp ++; 461 } 462 } 463 if (solution == 0) { // could go to first solution 464 indTmp = 0; 465 while ((solution == 0) && (indTmp < aNumber)) { 466 467 if ((fHatchShiftToMatchPointVec[indTmp] > ((float)fFirstNumHatch+(float)indHatch-fStripWidth)) 468 && (fHatchShiftToMatchPointVec[indTmp] < ((float)fFirstNumHatch+(float)indHatch)) 469 && ((indTmp == lineNumber) || (indTmp==lineNumber+1) || ((lineNumber == (aNumber-1)) && (indTmp ==0)))) { 470 find = false; 471 unsigned a =0; 472 while ((a<fVertices.back()) && (find == false)) { 473 if ((tabPoints[indTmp][0] == fPoints[a][0]) && (tabPoints[indTmp][1] == fPoints[a][1]) && (tabPoints[indTmp][2] == fPoints[a][2])) find = true; 474 a++; 475 } 476 if (find == false){ 477 currentHatch =2; 478 solution = 3; 479 fPoints.push_back(tabPoints[indTmp]); 480 fVertices.back() ++; 481 if (lineNumber == indTmp) { 482 if (indTmp >0) lineNumber = indTmp-1; 483 else lineNumber = aNumber-1; 484 } 485 else { 486 if (indTmp < aNumber-1) lineNumber = indTmp; 487 else lineNumber = 0; 488 } 489 } 490 } 491 indTmp++; 492 } 493 } 494 } // end of current hatch 495 if (solution == 0) { 496 // the end for this polyline 497 // close polyline 498 fPoints.push_back(fPoints[fPoints.size()-fVertices.back()]); 499 fVertices.back() ++; 500 result =true; 501 } 502 } // while solution !=0 503 // } // if result 504 } // while result 505 for (unsigned int a =0;a<fVertices.size();a++){ 506 #ifdef TOOLS_HATCHER_DEBUG 507 if (fVertices[a] <4) ::printf("hatcher::drawStripPolyline : WARNING A strip polyline has been compute with less than 3 points, it could be an error in the algorithm or a special case.\n\n"); 508 #endif 509 } 510 511 firstPointTabInd += firstComputeConflictNumHatchLineTab[indHatch].size(); 512 secondPointTabInd += fConflictNumHatchLineTab[indHatch].size(); 513 } //end for 514 return true; 515 } 516 517 518 519 520 ////////////////////////////////////////////////////////////////////////////// 521 // draw the hatch into the polyline bounding box giving in argument 522 // return false if : 523 // - All points are not in the same plan 524 // - There is a precision error on one or more point 525 ////////////////////////////////////////////////////////////////////////////// 526 527 inline bool hatcher::compute_single_polyline (vec3f* tabPoints,unsigned int aNumber) { 528 std::vector<vec3f> listNormalVec; 529 int numberOfPolylinePoints =0; 530 fPoints.resize(0); 531 fPoints.clear(); 532 int precisionError =0; 533 unsigned int firstOffset =0; 534 fFirstNumHatch =0; 535 fNumberHatchToDraw =0; 536 fVertices.resize(0); 537 fVertices.clear(); 538 539 if ( tabPoints[0].equals(tabPoints[1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) { 540 firstOffset =1; } 541 542 vec3f* listPoints = new vec3f[aNumber+1-firstOffset]; 543 544 for (unsigned int i=0;i<aNumber;i++){ 545 if ((i==0) || (listPoints[i-1] !=tabPoints[i+firstOffset])) { 546 listPoints[numberOfPolylinePoints] = tabPoints[i+firstOffset]; 547 numberOfPolylinePoints++; 548 } 549 } 550 551 // add the first point on last position to close the line 552 if ( ! listPoints[0].equals(listPoints[numberOfPolylinePoints-1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) { 553 listPoints[numberOfPolylinePoints]=listPoints[0]; 554 numberOfPolylinePoints ++; 555 } 556 557 // use to test the polyline and to build the shift vector. A is the first point, 558 // B second and C the last (in fact, the last-1)! 559 vec3f AB,AC; 560 AB.setValue(listPoints[1].getValue()[0]-listPoints[0].getValue()[0], 561 listPoints[1].getValue()[1]-listPoints[0].getValue()[1], 562 listPoints[1].getValue()[2]-listPoints[0].getValue()[2]); // Vector A->B 563 564 fResolveResult = RESOLVE_COLINEAR; 565 unsigned int test = numberOfPolylinePoints-1; 566 while ((fResolveResult !=0) && (test>1)) { 567 test--; 568 AC.setValue(listPoints[test].getValue()[0]-listPoints[0].getValue()[0], 569 listPoints[test].getValue()[1]-listPoints[0].getValue()[1], 570 listPoints[test].getValue()[2]-listPoints[0].getValue()[2]); 571 572 // test if AB != AC*i 573 resolve_system( AB, 574 AC, 575 vec3f(.0f,.0f,.0f)); 576 } 577 if (fResolveResult == RESOLVE_COLINEAR) { 578 #ifdef TOOLS_HATCHER_DEBUG 579 ::printf("hatcher::drawPolyline : ERROR all the point you give are colinear!\n\n"); 580 for (unsigned int a =0;a<aNumber;a++) { 581 printf(" %f %f %f \n",listPoints[a][0],listPoints[a][1],listPoints[a][2]); } 582 #endif 583 delete [] listPoints; 584 return false; 585 } 586 587 /////////////////////////////////////////////////////////////// 588 // creation of the dirVec. It is done with the dirAngle field 589 // The angle is the one between the first line (point 1-point0) 590 // and the dirVec, on the plan delimited by polyline 591 // Given in the direct axis ((point1-point0),(lastPoint-point0),normalPlanVec) 592 // Normal plane Vector = AB x AC 593 /////////////////////////////////////////////////////////////// 594 if (fFirstPolyline) { 595 596 fFirstPolyline = false; 597 598 fNormal.setValue(AB[1]*AC[2]-AB[2]*AC[1], 599 AB[2]*AC[0]-AB[0]*AC[2], 600 AB[0]*AC[1]-AB[1]*AC[0]); 601 602 603 // ABPerp Vector = normal x AB 604 vec3f ABPerpVector; 605 ABPerpVector.setValue(fNormal[1]*AB[2]-fNormal[2]*AB[1], 606 fNormal[2]*AB[0]-fNormal[0]*AB[2], 607 fNormal[0]*AB[1]-fNormal[1]*AB[0]); 608 609 float normAB =(float)std::sqrt(std::pow(AB[0],2)+ 610 std::pow(AB[1],2)+ 611 std::pow(AB[2],2)); 612 float normABPerpVector =(float)std::sqrt(std::pow(ABPerpVector[0],2)+ 613 std::pow(ABPerpVector[1],2)+ 614 std::pow(ABPerpVector[2],2)); 615 616 float j = std::tan(fDirAngle)*normAB/normABPerpVector; 617 618 if (normABPerpVector == 0){ // never done (should be test before) 619 #ifdef TOOLS_HATCHER_DEBUG 620 ::printf("hatcher::drawPolyline : ERROR Impossible to compute the dir vector for hatch. Normal for this plan is null (normal for : point[0],point[1],lastPoint) point[0], point[1], last point are probably aligned\n\n"); 621 #endif 622 delete [] listPoints; 623 return false; 624 } 625 626 fDirVec = AB +(float)j*ABPerpVector; 627 // normalize vector to unit on X or on Y 628 if (fDirVec.getValue()[0] ==0){ 629 fDirVec[0] = fPrecisionFactor; // to get rid of somes errors 630 fDirVec = fDirVec/fDirVec.getValue()[1]; // normalize on Y because X will be a big value 631 } else { 632 fDirVec = fDirVec/fDirVec.getValue()[0]; 633 } 634 635 /////////////////////////////////////////////////////////////// 636 // creation of the shiftVec thanks to the shift field 637 /////////////////////////////////////////////////////////////// 638 639 vec3f dirShiftVector; 640 dirShiftVector.setValue(fNormal[1]*fDirVec.getValue()[2]-fNormal[2]*fDirVec.getValue()[1], 641 fNormal[2]*fDirVec.getValue()[0]-fNormal[0]*fDirVec.getValue()[2], 642 fNormal[0]*fDirVec.getValue()[1]-fNormal[1]*fDirVec.getValue()[0]); 643 644 // normalize vector to match the shift size 645 float param = 1.0f; 646 param = (float)std::sqrt((std::pow(fShift,2))/( 647 std::pow(dirShiftVector[0],2)+ 648 std::pow(dirShiftVector[1],2)+ 649 std::pow(dirShiftVector[2],2))); 650 fShiftVec = dirShiftVector*param; 651 652 // compute offset only if it was not given 653 if ((fOffset[0] == FLT_MAX) && (fOffset[1] == FLT_MAX) && (fOffset[2] == FLT_MAX)){ 654 fOffset = listPoints[0]+fShiftVec*fOffsetValue; 655 } 656 } 657 658 659 ///////////////////////////////////////////// 660 // START to compute 661 // We compute each line one by one to know witch hatch will be draw thrue this line 662 // we try to know the result of 663 // (origin_point_of_hatch)+i*(directionVector)+j*(shiftVector) = each_point_of_polyline 664 // We will be interest only on j factor for the moment. This factor represent the offset 665 // between the Origin point of the hatch and the compute point of the polyline 666 // We put results in a float table 667 // 668 // We also have to memorize the min and max number of the hatch to be draw 669 // Point 0 1 2 3 4 5 6 ...n 1 670 // hatchShiftToMatchPoint 5 7 2 6 7 8 5 ...2 5 671 // min = 1 max = 8 -> 8 hatch to draw 672 //////////////////////////////////////////// 673 674 fHatchShiftToMatchPointVec.resize(numberOfPolylinePoints+1); 675 float minShiftHatch =FLT_MAX; 676 float maxShiftHatch =-FLT_MAX; 677 vec2f res; 678 679 for (int a=0;a<numberOfPolylinePoints;a++) { 680 res = resolve_system(fDirVec.getValue(), 681 fShiftVec, 682 listPoints[a]-fOffset); 683 // test result 684 if (fResolveResult ==0 ) { 685 fHatchShiftToMatchPointVec[a] = res[1]; 686 if (res[1]>maxShiftHatch) { 687 maxShiftHatch = res[1]; 688 } 689 if (res[1]<minShiftHatch) { 690 minShiftHatch = res[1]; 691 } 692 } 693 else { // never done (should be test before) 694 #ifdef TOOLS_HATCHER_DEBUG 695 ::printf("hatcher::drawPolyline : ERROR one or more of your polyline points are not on the same plan ! Testing point %d/%d error:%d\n\n",a,numberOfPolylinePoints,fResolveResult); 696 #endif 697 delete [] listPoints; 698 return false; 699 } 700 } 701 // for the first point to close the polyline 702 fHatchShiftToMatchPointVec[numberOfPolylinePoints] = fHatchShiftToMatchPointVec[0]; 703 fFirstNumHatch = (int)(ceilf(minShiftHatch)); 704 fNumberHatchToDraw = (int)(floorf(maxShiftHatch)-fFirstNumHatch+1); 705 if ((int)(floorf(maxShiftHatch)-fFirstNumHatch+1) <0) fNumberHatchToDraw =0; 706 707 int moreNumberHatchToDraw = fNumberHatchToDraw+1; 708 std::vector<vec3f> listHatchStartPoint; 709 std::vector<vec3f> listHatchEndPoint; 710 std::vector<int> numberOfStartEndPointsVec; 711 712 fConflictNumHatchLineTab.resize(moreNumberHatchToDraw); 713 714 // initialize tab 715 for (int a=0;a<moreNumberHatchToDraw;a++) { 716 numberOfStartEndPointsVec.push_back(0); 717 listHatchStartPoint.push_back(vec3f(.0f,.0f,.0f)); 718 listHatchEndPoint.push_back(vec3f(.0f,.0f,.0f)); 719 fConflictNumHatchLineTab[a].clear(); 720 } 721 722 ///////////////////////////////////////////// 723 // Compute the normalize shift vector for all lines 724 // the normal Vector for point 3 to 4 will be listNormalvec[2] 725 ///////////////////////////////////////////// 726 727 for (int a=0;a<numberOfPolylinePoints-1;a++) { 728 res = resolve_system(fDirVec.getValue(), 729 vec3f(listPoints[a].getValue()[0]-listPoints[a+1].getValue()[0], 730 listPoints[a].getValue()[1]-listPoints[a+1].getValue()[1], 731 listPoints[a].getValue()[2]-listPoints[a+1].getValue()[2]), 732 -fShiftVec); 733 if (fResolveResult ==0 ) { 734 listNormalVec.push_back(vec3f(res[1]*(listPoints[a+1].getValue()[0]-listPoints[a].getValue()[0]), 735 res[1]*(listPoints[a+1].getValue()[1]-listPoints[a].getValue()[1]), 736 res[1]*(listPoints[a+1].getValue()[2]-listPoints[a].getValue()[2]) 737 )); 738 } 739 else if (fResolveResult == RESOLVE_Z_ERROR ) { // never done (should be test before) 740 #ifdef TOOLS_HATCHER_DEBUG 741 ::printf("hatcher::drawPolyline : ERROR one or more of your polyline points are not on the same plan !\n\n"); 742 #endif 743 delete [] listPoints; 744 return false; 745 } 746 else{ 747 listNormalVec.push_back(vec3f(FLT_MAX,FLT_MAX,FLT_MAX)); 748 // listNormalVec.append(new vec3f(FLT_MAX,FLT_MAX,FLT_MAX)); 749 } 750 } 751 752 ///////////////////////////////////////////// 753 // Compute the hatchShiftToMatchPointVec table to try to get the start 754 // and end point of each hatch 755 // if there is more than one start/end point, we will resolve it later. For the moment, 756 // we put confict points into a table 757 // HatchNumber 1 2 3 4 5 6 7 8 9 758 // listHatchStartPoint 1,0,0 1,1,0 0,0,1 0,1,0 1,1,0 0,2,0 1,1,4 759 // listHatchEndPoint .............. 760 // conflictNumHatchLineTab 5 6 7 761 // line Number is 0 for (point[0]->point[1]) 762 // We put each line number into the conflict table to be sure to get all the lines 763 // in conflict. When we will thest the value of the conflicy table, it should 764 // be greater than 2 to have a conflict 765 ///////////////////////////////////////////// 766 767 vec3f newPoint; 768 int minHatch; 769 int maxHatch; 770 int hatchIndice =0; 771 772 for (int indPolyline=0;indPolyline<numberOfPolylinePoints-1;indPolyline++) { 773 minHatch = (int)(ceilf(fHatchShiftToMatchPointVec[indPolyline])); 774 maxHatch = (int)(floorf(fHatchShiftToMatchPointVec[indPolyline+1])); 775 776 if (fHatchShiftToMatchPointVec[indPolyline+1] <fHatchShiftToMatchPointVec[indPolyline]) { 777 minHatch =(int)(ceilf(fHatchShiftToMatchPointVec[indPolyline+1])); 778 maxHatch = (int)(floorf(fHatchShiftToMatchPointVec[indPolyline])); 779 } 780 for (int b=minHatch;b<=maxHatch;b++) { // for all number of hatch fund 781 // compute new point 782 hatchIndice = b-fFirstNumHatch; 783 784 newPoint.setValue(listPoints[indPolyline].getValue()[0]+ 785 listNormalVec[indPolyline][0]*(b-fHatchShiftToMatchPointVec[indPolyline]), 786 listPoints[indPolyline].getValue()[1]+ 787 listNormalVec[indPolyline][1]*(b-fHatchShiftToMatchPointVec[indPolyline]), 788 listPoints[indPolyline].getValue()[2]+ 789 listNormalVec[indPolyline][2]*(b-fHatchShiftToMatchPointVec[indPolyline])); 790 791 if (numberOfStartEndPointsVec[hatchIndice] == 0) {// it is the first point 792 //compute point and save it 793 // the start point will be : 794 // Point_of_the_line + normalVec * 795 //(number_of_hatch_to_compute - number_of_hatch_corresponding_to_first_point_of_line) 796 // 797 if ( (listNormalVec[indPolyline][0] != FLT_MAX) 798 && (listNormalVec[indPolyline][1] != FLT_MAX) 799 && (listNormalVec[indPolyline][2] != FLT_MAX)) { 800 listHatchStartPoint[hatchIndice] = vec3f(newPoint); 801 fConflictNumHatchLineTab[hatchIndice].push_back(indPolyline); 802 numberOfStartEndPointsVec[hatchIndice]++; 803 } 804 } else if (numberOfStartEndPointsVec[hatchIndice] == 1) { // it is the second point 805 //compute point and save it (same point as previous ) 806 // the start point will be : 807 // Point_of_the_line + normalVec * 808 // (number_of_hatch_to_compute - number_of_hatch_corresponding_to_first_point_of_line) 809 // store only if newPoint is != start 810 if ((listNormalVec[indPolyline][0] != FLT_MAX) 811 && (listNormalVec[indPolyline][1] != FLT_MAX) 812 && (listNormalVec[indPolyline][2] != FLT_MAX)) { 813 listHatchEndPoint[hatchIndice] = vec3f(newPoint); 814 fConflictNumHatchLineTab[hatchIndice].push_back(indPolyline); 815 numberOfStartEndPointsVec[hatchIndice]++; 816 } 817 } else { // there is a conflict, we don't compute anything except for conflicts on points 818 // witch are already compute 819 // case of the hatch will be draw on a point of the polyline, 820 // so it match 2 lines + another 821 fConflictNumHatchLineTab[hatchIndice].push_back(indPolyline); // put the line number in conflict table 822 } 823 } 824 } 825 826 ///////////////////////////////////////////// 827 // Compute the numHatchLine tab and draw correct points 828 ///////////////////////////////////////////// 829 std::vector<float> listCoefDirHatch(fNumberHatchToDraw); 830 std::vector<vec3f> listConflictPoints(numberOfPolylinePoints); 831 832 vec3f ABVec,tempVec; 833 int valid =false; 834 bool drawEnabled = false; // true : we could draw second point, false we wait for the first 835 float temp=0; 836 int tempInt =0; 837 float nextPointConflictHatchNumber = -FLT_MAX; 838 float currentPointConflictHatchNumber = -FLT_MAX; 839 std::vector<unsigned int> orderConflictLineNumber; 840 841 for (unsigned int hatchNumber =0;hatchNumber<fNumberHatchToDraw;hatchNumber++) { 842 if ( fConflictNumHatchLineTab[hatchNumber].size() <= 2) { 843 if (!listHatchStartPoint[hatchNumber].equals(listHatchEndPoint[hatchNumber],FLT_EPSILON*FLT_EPSILON*10)) { 844 fPoints.push_back(listHatchStartPoint[hatchNumber]); 845 fPoints.push_back(listHatchEndPoint[hatchNumber]); 846 fVertices.push_back(2); 847 } 848 } else { // there is a conflict 849 // We read the conflict table and compute all the conflict lines 850 // conflict is on hatch number hatchNumber+ firstNumHatch 851 // Compute the equation on the conflict line (called ABVec ): 852 // i*dirVec - j*ABVec = A-(offset + shiftVec * numberHatchToDraw) 853 // and store the i parameter 854 // then we 855 856 listConflictPoints.clear(); 857 listCoefDirHatch.clear(); 858 std::vector <unsigned int> toRemove; 859 for (unsigned int conflictLineNumber=0;conflictLineNumber<fConflictNumHatchLineTab[hatchNumber].size();conflictLineNumber++ ) 860 { 861 862 ABVec.setValue(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]+1].getValue()[0]-listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[0], 863 listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]+1].getValue()[1]-listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[1], 864 listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]+1].getValue()[2]-listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[2]); 865 866 res = resolve_system(fDirVec.getValue(), 867 ABVec, 868 vec3f(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[0]-fOffset[0]-((float)hatchNumber+(float)fFirstNumHatch)*fShiftVec[0], 869 listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[1]-fOffset[1]-((float)hatchNumber+(float)fFirstNumHatch)*fShiftVec[1], 870 listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[2]-fOffset[2]-((float)hatchNumber+(float)fFirstNumHatch)*fShiftVec[2])); 871 872 if (fResolveResult ==0 ) { 873 // we store results 874 listCoefDirHatch.push_back(2); 875 listCoefDirHatch.pop_back(); 876 listCoefDirHatch.push_back(res[0]); 877 res[1] = -res[1]; 878 listConflictPoints.push_back(vec3f(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]]+ABVec*res[1])); 879 } 880 else if (fResolveResult != RESOLVE_COLINEAR){ 881 #ifdef TOOLS_HATCHER_DEBUG 882 printf("hatcher : Precision error during compute on hatch number%d\n\n",hatchNumber); 883 #endif 884 precisionError++; 885 } else { 886 toRemove.push_back(conflictLineNumber); 887 } 888 } 889 890 if (toRemove.size()) { 891 for (unsigned int conflictLineNumber=0;conflictLineNumber<fConflictNumHatchLineTab[hatchNumber].size();conflictLineNumber++ ) { 892 } 893 // remove potential colinear problems 894 for (unsigned int aa=0;aa<toRemove.size();aa++) { 895 unsigned int ind = 0; 896 for (std::vector<int>::iterator it = fConflictNumHatchLineTab[hatchNumber].begin();it !=fConflictNumHatchLineTab[hatchNumber].end();it++) { 897 if (ind == toRemove[aa]) { 898 fConflictNumHatchLineTab[hatchNumber].erase(it); 899 break; 900 } 901 ind++; 902 } 903 } 904 for (unsigned int conflictLineNumber=0;conflictLineNumber<fConflictNumHatchLineTab[hatchNumber].size();conflictLineNumber++ ) { 905 } 906 } 907 if (listCoefDirHatch.size() != 0) { // all points are resolve_system errors (RESOLVE_COLINEAR or RESOLVE_Z_ERROR 908 909 // now, we have to sort all coef dir from minus to max 910 // and at the same time, reorder the conflict ponts and the conflict line number 911 // this algorithm is not optimum... 912 valid = false; 913 while (valid ==false ) 914 { 915 valid = true; 916 for (unsigned int sort =0;sort< listCoefDirHatch.size()-1;sort++) 917 { 918 if (listCoefDirHatch[sort]>listCoefDirHatch[sort+1]) { 919 920 temp = listCoefDirHatch[sort]; 921 listCoefDirHatch[sort] = listCoefDirHatch[sort+1]; 922 listCoefDirHatch[sort+1] =temp; 923 tempVec = listConflictPoints[sort]; 924 listConflictPoints[sort] = listConflictPoints[sort+1]; 925 listConflictPoints[sort+1] = tempVec; 926 tempInt = fConflictNumHatchLineTab[hatchNumber][sort]; 927 fConflictNumHatchLineTab[hatchNumber][sort] = fConflictNumHatchLineTab[hatchNumber][sort+1]; 928 fConflictNumHatchLineTab[hatchNumber][sort+1] = tempInt; 929 valid= false; 930 } 931 } 932 } 933 934 // once dir coef have been sort, we could draw lines !! 935 //witch line had made a conflict ??? conflictNumHatchLineTab[a] 936 unsigned int conflictNumber =0; 937 orderConflictLineNumber.clear(); 938 939 drawEnabled = false; 940 while (conflictNumber < fConflictNumHatchLineTab[hatchNumber].size()) { // while 941 if (conflictNumber+1 == fConflictNumHatchLineTab[hatchNumber].size()) { 942 if(drawEnabled) { 943 drawEnabled = false; 944 fPoints.push_back(listConflictPoints[conflictNumber].getValue()); 945 orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]); 946 } 947 } 948 else { 949 // if the conflict point == next conflict point : that is a end/begin line conflict 950 // else, this is not a big problem, we just have to invert the drawEnabled 951 // (if we were drawing, we have to finish a line, else, we have to begin a line 952 if ( !(listConflictPoints[conflictNumber].equals(listConflictPoints[conflictNumber+1],FLT_EPSILON*FLT_EPSILON*10))) { 953 // special case of nextPointline=nextConflict point : hatch//line 954 unsigned int follow=conflictNumber+1; 955 bool overContour = false; 956 while ((follow <fConflictNumHatchLineTab[hatchNumber].size()) && 957 (listConflictPoints[conflictNumber].equals(listConflictPoints[follow],FLT_EPSILON*FLT_EPSILON*10))) { 958 follow++; 959 } 960 //test if next point is on the contour 961 if(follow < fConflictNumHatchLineTab[hatchNumber].size()) { 962 if ((listConflictPoints[follow].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][follow]].getValue(),FLT_EPSILON*FLT_EPSILON*10))) { 963 if ((fConflictNumHatchLineTab[hatchNumber][follow] != 0) && 964 (fConflictNumHatchLineTab[hatchNumber][follow] != numberOfPolylinePoints-1)) { 965 if ((listConflictPoints[conflictNumber].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][follow]-1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) || 966 (listConflictPoints[conflictNumber].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][follow]+1].getValue(),FLT_EPSILON*FLT_EPSILON*10))) { 967 overContour = true; 968 } 969 } 970 } 971 } 972 int previous=conflictNumber-1; 973 while ((previous >=0) && 974 (listConflictPoints[conflictNumber].equals(listConflictPoints[previous],FLT_EPSILON*FLT_EPSILON*10))) { 975 previous--; 976 } 977 //test if next point is on the contour 978 if(previous >= 0) { 979 if ((listConflictPoints[conflictNumber].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber]].getValue(),FLT_EPSILON*FLT_EPSILON*10))) { 980 if ((listConflictPoints[previous].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber]-1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) || 981 (listConflictPoints[previous].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber]+1].getValue(),FLT_EPSILON*FLT_EPSILON*10))) { 982 overContour = true; 983 } 984 } 985 } 986 if (!overContour) { // we are not on a contour, we can draw 987 fPoints.push_back(listConflictPoints[conflictNumber].getValue()); 988 orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]); 989 drawEnabled = drawEnabled?false:true; 990 if (drawEnabled) { 991 fVertices.push_back(2); 992 } 993 } else { // else we have to stop drawing 994 if (drawEnabled) { 995 fPoints.push_back(listConflictPoints[conflictNumber].getValue()); 996 orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]); 997 drawEnabled = false; 998 } 999 } 1000 } 1001 else { // next point == current 1002 bool currentPointCrossLine = false; 1003 bool nextPointCrossLine = false; 1004 // if the conflict is on a line point, we have to look the hatch number 1005 // of the previous and next point to see if the hatch had to be draw or not 1006 1007 // test if conflictPoint == first line point 1008 if (listConflictPoints[conflictNumber].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber]].getValue(),FLT_EPSILON*FLT_EPSILON*10)) { 1009 // we look second point hatchNumber 1010 currentPointConflictHatchNumber = fHatchShiftToMatchPointVec[fConflictNumHatchLineTab[hatchNumber][conflictNumber]+1]; 1011 } 1012 else if (listConflictPoints[conflictNumber].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber]+1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) { 1013 // we look first point hatchNumber 1014 currentPointConflictHatchNumber = fHatchShiftToMatchPointVec[fConflictNumHatchLineTab[hatchNumber][conflictNumber]]; 1015 } 1016 else { // case of two lines have intersection point on a hatch 1017 // it is the same case as a "end of line" and a "begin of line" conflict 1018 currentPointCrossLine = true; 1019 currentPointConflictHatchNumber =-1 ; 1020 } 1021 // test if conflictPoint == second line point 1022 if (listConflictPoints[conflictNumber+1].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber+1]].getValue(),FLT_EPSILON*FLT_EPSILON*10)) { 1023 // we look second point hatchNumber 1024 nextPointConflictHatchNumber = fHatchShiftToMatchPointVec[fConflictNumHatchLineTab[hatchNumber][conflictNumber+1]+1]; 1025 } 1026 else if (listConflictPoints[conflictNumber+1].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber+1]+1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) { 1027 // we look first point hatchNumber 1028 nextPointConflictHatchNumber = fHatchShiftToMatchPointVec[fConflictNumHatchLineTab[hatchNumber][conflictNumber+1]]; 1029 } 1030 else { // case of two lines have intersection point on a hatch 1031 // it is the same case as a "end of line" and a "begin of line" conflict 1032 nextPointConflictHatchNumber = -1; 1033 nextPointCrossLine = true; 1034 } 1035 1036 // we have to compute the currentPointConflictHatchNumber and 1037 // nextPointConflictHatchNumber 1038 // if they are all the same side of the hatch, we have to ignore points 1039 // else, we have to draw a line 1040 if (currentPointCrossLine && nextPointCrossLine) { 1041 // do not draw anything, this is the case of a hatch crossing 1042 // two identical line 1043 } 1044 // case of two points on conflict on a contour point where nothing has to be draw 1045 else if ((!currentPointCrossLine && !nextPointCrossLine) && (currentPointConflictHatchNumber == nextPointConflictHatchNumber) && (currentPointConflictHatchNumber == fHatchShiftToMatchPointVec[fConflictNumHatchLineTab[hatchNumber][conflictNumber]])) { 1046 if (drawEnabled) { 1047 fPoints.push_back(listConflictPoints[conflictNumber].getValue()); 1048 orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]); 1049 drawEnabled = false; 1050 } 1051 } 1052 // we draw 1053 else if( ( (currentPointConflictHatchNumber - 1054 fHatchShiftToMatchPointVec[fConflictNumHatchLineTab[hatchNumber][conflictNumber]]) * 1055 (nextPointConflictHatchNumber - 1056 fHatchShiftToMatchPointVec[fConflictNumHatchLineTab[hatchNumber][conflictNumber]])) 1057 <=FLT_EPSILON) { 1058 // try to see if we are trying to draw a hatch OVER a contour 1059 unsigned int follow=conflictNumber+1; 1060 bool overContour = false; 1061 while ((follow <fConflictNumHatchLineTab[hatchNumber].size()) && 1062 (listConflictPoints[conflictNumber].equals(listConflictPoints[follow],FLT_EPSILON*FLT_EPSILON*10))) { 1063 follow++; 1064 } 1065 if(follow < fConflictNumHatchLineTab[hatchNumber].size()) { 1066 float alpha = 0; 1067 bool findAlpha = true; 1068 if (listConflictPoints[follow][0] != listConflictPoints[conflictNumber][0]) { 1069 alpha = (listPoints[fConflictNumHatchLineTab[hatchNumber][follow]][0]-listConflictPoints[conflictNumber][0])/(listConflictPoints[follow][0]-listConflictPoints[conflictNumber][0]); 1070 } 1071 else if (listConflictPoints[follow][1] != listConflictPoints[conflictNumber][1]) { 1072 alpha = (listPoints[fConflictNumHatchLineTab[hatchNumber][follow]][1]-listConflictPoints[conflictNumber][1])/(listConflictPoints[follow][1]-listConflictPoints[conflictNumber][1]); 1073 } 1074 else if (listConflictPoints[follow][2] != listConflictPoints[conflictNumber][2]) { 1075 alpha = (listPoints[fConflictNumHatchLineTab[hatchNumber][follow]][2]-listConflictPoints[conflictNumber][2])/(listConflictPoints[follow][2]-listConflictPoints[conflictNumber][2]); 1076 } 1077 else { 1078 findAlpha =false; 1079 } 1080 if (findAlpha) { 1081 if ((alpha*(listConflictPoints[follow]-listConflictPoints[conflictNumber])).equals(listPoints[fConflictNumHatchLineTab[hatchNumber][follow]]-listConflictPoints[conflictNumber],FLT_EPSILON*FLT_EPSILON*10)) { 1082 overContour = true; 1083 } 1084 } 1085 } 1086 if (!overContour) { // if we are not on a contour, no problem 1087 fPoints.push_back(listConflictPoints[conflictNumber].getValue()); 1088 orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]); 1089 drawEnabled = drawEnabled?false:true; 1090 if (drawEnabled) { 1091 fVertices.push_back(2); 1092 } 1093 } else { // else we have to stop drawing 1094 if (drawEnabled) { 1095 fPoints.push_back(listConflictPoints[conflictNumber].getValue()); 1096 orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]); 1097 drawEnabled = false; 1098 } 1099 } 1100 } 1101 conflictNumber ++; 1102 } // end next== current 1103 } 1104 conflictNumber ++; 1105 } // end while 1106 if (drawEnabled) { 1107 fPoints.push_back(fPoints[fPoints.size()-1]); 1108 #ifdef TOOLS_HATCHER_DEBUG 1109 printf("hatcher : Probably a error during conflict resolution on hatch number %d :\nWe have close this line by putting two times the same point.\n\n",hatchNumber); 1110 #endif 1111 } 1112 //re put the order conflictNumHatchLineTab witch could be use by stripWidth 1113 fConflictNumHatchLineTab[hatchNumber].clear(); 1114 for(unsigned int a=0;a<orderConflictLineNumber.size();a++) { 1115 fConflictNumHatchLineTab[hatchNumber].push_back(orderConflictLineNumber[a]);} 1116 1117 // test if it is correct 1118 } // end resolve system errors 1119 } // end conflict 1120 } 1121 1122 if (fPoints.size() >0){ 1123 1124 if (precisionError == 0){ 1125 delete [] listPoints; 1126 return true; 1127 } 1128 else { 1129 #ifdef TOOLS_HATCHER_DEBUG 1130 printf("hatcher : Exit with %d precision error during compute\n\n",precisionError); 1131 #endif 1132 delete [] listPoints; 1133 return false; 1134 } 1135 } 1136 delete [] listPoints; 1137 return true; 1138 } 1139 1140 1141 1142 ////////////////////////////////////////////////////////////////////////////// 1143 // Compute a vector system equation aA+bB=C 1144 // return vec2f(0,0) if there is an error 1145 // set the resolveResult variable to the error code : 1146 // COLINEAR if A and B are 1147 // PRECISION_ERROR if there is a lack of precision in computing 1148 // Z_ERROR if there s no solution for Z 1149 // UNDEFINED never throw 1150 // return a vec2f for result. a is 'x' value and b is 'y' if it is correct 1151 ////////////////////////////////////////////////////////////////////////////// 1152 1153 inline vec2f hatcher::resolve_system(const vec3f& A,const vec3f& B,const vec3f& C) { 1154 1155 fResolveResult = RESOLVE_UNDEFINED; 1156 1157 double Ax = A[0]; 1158 double Ay = A[1]; 1159 double Az = A[2]; 1160 double Bx = B[0]; 1161 double By = B[1]; 1162 double Bz = B[2]; 1163 double Cx = C[0]; 1164 double Cy = C[1]; 1165 double Cz = C[2]; 1166 1167 double bDiv = (By*Ax-Ay*Bx); 1168 if (ffabs(float(bDiv)) <=FLT_EPSILON) { 1169 // we have to test in a other order 1170 double tmp; 1171 tmp = Ax; Ax = Ay; Ay = Az; Az = tmp; 1172 tmp = Bx; Bx = By; By = Bz; Bz = tmp; 1173 tmp = Cx; Cx = Cy; Cy = Cz; Cz = tmp; 1174 1175 bDiv = (By*Ax-Ay*Bx); 1176 1177 if (ffabs(float(bDiv)) <=FLT_EPSILON) { 1178 // we have to test in a other order 1179 tmp = Ax; Ax = Ay; Ay = Az; Az = tmp; 1180 tmp = Bx; Bx = By; By = Bz; Bz = tmp; 1181 tmp = Cx; Cx = Cy; Cy = Cz; Cz = tmp; 1182 1183 bDiv = (By*Ax-Ay*Bx); 1184 if (ffabs(float(bDiv)) <=FLT_EPSILON) { 1185 fResolveResult = RESOLVE_COLINEAR; 1186 return vec2f(0,0); 1187 } 1188 } 1189 } 1190 double b= (Cy*Ax-Ay*Cx)/bDiv; 1191 double a= -(Cy*Bx-By*Cx)/bDiv; 1192 double bid = ffabs(float(a*Az+b*Bz - Cz)); 1193 1194 if (bid <= FLT_EPSILON) { 1195 fResolveResult = RESOLVE_OK; 1196 return vec2f((float)a,(float)b); 1197 } 1198 else { 1199 1200 double minBoxValue = 1; 1201 1202 double minXValue =FLT_MAX; 1203 double minYValue =FLT_MAX; 1204 double minZValue =FLT_MAX; 1205 if ((A[0] !=0) && ((A[0]) <minXValue)) minXValue = (A[0]); 1206 if ((B[0] !=0) && ((B[0]) <minXValue)) minXValue = (B[0]); 1207 if ((C[0] !=0) && ((C[0]) <minXValue)) minXValue = (C[0]); 1208 if ((A[1] !=0) && ((A[1]) <minYValue)) minYValue = (A[1]); 1209 if ((B[1] !=0) && ((B[1]) <minYValue)) minYValue = (B[1]); 1210 if ((C[1] !=0) && ((C[1]) <minYValue)) minYValue = (C[1]); 1211 if ((A[2] !=0) && ((A[2]) <minZValue)) minZValue = (A[2]); 1212 if ((B[2] !=0) && ((B[2]) <minZValue)) minZValue = (B[2]); 1213 if ((C[2] !=0) && ((C[2]) <minZValue)) minZValue = (C[2]); 1214 1215 1216 double maxXValue =-FLT_MAX; 1217 double maxYValue =-FLT_MAX; 1218 double maxZValue =-FLT_MAX; 1219 if ((A[0] !=0) && ((A[0]) >maxXValue)) maxXValue = (A[0]); 1220 if ((B[0] !=0) && ((B[0]) >maxXValue)) maxXValue = (B[0]); 1221 if ((C[0] !=0) && ((C[0]) >maxXValue)) maxXValue = (C[0]); 1222 if ((A[1] !=0) && ((A[1]) >maxYValue)) maxYValue = (A[1]); 1223 if ((B[1] !=0) && ((B[1]) >maxYValue)) maxYValue = (B[1]); 1224 if ((C[1] !=0) && ((C[1]) >maxYValue)) maxYValue = (C[1]); 1225 if ((A[2] !=0) && ((A[2]) >maxZValue)) maxZValue = (A[2]); 1226 if ((B[2] !=0) && ((B[2]) >maxZValue)) maxZValue = (B[2]); 1227 if ((C[2] !=0) && ((C[2]) >maxZValue)) maxZValue = (C[2]); 1228 1229 if (((maxXValue-minXValue) <= (maxYValue-minYValue)) && ((maxXValue-minXValue) <= (maxZValue-minZValue))) { minBoxValue = maxXValue-minXValue; } 1230 else 1231 if (((maxYValue-minYValue) <= (maxXValue-minXValue)) && ((maxYValue-minYValue) <= (maxZValue-minZValue))) { minBoxValue = maxYValue-minYValue; } 1232 else 1233 { minBoxValue = maxZValue-minZValue; } 1234 1235 minBoxValue *= fPrecisionFactor; 1236 1237 if (bid <= minBoxValue) { 1238 fResolveResult = RESOLVE_OK; 1239 return vec2f((float)a,(float)b); 1240 } 1241 else { 1242 if (bid>100*minBoxValue) { 1243 #ifdef TOOLS_HATCHER_DEBUG 1244 printf("hatcher : ***** PRECISON ERROR ON Z ******* compare %f > %f res :%f %f test %f %f bDiv %e\n\n",bid,100*minBoxValue,a,b,a*Ax+b*Bx-Cx,a*Ay+b*By-Cy,bDiv); 1245 #endif 1246 fResolveResult = RESOLVE_Z_ERROR; 1247 } 1248 else 1249 { 1250 #ifdef TOOLS_HATCHER_DEBUG 1251 printf("hatcher : ***** PRECISON ERROR ******* compare %f > %f res :%f %f test %f %f bDiv %e\n\n",bid,100*minBoxValue,a,b,a*Ax+b*Bx-Cx,a*Ay+b*By-Cy,bDiv); 1252 #endif 1253 fResolveResult = RESOLVE_PRECISION_ERROR; 1254 } 1255 //return vec2f(0,0); //G.Barrand : commented out to quiet Coverity. 1256 } 1257 } 1258 return vec2f(0,0); 1259 } 1260 1261 } 1262 1263 //#undef TOOLS_HATCHER_DEBUG 1264