Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:49

0001 //  Created by Laurent Garnier on Fri Jan 30 2004.
0002 
0003 //#define TOOLS_HATCHER_DEBUG
0004 
0005 #ifdef TOOLS_HATCHER_DEBUG
0006 #include <cstdio>
0007 #endif
0008 
0009 namespace tools {
0010 
0011 //////////////////////////////////////////////////////////////////////////////
0012 // test if the polygone given is correct for hatching
0013 // return FALSE if :
0014 //    - All points are not in the same plan
0015 //    - Number of points <3
0016 //    - Offset point is not in the same plan
0017 //    - There is less than three different points
0018 //    - The vector from point[0],point[1] is colinear to point[0],lastPoint
0019 //////////////////////////////////////////////////////////////////////////////
0020 
0021 inline bool hatcher::check_polyline(vec3f* listPoints,unsigned int aNumber){
0022 
0023   unsigned int firstOffset =0;
0024 
0025   if ( listPoints[0].equals(listPoints[1],FLT_EPSILON*FLT_EPSILON*10)) {
0026     firstOffset =1;
0027   }
0028 
0029   if ( listPoints[0].equals(listPoints[aNumber-1],FLT_EPSILON*FLT_EPSILON*10)) {
0030     aNumber --;
0031   }
0032 
0033   if ((int)aNumber-firstOffset <3) {
0034 #ifdef TOOLS_HATCHER_DEBUG
0035     ::printf("hatcher::check_polyline : ERROR the polygone you give have not enought points!\n\n");
0036 #endif
0037     return false;
0038   }
0039 
0040 
0041   // use to test the polyline and to build the shift vector. A is the first point,
0042   // B second and C the last (in fact, the last-1)!
0043   vec3f AB,AC;
0044   AB.setValue(listPoints[1+firstOffset].getValue()[0]-listPoints[0].getValue()[0],
0045               listPoints[1+firstOffset].getValue()[1]-listPoints[0].getValue()[1],
0046               listPoints[1+firstOffset].getValue()[2]-listPoints[0].getValue()[2]); // Vector A->B
0047 
0048 
0049   fResolveResult = RESOLVE_COLINEAR;
0050   unsigned int test = aNumber;
0051   while ((fResolveResult !=0) && (test>2+firstOffset)) {
0052     test--;
0053     AC.setValue(listPoints[test].getValue()[0]-listPoints[0].getValue()[0],
0054                 listPoints[test].getValue()[1]-listPoints[0].getValue()[1],
0055                 listPoints[test].getValue()[2]-listPoints[0].getValue()[2]);
0056 
0057     // test if AB != AC*i
0058     resolve_system( AB,
0059                    AC,
0060                    vec3f(.0f,.0f,.0f));
0061   }
0062   if (fResolveResult == RESOLVE_COLINEAR) {
0063 #ifdef TOOLS_HATCHER_DEBUG
0064     ::printf("hatcher::check_polyline : ERROR all the point you give are colinear!\n\n");
0065     for (unsigned int a =0;a<aNumber;a++) {
0066       printf(" %f %f %f \n",listPoints[a][0],listPoints[a][1],listPoints[a][2]);  }
0067 #endif
0068     return false;
0069   }
0070 
0071   ///////////////////////////////////////////////////////////////
0072   // test if all points of the polyline are on the same plan
0073   ///////////////////////////////////////////////////////////////
0074 
0075   int falsePoints =0;
0076   for (unsigned int a=2+firstOffset;a<aNumber;a++) {
0077     resolve_system( AB,
0078                    AC,
0079                        vec3f((listPoints[a].getValue()[0]-listPoints[0].getValue()[0]),
0080                                (listPoints[a].getValue()[1]-listPoints[0].getValue()[1]),
0081                                (listPoints[a].getValue()[2]-listPoints[0].getValue()[2])));
0082     if (fResolveResult != 0){
0083       falsePoints++;
0084     }
0085   }
0086 
0087   if (falsePoints !=0) {
0088 #ifdef TOOLS_HATCHER_DEBUG
0089     ::printf("hatcher::check_polyline : ERROR there is %d points on the polyline witch are not on the same plan!\n\n",falsePoints);
0090 #endif
0091     return false;
0092   }
0093 
0094   // test offset
0095     if (! ((fOffset[0] == FLT_MAX) && (fOffset[1] == FLT_MAX) && (fOffset[2] == FLT_MAX))){
0096       resolve_system( AB,
0097                      AC,
0098                      fOffset-listPoints[0]);
0099       if (fResolveResult != 0) {
0100 #ifdef TOOLS_HATCHER_DEBUG
0101         ::printf("hatcher::check_polyline : ERROR Offset vector has to be on the same plan!\n\n");
0102 #endif
0103         return false;
0104       }
0105     }
0106     return true;
0107 }
0108 
0109 
0110 //////////////////////////////////////////////////////////////////////////////
0111 // draw the hatch into the polyline bounding box giving in argument
0112 // return false if :
0113 //    - All points are not in the same plan
0114 //    - There is a precision error on one or more point
0115 // Compute a first sequence of hacth, store results, compute a second sequence
0116 // and match all results to get the correct strip points
0117 //////////////////////////////////////////////////////////////////////////////
0118 /** Compute stripWidth
0119  * We have to use the conflictNumHatchLineTab, hatchNumber,listHatchStartPoint tables
0120  * also the HatchShiftToMacthPoint tab.
0121  * and the hatch line just compute below
0122  * We try to made a polyline with all points witch are on the current hatch and on the next hacth
0123  * (distant of stripwidth form current hatch)
0124  * conflictNumHatchLineTab give us something like this for current and next hatch
0125  * current   next                                                current    next
0126  *    4       4              if we consider that                   ,4        ,4
0127  *    0       5              we know the compute hatch             '0        '5
0128  *    1       3              lines, we could link                  ,1        ,3
0129  *    3       2              some of theses line numbers           '3        '2
0130  *    5                        so ->>                              ,5
0131  *    2                                                            '2
0132  *  And we have to add some points when  HatchShiftToMacthPoint(point) is between current
0133  * and next hatch :  We add a point B on intersection of line 0 and 1
0134  * current   next                                                current    next
0135  *    ,4             ,4
0136  *    '0    B(0,1)   '5
0137  *    ,1
0138  *    '3             ,3
0139  *    ,5             '2
0140  *    '2
0141  *
0142  * Now we have to match a way to traverse all of theses lines. We have 3 solutions to go from
0143  * one line to another :
0144  * - go to the next point if there is one between current and next hatch
0145  * - go to the same line but on another hatch
0146  * - go to the next tach point
0147  * If there is no solution, we have to close the polyline strip and go to another point until
0148  * all are compute
0149  */
0150 
0151 /** first, we have to match 7 different cases
0152  * 1- all strip hatch are entirely in the polyline
0153  * 2- the first strip begin before the polyline and the last end in the polyline
0154  * 3- the first strip begin before the polyline and the last ends after
0155  * 4- the first strip is entierly in the polyline and the last ends after
0156  * 5- the strip has only an intersection with the second hatch sequence (if it has only an intersection
0157  *    with the first hatch sequence, it is case 2
0158  * 6- the strip has a full intersection
0159  * 7- the strip has no intersection !
0160  */
0161 
0162 inline bool hatcher::compute_polyline (vec3f* tabPoints,unsigned int aNumber) {
0163   std::vector<vec3f> firstComputePoints;   // copy first Points in
0164   std::vector<vec3f> secondComputePoints;   // copy first Points in
0165   std::vector<bool> firstComputePointsEnable; // table of already compute points for first hatch
0166   std::vector<bool> secondComputePointsEnable;// table of already compute points for second hatch
0167   std::vector< std::vector<int> > firstComputeConflictNumHatchLineTab; // copy firstComputeConflictNumHatchLineTab in
0168 
0169   int firstComputeFirstNumHatch =0;
0170   unsigned int firstComputeNumberHatchToDraw =0;
0171   float firstHatchShiftToMatchFirstPoint = FLT_MAX; // use in one case when there is no intersection points: to test we have to fill all the polygone
0172   float secondHatchShiftToMatchFirstPoint = FLT_MAX; // use in one case when there is no intersection points: to test we have to fill all the polygone
0173   //call compute for first set of hatch
0174   if ( !compute_single_polyline (tabPoints,aNumber))
0175     return false;
0176   if (fStripWidth ==0)
0177     return true;
0178 
0179 
0180   //save values
0181   for (unsigned int a =0;a<fPoints.size();a++){
0182     firstComputePoints.push_back(fPoints[a]);
0183   }
0184 
0185   firstComputeConflictNumHatchLineTab.resize(fConflictNumHatchLineTab.size());
0186   for (unsigned int a=0;a<fConflictNumHatchLineTab.size();a++){
0187     firstComputeConflictNumHatchLineTab[a].clear();
0188     for (unsigned int b=0;b<fConflictNumHatchLineTab[a].size();b++){
0189       firstComputeConflictNumHatchLineTab[a].push_back(fConflictNumHatchLineTab[a][b]);
0190     }
0191   }
0192   firstComputeFirstNumHatch = fFirstNumHatch;
0193   firstComputeNumberHatchToDraw = fNumberHatchToDraw;
0194   firstHatchShiftToMatchFirstPoint = fHatchShiftToMatchPointVec[0];
0195   //change the offset vector
0196   fOffset = fOffset+fShiftVec*fStripWidth;
0197 
0198   //call compute for second set of hatch
0199   if ( !compute_single_polyline (tabPoints,aNumber))
0200     return false;
0201 
0202   //save values
0203   for (unsigned int a =0;a<fPoints.size();a++){
0204     secondComputePoints.push_back(fPoints[a]);
0205   }
0206 
0207   secondHatchShiftToMatchFirstPoint = fHatchShiftToMatchPointVec[0];
0208 
0209 
0210   // initialize values
0211   fPoints.clear();
0212   fVertices.clear();
0213 
0214   int specialCase=1;
0215 
0216   //first hatch, case 1
0217   if ((firstComputeFirstNumHatch == fFirstNumHatch) && (firstComputeNumberHatchToDraw == fNumberHatchToDraw) && (firstComputeNumberHatchToDraw !=0)) {
0218     specialCase =1;
0219   }
0220   //first hatch, case 2
0221   else if ((firstComputeFirstNumHatch > fFirstNumHatch) && (firstComputeNumberHatchToDraw < fNumberHatchToDraw) && (firstComputeNumberHatchToDraw !=0)) {
0222     //insert a empty element at the beginning
0223     firstComputeConflictNumHatchLineTab.insert(firstComputeConflictNumHatchLineTab.begin(), firstComputeConflictNumHatchLineTab.back());
0224     firstComputeConflictNumHatchLineTab[0].resize(0);
0225     firstComputeFirstNumHatch--;
0226     firstComputeNumberHatchToDraw ++;
0227     firstComputeConflictNumHatchLineTab[0].clear();
0228     specialCase =2;
0229 
0230   }   //second hatch, case 3
0231   else   if (((firstComputeFirstNumHatch > fFirstNumHatch) && (firstComputeNumberHatchToDraw == fNumberHatchToDraw)) && (firstComputeNumberHatchToDraw !=0)) {
0232     //insert a empty element at the beginning
0233     firstComputeConflictNumHatchLineTab.insert(firstComputeConflictNumHatchLineTab.begin(),firstComputeConflictNumHatchLineTab.back());
0234     firstComputeConflictNumHatchLineTab[0].resize(0);
0235     firstComputeConflictNumHatchLineTab[0].clear();
0236     //insert a empty element at the end
0237     fConflictNumHatchLineTab.push_back(firstComputeConflictNumHatchLineTab.back());
0238     fConflictNumHatchLineTab.back().resize(0);
0239     fConflictNumHatchLineTab.back().clear();
0240     firstComputeFirstNumHatch--;
0241     firstComputeNumberHatchToDraw ++;
0242     specialCase =3;
0243   }   //second hatch, case 4
0244   else   if (((firstComputeFirstNumHatch == fFirstNumHatch) && (firstComputeNumberHatchToDraw > fNumberHatchToDraw)) && (firstComputeNumberHatchToDraw !=0)) {
0245     //insert a empty element at the end
0246     fConflictNumHatchLineTab.push_back(firstComputeConflictNumHatchLineTab.back());
0247     fConflictNumHatchLineTab.back().resize(0);
0248     fConflictNumHatchLineTab.back().clear();
0249     specialCase =4;
0250 
0251   }   //second hatch, case 5
0252   else   if ((firstComputeNumberHatchToDraw ==0) && (fNumberHatchToDraw !=0)) {
0253     //insert a empty element at the beginning
0254     firstComputeConflictNumHatchLineTab.insert(firstComputeConflictNumHatchLineTab.begin(),firstComputeConflictNumHatchLineTab.back());
0255     firstComputeConflictNumHatchLineTab[0].resize(0);
0256     firstComputeConflictNumHatchLineTab[0].clear();
0257     firstComputeNumberHatchToDraw ++;
0258     specialCase =5;
0259 
0260   }   //second hatch, case 6
0261   else if (floorf(firstHatchShiftToMatchFirstPoint) != floorf(secondHatchShiftToMatchFirstPoint)) {
0262     specialCase =6;
0263 
0264     //fill all the polygone !
0265     fVertices.push_back(aNumber);
0266     for (unsigned int a =0;a<aNumber;a++){
0267       fPoints.push_back(tabPoints[a]);
0268     }
0269     return true;
0270   }
0271   else if (floorf(firstHatchShiftToMatchFirstPoint) == floorf(secondHatchShiftToMatchFirstPoint)) {
0272     specialCase =7;
0273     return true;
0274   } else {
0275 #ifdef TOOLS_HATCHER_DEBUG
0276     ::printf("hatcher::drawStripPolyline : WARNING there is a case witch was not done in the algotithm...possibly some drawing problems.\n\n");
0277 #endif
0278 
0279   }
0280 
0281 
0282   bool result;
0283   bool find; // temp variable
0284   int firstHatchComputePoint = 0; //first point number
0285   int secondHatchComputePoint = 0; //first point number
0286   unsigned int lineNumber;
0287   unsigned int firstPointTabInd =0;
0288   unsigned int secondPointTabInd=0;
0289   unsigned int currentHatch; // 0 is first, 1 is second, 2 is one or other !!
0290   unsigned int solution; //default for beginning
0291   unsigned int indTmp;
0292   unsigned int oldSolution;
0293   for (unsigned int indHatch =0;indHatch<firstComputeNumberHatchToDraw;indHatch++) {
0294 
0295 
0296     currentHatch =0; // 0 is first, 1 is second
0297     solution =99; //default for beginning
0298     indTmp = 0;
0299     lineNumber = 0;
0300     secondComputePointsEnable.clear();
0301     firstComputePointsEnable.clear();
0302     for (unsigned int a=0;a<firstComputeConflictNumHatchLineTab[indHatch].size();a++){
0303       firstComputePointsEnable.push_back(false);}
0304     for (unsigned int a=0;a<fConflictNumHatchLineTab[indHatch].size();a++){
0305       secondComputePointsEnable.push_back(false);}
0306 
0307     if ((indHatch == 0) && ((specialCase ==2) || (specialCase ==3) || (specialCase ==5))) {
0308       for (unsigned int a=0;a<firstComputeConflictNumHatchLineTab[indHatch].size();a++){
0309         firstComputePointsEnable[a] = true;
0310       }
0311     }
0312     if ((indHatch == (firstComputeNumberHatchToDraw-1)) && ((specialCase ==3) || (specialCase ==4))) {
0313       for (unsigned int a=0;a<fConflictNumHatchLineTab[indHatch].size();a++){
0314         secondComputePointsEnable[a] = true;
0315       }
0316     }
0317 
0318     result = false;
0319     while (result == false) {
0320 
0321 
0322       //find a uncompute point for this set of hatch
0323       result =true;
0324       unsigned int b=0;
0325       while ((result == true) && (b<firstComputeConflictNumHatchLineTab[indHatch].size())) {
0326         if (firstComputePointsEnable[b] == false) {
0327           result =false;
0328           firstHatchComputePoint = b;
0329           lineNumber = firstComputeConflictNumHatchLineTab[indHatch][b];
0330           fPoints.push_back(firstComputePoints[b+firstPointTabInd]);
0331           fVertices.push_back(1);
0332           firstComputePointsEnable[b] = true;
0333           currentHatch = 0;
0334         }
0335         b++;
0336       }
0337       if (result ==true) {
0338         //find a uncompute point for this set of hatch
0339 
0340         while ((result == true) && (b<fConflictNumHatchLineTab[indHatch].size())) {
0341           if (secondComputePointsEnable[b] == false) {
0342             result =false;
0343             secondHatchComputePoint = b;
0344             lineNumber = fConflictNumHatchLineTab[indHatch][b];
0345             fPoints.push_back(secondComputePoints[b+secondPointTabInd]);
0346             fVertices.push_back(1);
0347             secondComputePointsEnable[b] = true;
0348             currentHatch = 1;
0349           }
0350           b++;
0351         }
0352       }
0353       if (result == true) {
0354       }
0355         solution =99; // to enter in the while
0356         while (solution !=0) {
0357           oldSolution = solution;
0358           solution =0; //default
0359           // get the line number for this point
0360           /** Now we have to match a way to traverse all of theses lines. We have 3 solutions to go from
0361            * one line to another :
0362            * - go to the next point if there is one between current and next hatch
0363            * - go to the same line but on another hatch
0364            * - go to the next hatch point
0365            */
0366           if (currentHatch != 1) {
0367 
0368             if (oldSolution != 3) {                   // could go to first solution
0369               int index =0;
0370               if ((firstHatchComputePoint % 2 == 0) && (firstComputePointsEnable[firstHatchComputePoint+1] == false))   index =1;
0371               else if ((firstHatchComputePoint % 2 != 0) && (firstComputePointsEnable[firstHatchComputePoint-1] == false))  index = -1;
0372               if (index !=0) {
0373                 solution = 1;
0374                 oldSolution = 0;
0375                 firstHatchComputePoint = firstHatchComputePoint+index;
0376                 fPoints.push_back(firstComputePoints[firstHatchComputePoint+firstPointTabInd]);
0377                 fVertices.back() ++;
0378                 firstComputePointsEnable[firstHatchComputePoint] = true;
0379                 lineNumber = firstComputeConflictNumHatchLineTab[indHatch][firstHatchComputePoint];
0380               }
0381             }
0382             if (solution == 0) {                  // could go to second solution
0383               indTmp = 0;
0384               while ((solution == 0) && (indTmp < fConflictNumHatchLineTab[indHatch].size())) {
0385                 if ((fConflictNumHatchLineTab[indHatch][indTmp] == (int)lineNumber) && (secondComputePointsEnable[indTmp] == false)) {
0386                   solution =2;
0387                   oldSolution = 0;
0388                   fPoints.push_back(secondComputePoints[indTmp+secondPointTabInd]);
0389                   fVertices.back() ++;
0390                   secondComputePointsEnable[indTmp] = true;
0391                   lineNumber = fConflictNumHatchLineTab[indHatch][indTmp];
0392                   secondHatchComputePoint = indTmp;
0393                   currentHatch =1;
0394                 }
0395                 indTmp ++;
0396               }
0397             }
0398             if (solution == 0) {                    // could go to first solution
0399               indTmp = 0;
0400               while ((solution == 0) && (indTmp < aNumber)) {
0401 
0402                 if ((fHatchShiftToMatchPointVec[indTmp] > ((float)firstComputeFirstNumHatch+(float)indHatch-fStripWidth))
0403                     && (fHatchShiftToMatchPointVec[indTmp] < ((float)firstComputeFirstNumHatch+(float)indHatch))
0404                     && ((indTmp == lineNumber) || (indTmp==lineNumber+1) || ((lineNumber == (aNumber-1)) && (indTmp ==0)))) {
0405                   find = false;
0406                   unsigned a =0;
0407                   while ((a<fVertices.back()) && (find == false)) {
0408                     if ((tabPoints[indTmp][0] == fPoints[a][0]) && (tabPoints[indTmp][1] == fPoints[a][1]) && (tabPoints[indTmp][2] == fPoints[a][2])) find = true;
0409                     a++;
0410                   }
0411                   if (find == false){
0412                     solution = 3;
0413                     oldSolution = 0;
0414                     currentHatch =2;
0415                     fPoints.push_back(tabPoints[indTmp]);
0416                     fVertices.back() ++;
0417                     if (lineNumber == indTmp) {
0418                       if (indTmp >0)  lineNumber =  indTmp-1;
0419                       else lineNumber = aNumber-1;
0420                     }
0421                     else {
0422                       if (indTmp < aNumber-1)  lineNumber =  indTmp;
0423                       else lineNumber = 0;
0424                     }
0425                   }
0426                 }
0427                 indTmp++;
0428               }
0429             }
0430           } // end of current hatch
0431 
0432             //test of second hatch if currentHatch is second
0433           if ((oldSolution != 0) && (solution !=2) && (currentHatch !=0)) {
0434 
0435             if (oldSolution != 3){                   // could go to first solution
0436               int index =0;
0437               if ((secondHatchComputePoint % 2 == 0) && (secondComputePointsEnable[secondHatchComputePoint+1] == false))   index =1;
0438               else if ((secondHatchComputePoint % 2 != 0) && (secondComputePointsEnable[secondHatchComputePoint-1] == false))  index = -1;
0439               if (index !=0){
0440                 solution = 1;
0441                 secondHatchComputePoint = secondHatchComputePoint+index;
0442                 fPoints.push_back(secondComputePoints[secondHatchComputePoint+secondPointTabInd]);
0443                 fVertices.back() ++;
0444                 secondComputePointsEnable[secondHatchComputePoint] = true;
0445                 lineNumber = fConflictNumHatchLineTab[indHatch][secondHatchComputePoint];
0446               }
0447             }
0448             if (solution == 0) {                  // could go to second solution
0449               indTmp = 0;
0450               while ((solution == 0) && (indTmp < firstComputeConflictNumHatchLineTab[indHatch].size())) {
0451                 if ((firstComputeConflictNumHatchLineTab[indHatch][indTmp] == (int)lineNumber) && (firstComputePointsEnable[indTmp] == false)) {
0452                   solution =2;
0453                   fPoints.push_back(firstComputePoints[indTmp+firstPointTabInd]);
0454                   fVertices.back() ++;
0455                   firstComputePointsEnable[indTmp] = true;
0456                   lineNumber = firstComputeConflictNumHatchLineTab[indHatch][indTmp];
0457                   firstHatchComputePoint = indTmp;
0458                   currentHatch =0;
0459                 }
0460                 indTmp ++;
0461               }
0462             }
0463             if (solution == 0) {                    // could go to first solution
0464               indTmp = 0;
0465               while ((solution == 0) && (indTmp < aNumber)) {
0466 
0467                 if ((fHatchShiftToMatchPointVec[indTmp] > ((float)fFirstNumHatch+(float)indHatch-fStripWidth))
0468                     && (fHatchShiftToMatchPointVec[indTmp] < ((float)fFirstNumHatch+(float)indHatch))
0469                     && ((indTmp == lineNumber) || (indTmp==lineNumber+1) || ((lineNumber == (aNumber-1)) && (indTmp ==0)))) {
0470                   find = false;
0471                   unsigned a =0;
0472                   while ((a<fVertices.back()) && (find == false)) {
0473                     if ((tabPoints[indTmp][0] == fPoints[a][0]) && (tabPoints[indTmp][1] == fPoints[a][1]) && (tabPoints[indTmp][2] == fPoints[a][2])) find = true;
0474                     a++;
0475                   }
0476                   if (find == false){
0477                     currentHatch =2;
0478                     solution = 3;
0479                     fPoints.push_back(tabPoints[indTmp]);
0480                     fVertices.back() ++;
0481                     if (lineNumber == indTmp) {
0482                       if (indTmp >0)  lineNumber =  indTmp-1;
0483                       else lineNumber = aNumber-1;
0484                     }
0485                     else {
0486                       if (indTmp < aNumber-1)  lineNumber =  indTmp;
0487                       else lineNumber = 0;
0488                     }
0489                   }
0490                 }
0491                 indTmp++;
0492               }
0493             }
0494           } // end of current hatch
0495           if (solution == 0) {
0496             // the end for this polyline
0497             // close polyline
0498             fPoints.push_back(fPoints[fPoints.size()-fVertices.back()]);
0499             fVertices.back() ++;
0500             result =true;
0501           }
0502         } // while solution !=0
0503         //      } // if result
0504     } // while result
0505     for (unsigned int a =0;a<fVertices.size();a++){
0506 #ifdef TOOLS_HATCHER_DEBUG
0507       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");
0508 #endif
0509     }
0510 
0511     firstPointTabInd += firstComputeConflictNumHatchLineTab[indHatch].size();
0512     secondPointTabInd += fConflictNumHatchLineTab[indHatch].size();
0513   } //end for
0514   return true;
0515 }
0516 
0517 
0518 
0519 
0520 //////////////////////////////////////////////////////////////////////////////
0521 // draw the hatch into the polyline bounding box giving in argument
0522 // return false if :
0523 //    - All points are not in the same plan
0524 //    - There is a precision error on one or more point
0525 //////////////////////////////////////////////////////////////////////////////
0526 
0527 inline bool hatcher::compute_single_polyline (vec3f* tabPoints,unsigned int aNumber) {
0528   std::vector<vec3f> listNormalVec;
0529   int numberOfPolylinePoints =0;
0530   fPoints.resize(0);
0531   fPoints.clear();
0532   int precisionError =0;
0533   unsigned int firstOffset =0;
0534   fFirstNumHatch =0;
0535   fNumberHatchToDraw =0;
0536   fVertices.resize(0);
0537   fVertices.clear();
0538 
0539   if ( tabPoints[0].equals(tabPoints[1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) {
0540     firstOffset =1;  }
0541 
0542   vec3f* listPoints = new vec3f[aNumber+1-firstOffset];
0543 
0544   for (unsigned int i=0;i<aNumber;i++){
0545     if ((i==0) || (listPoints[i-1] !=tabPoints[i+firstOffset])) {
0546       listPoints[numberOfPolylinePoints] = tabPoints[i+firstOffset];
0547       numberOfPolylinePoints++;
0548     }
0549   }
0550 
0551   // add the first point on last position to close the line
0552   if ( ! listPoints[0].equals(listPoints[numberOfPolylinePoints-1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) {
0553     listPoints[numberOfPolylinePoints]=listPoints[0];
0554     numberOfPolylinePoints ++;
0555   }
0556 
0557   // use to test the polyline and to build the shift vector. A is the first point,
0558   // B second and C the last (in fact, the last-1)!
0559   vec3f AB,AC;
0560   AB.setValue(listPoints[1].getValue()[0]-listPoints[0].getValue()[0],
0561               listPoints[1].getValue()[1]-listPoints[0].getValue()[1],
0562               listPoints[1].getValue()[2]-listPoints[0].getValue()[2]); // Vector A->B
0563 
0564   fResolveResult = RESOLVE_COLINEAR;
0565   unsigned int test = numberOfPolylinePoints-1;
0566   while ((fResolveResult !=0) && (test>1)) {
0567     test--;
0568     AC.setValue(listPoints[test].getValue()[0]-listPoints[0].getValue()[0],
0569                 listPoints[test].getValue()[1]-listPoints[0].getValue()[1],
0570                 listPoints[test].getValue()[2]-listPoints[0].getValue()[2]);
0571 
0572     // test if AB != AC*i
0573     resolve_system( AB,
0574                    AC,
0575                    vec3f(.0f,.0f,.0f));
0576   }
0577   if (fResolveResult == RESOLVE_COLINEAR) {
0578 #ifdef TOOLS_HATCHER_DEBUG
0579     ::printf("hatcher::drawPolyline : ERROR all the point you give are colinear!\n\n");
0580     for (unsigned int a =0;a<aNumber;a++) {
0581       printf(" %f %f %f \n",listPoints[a][0],listPoints[a][1],listPoints[a][2]);  }
0582 #endif
0583     delete [] listPoints;
0584     return false;
0585   }
0586 
0587   ///////////////////////////////////////////////////////////////
0588   // creation of the dirVec. It is done with the dirAngle field
0589   // The angle is the one between the first line (point 1-point0)
0590   // and the dirVec, on the plan delimited by polyline
0591   // Given in the direct axis ((point1-point0),(lastPoint-point0),normalPlanVec)
0592   // Normal plane Vector = AB x AC
0593   ///////////////////////////////////////////////////////////////
0594   if (fFirstPolyline) {
0595 
0596     fFirstPolyline = false;
0597 
0598     fNormal.setValue(AB[1]*AC[2]-AB[2]*AC[1],
0599                                AB[2]*AC[0]-AB[0]*AC[2],
0600                                AB[0]*AC[1]-AB[1]*AC[0]);
0601 
0602 
0603     // ABPerp Vector = normal x AB
0604     vec3f ABPerpVector;
0605     ABPerpVector.setValue(fNormal[1]*AB[2]-fNormal[2]*AB[1],
0606                           fNormal[2]*AB[0]-fNormal[0]*AB[2],
0607                           fNormal[0]*AB[1]-fNormal[1]*AB[0]);
0608 
0609     float normAB =(float)std::sqrt(std::pow(AB[0],2)+
0610                         std::pow(AB[1],2)+
0611                         std::pow(AB[2],2));
0612     float normABPerpVector =(float)std::sqrt(std::pow(ABPerpVector[0],2)+
0613                         std::pow(ABPerpVector[1],2)+
0614                         std::pow(ABPerpVector[2],2));
0615 
0616     float j = std::tan(fDirAngle)*normAB/normABPerpVector;
0617 
0618     if (normABPerpVector == 0){  // never done (should be test before)
0619 #ifdef TOOLS_HATCHER_DEBUG
0620       ::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");
0621 #endif
0622       delete [] listPoints;
0623       return false;
0624     }
0625 
0626     fDirVec = AB +(float)j*ABPerpVector;
0627     // normalize vector to unit on X or on Y
0628     if (fDirVec.getValue()[0] ==0){
0629       fDirVec[0] = fPrecisionFactor; // to get rid of somes errors
0630       fDirVec = fDirVec/fDirVec.getValue()[1]; // normalize on Y because X will be a big value
0631     } else {
0632       fDirVec = fDirVec/fDirVec.getValue()[0];
0633     }
0634 
0635     ///////////////////////////////////////////////////////////////
0636     // creation of the shiftVec thanks to the shift field
0637     ///////////////////////////////////////////////////////////////
0638 
0639     vec3f dirShiftVector;
0640     dirShiftVector.setValue(fNormal[1]*fDirVec.getValue()[2]-fNormal[2]*fDirVec.getValue()[1],
0641                             fNormal[2]*fDirVec.getValue()[0]-fNormal[0]*fDirVec.getValue()[2],
0642                             fNormal[0]*fDirVec.getValue()[1]-fNormal[1]*fDirVec.getValue()[0]);
0643 
0644     // normalize vector to match the shift size
0645     float param = 1.0f;
0646     param = (float)std::sqrt((std::pow(fShift,2))/(
0647                                         std::pow(dirShiftVector[0],2)+
0648                                         std::pow(dirShiftVector[1],2)+
0649                                         std::pow(dirShiftVector[2],2)));
0650     fShiftVec = dirShiftVector*param;
0651 
0652     // compute offset only if it was not given
0653     if ((fOffset[0] == FLT_MAX) && (fOffset[1] == FLT_MAX) && (fOffset[2] == FLT_MAX)){
0654       fOffset = listPoints[0]+fShiftVec*fOffsetValue;
0655     }
0656   }
0657 
0658 
0659   /////////////////////////////////////////////
0660   // START to compute
0661   // We compute each line one by one to know witch hatch will be draw thrue this line
0662   // we try to know the result of
0663   // (origin_point_of_hatch)+i*(directionVector)+j*(shiftVector) = each_point_of_polyline
0664   // We will be interest only on j factor for the moment. This factor represent the offset
0665   // between the Origin point of the hatch and the compute point of the polyline
0666   // We put results in a float table
0667   //
0668   // We also have to memorize the min and max number of the hatch to be draw
0669   // Point                  0 1 2 3 4 5 6 ...n 1
0670   // hatchShiftToMatchPoint   5 7 2 6 7 8 5 ...2 5
0671   // min = 1 max = 8   -> 8 hatch to draw
0672   ////////////////////////////////////////////
0673 
0674   fHatchShiftToMatchPointVec.resize(numberOfPolylinePoints+1);
0675   float minShiftHatch =FLT_MAX;
0676   float maxShiftHatch =-FLT_MAX;
0677   vec2f res;
0678 
0679   for (int a=0;a<numberOfPolylinePoints;a++) {
0680     res = resolve_system(fDirVec.getValue(),
0681                         fShiftVec,
0682                         listPoints[a]-fOffset);
0683     // test result
0684     if (fResolveResult ==0 ) {
0685          fHatchShiftToMatchPointVec[a] = res[1];
0686          if (res[1]>maxShiftHatch) {
0687            maxShiftHatch = res[1];
0688          }
0689          if (res[1]<minShiftHatch) {
0690            minShiftHatch = res[1];
0691          }
0692     }
0693     else {  // never done (should be test before)
0694 #ifdef TOOLS_HATCHER_DEBUG
0695       ::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);
0696 #endif
0697       delete [] listPoints;
0698       return false;
0699     }
0700   }
0701   // for the first point to close the polyline
0702   fHatchShiftToMatchPointVec[numberOfPolylinePoints] = fHatchShiftToMatchPointVec[0];
0703   fFirstNumHatch = (int)(ceilf(minShiftHatch));
0704   fNumberHatchToDraw = (int)(floorf(maxShiftHatch)-fFirstNumHatch+1);
0705   if ((int)(floorf(maxShiftHatch)-fFirstNumHatch+1) <0) fNumberHatchToDraw =0;
0706 
0707   int moreNumberHatchToDraw = fNumberHatchToDraw+1;
0708   std::vector<vec3f> listHatchStartPoint;
0709   std::vector<vec3f> listHatchEndPoint;
0710   std::vector<int> numberOfStartEndPointsVec;
0711 
0712   fConflictNumHatchLineTab.resize(moreNumberHatchToDraw);
0713 
0714   // initialize tab
0715     for (int a=0;a<moreNumberHatchToDraw;a++) {
0716       numberOfStartEndPointsVec.push_back(0);
0717       listHatchStartPoint.push_back(vec3f(.0f,.0f,.0f));
0718       listHatchEndPoint.push_back(vec3f(.0f,.0f,.0f));
0719       fConflictNumHatchLineTab[a].clear();
0720     }
0721 
0722   /////////////////////////////////////////////
0723   // Compute the normalize shift vector for all lines
0724   // the normal Vector for point 3 to 4 will be listNormalvec[2]
0725   /////////////////////////////////////////////
0726 
0727   for (int a=0;a<numberOfPolylinePoints-1;a++) {
0728     res = resolve_system(fDirVec.getValue(),
0729                         vec3f(listPoints[a].getValue()[0]-listPoints[a+1].getValue()[0],
0730                                 listPoints[a].getValue()[1]-listPoints[a+1].getValue()[1],
0731                                 listPoints[a].getValue()[2]-listPoints[a+1].getValue()[2]),
0732                         -fShiftVec);
0733     if (fResolveResult ==0 ) {
0734       listNormalVec.push_back(vec3f(res[1]*(listPoints[a+1].getValue()[0]-listPoints[a].getValue()[0]),
0735                                        res[1]*(listPoints[a+1].getValue()[1]-listPoints[a].getValue()[1]),
0736                                        res[1]*(listPoints[a+1].getValue()[2]-listPoints[a].getValue()[2])
0737                                        ));
0738     }
0739     else  if (fResolveResult == RESOLVE_Z_ERROR ) {  // never done (should be test before)
0740 #ifdef TOOLS_HATCHER_DEBUG
0741       ::printf("hatcher::drawPolyline : ERROR one or more of your polyline points are not on the same plan !\n\n");
0742 #endif
0743       delete [] listPoints;
0744       return false;
0745     }
0746     else{
0747       listNormalVec.push_back(vec3f(FLT_MAX,FLT_MAX,FLT_MAX));
0748       //      listNormalVec.append(new vec3f(FLT_MAX,FLT_MAX,FLT_MAX));
0749     }
0750  }
0751 
0752   /////////////////////////////////////////////
0753   // Compute the hatchShiftToMatchPointVec table to try to get the start
0754   // and end point of each hatch
0755   // if there is more than one start/end point, we will resolve it later. For the moment,
0756   // we put confict points into a table
0757   // HatchNumber        1     2     3      4      5      6      7     8    9
0758   // listHatchStartPoint  1,0,0  1,1,0  0,0,1  0,1,0  1,1,0  0,2,0  1,1,4
0759   // listHatchEndPoint    ..............
0760   // conflictNumHatchLineTab 5 6 7
0761   // line Number is 0 for (point[0]->point[1])
0762   // We put each line number into the conflict table to be sure to get all the lines
0763   //  in conflict. When we will thest the value of the conflicy table, it should
0764   // be greater than 2 to have a conflict
0765   /////////////////////////////////////////////
0766 
0767   vec3f newPoint;
0768   int minHatch;
0769   int maxHatch;
0770   int hatchIndice =0;
0771 
0772   for (int indPolyline=0;indPolyline<numberOfPolylinePoints-1;indPolyline++) {
0773     minHatch = (int)(ceilf(fHatchShiftToMatchPointVec[indPolyline]));
0774     maxHatch = (int)(floorf(fHatchShiftToMatchPointVec[indPolyline+1]));
0775 
0776     if (fHatchShiftToMatchPointVec[indPolyline+1] <fHatchShiftToMatchPointVec[indPolyline]) {
0777       minHatch =(int)(ceilf(fHatchShiftToMatchPointVec[indPolyline+1]));
0778       maxHatch = (int)(floorf(fHatchShiftToMatchPointVec[indPolyline]));
0779     }
0780     for (int b=minHatch;b<=maxHatch;b++) {  // for all number of hatch fund
0781       // compute new point
0782       hatchIndice = b-fFirstNumHatch;
0783 
0784       newPoint.setValue(listPoints[indPolyline].getValue()[0]+
0785                         listNormalVec[indPolyline][0]*(b-fHatchShiftToMatchPointVec[indPolyline]),
0786                         listPoints[indPolyline].getValue()[1]+
0787                         listNormalVec[indPolyline][1]*(b-fHatchShiftToMatchPointVec[indPolyline]),
0788                         listPoints[indPolyline].getValue()[2]+
0789                         listNormalVec[indPolyline][2]*(b-fHatchShiftToMatchPointVec[indPolyline]));
0790 
0791       if (numberOfStartEndPointsVec[hatchIndice] == 0) {// it is the first point
0792         //compute point and save it
0793         // the start point will be :
0794         // Point_of_the_line + normalVec *
0795         //(number_of_hatch_to_compute - number_of_hatch_corresponding_to_first_point_of_line)
0796         //
0797         if ( (listNormalVec[indPolyline][0] != FLT_MAX)
0798             && (listNormalVec[indPolyline][1] != FLT_MAX)
0799             && (listNormalVec[indPolyline][2] != FLT_MAX)) {
0800           listHatchStartPoint[hatchIndice] = vec3f(newPoint);
0801            fConflictNumHatchLineTab[hatchIndice].push_back(indPolyline);
0802            numberOfStartEndPointsVec[hatchIndice]++;
0803          }
0804       } else if (numberOfStartEndPointsVec[hatchIndice] == 1) { // it is the second point
0805         //compute point and save it (same point as previous )
0806         // the start point will be :
0807         // Point_of_the_line + normalVec *
0808         //  (number_of_hatch_to_compute - number_of_hatch_corresponding_to_first_point_of_line)
0809         // store only if newPoint is != start
0810         if ((listNormalVec[indPolyline][0] != FLT_MAX)
0811             && (listNormalVec[indPolyline][1] != FLT_MAX)
0812             && (listNormalVec[indPolyline][2] != FLT_MAX)) {
0813           listHatchEndPoint[hatchIndice] = vec3f(newPoint);
0814           fConflictNumHatchLineTab[hatchIndice].push_back(indPolyline);
0815           numberOfStartEndPointsVec[hatchIndice]++;
0816         }
0817       } else { // there is a conflict, we don't compute anything except for conflicts on points
0818         // witch are already compute
0819         // case of the hatch will be draw on a point of the polyline,
0820         // so it match 2 lines + another
0821         fConflictNumHatchLineTab[hatchIndice].push_back(indPolyline); // put the line number in conflict table
0822       }
0823     }
0824   }
0825 
0826   /////////////////////////////////////////////
0827   // Compute the numHatchLine tab and draw correct points
0828   /////////////////////////////////////////////
0829   std::vector<float> listCoefDirHatch(fNumberHatchToDraw);
0830   std::vector<vec3f> listConflictPoints(numberOfPolylinePoints);
0831 
0832   vec3f ABVec,tempVec;
0833   int valid =false;
0834   bool drawEnabled = false; // true : we could draw second point, false we wait for the first
0835   float temp=0;
0836   int tempInt =0;
0837   float nextPointConflictHatchNumber = -FLT_MAX;
0838   float currentPointConflictHatchNumber = -FLT_MAX;
0839   std::vector<unsigned int> orderConflictLineNumber;
0840 
0841   for (unsigned int hatchNumber =0;hatchNumber<fNumberHatchToDraw;hatchNumber++) {
0842     if ( fConflictNumHatchLineTab[hatchNumber].size() <= 2) {
0843       if (!listHatchStartPoint[hatchNumber].equals(listHatchEndPoint[hatchNumber],FLT_EPSILON*FLT_EPSILON*10)) {
0844         fPoints.push_back(listHatchStartPoint[hatchNumber]);
0845         fPoints.push_back(listHatchEndPoint[hatchNumber]);
0846         fVertices.push_back(2);
0847       }
0848     } else { // there is a conflict
0849       // We read the conflict table and compute all the conflict lines
0850       // conflict is on hatch number hatchNumber+ firstNumHatch
0851       // Compute the equation on the conflict line (called ABVec ):
0852       // i*dirVec - j*ABVec = A-(offset + shiftVec * numberHatchToDraw)
0853       // and store the i parameter
0854       // then we
0855 
0856       listConflictPoints.clear();
0857       listCoefDirHatch.clear();
0858       std::vector <unsigned int> toRemove;
0859       for (unsigned int conflictLineNumber=0;conflictLineNumber<fConflictNumHatchLineTab[hatchNumber].size();conflictLineNumber++ )
0860         {
0861 
0862           ABVec.setValue(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]+1].getValue()[0]-listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[0],
0863                          listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]+1].getValue()[1]-listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[1],
0864                          listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]+1].getValue()[2]-listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[2]);
0865 
0866           res = resolve_system(fDirVec.getValue(),
0867                               ABVec,
0868                               vec3f(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[0]-fOffset[0]-((float)hatchNumber+(float)fFirstNumHatch)*fShiftVec[0],
0869                                       listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[1]-fOffset[1]-((float)hatchNumber+(float)fFirstNumHatch)*fShiftVec[1],
0870                                       listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]].getValue()[2]-fOffset[2]-((float)hatchNumber+(float)fFirstNumHatch)*fShiftVec[2]));
0871 
0872           if (fResolveResult ==0 ) {
0873             // we store results
0874             listCoefDirHatch.push_back(2);
0875             listCoefDirHatch.pop_back();
0876             listCoefDirHatch.push_back(res[0]);
0877             res[1] = -res[1];
0878             listConflictPoints.push_back(vec3f(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictLineNumber]]+ABVec*res[1]));
0879           }
0880           else if (fResolveResult != RESOLVE_COLINEAR){
0881 #ifdef TOOLS_HATCHER_DEBUG
0882             printf("hatcher : Precision error during compute on hatch number%d\n\n",hatchNumber);
0883 #endif
0884             precisionError++;
0885           } else {
0886             toRemove.push_back(conflictLineNumber);
0887           }
0888         }
0889 
0890       if (toRemove.size()) {
0891         for (unsigned int conflictLineNumber=0;conflictLineNumber<fConflictNumHatchLineTab[hatchNumber].size();conflictLineNumber++ ) {
0892         }
0893         // remove potential colinear problems
0894         for (unsigned int aa=0;aa<toRemove.size();aa++) {
0895           unsigned int ind = 0;
0896           for (std::vector<int>::iterator it = fConflictNumHatchLineTab[hatchNumber].begin();it !=fConflictNumHatchLineTab[hatchNumber].end();it++) {
0897             if (ind == toRemove[aa]) {
0898               fConflictNumHatchLineTab[hatchNumber].erase(it);
0899               break;
0900             }
0901             ind++;
0902           }
0903         }
0904         for (unsigned int conflictLineNumber=0;conflictLineNumber<fConflictNumHatchLineTab[hatchNumber].size();conflictLineNumber++ ) {
0905         }
0906       }
0907       if (listCoefDirHatch.size() != 0) { // all points are resolve_system errors (RESOLVE_COLINEAR or RESOLVE_Z_ERROR
0908 
0909         // now, we have to sort all coef dir from minus to max
0910         // and at the same time, reorder the conflict ponts and the conflict line number
0911         // this algorithm is not optimum...
0912         valid = false;
0913         while (valid ==false )
0914           {
0915             valid = true;
0916             for (unsigned int sort =0;sort< listCoefDirHatch.size()-1;sort++)
0917               {
0918                 if (listCoefDirHatch[sort]>listCoefDirHatch[sort+1]) {
0919 
0920                   temp = listCoefDirHatch[sort];
0921                   listCoefDirHatch[sort] = listCoefDirHatch[sort+1];
0922                   listCoefDirHatch[sort+1] =temp;
0923                   tempVec = listConflictPoints[sort];
0924                   listConflictPoints[sort] = listConflictPoints[sort+1];
0925                   listConflictPoints[sort+1] = tempVec;
0926                   tempInt = fConflictNumHatchLineTab[hatchNumber][sort];
0927                   fConflictNumHatchLineTab[hatchNumber][sort] = fConflictNumHatchLineTab[hatchNumber][sort+1];
0928                   fConflictNumHatchLineTab[hatchNumber][sort+1] = tempInt;
0929                   valid= false;
0930                 }
0931               }
0932           }
0933 
0934         // once dir coef have been sort, we could draw lines !!
0935         //witch line had made a conflict ??? conflictNumHatchLineTab[a]
0936         unsigned int conflictNumber =0;
0937         orderConflictLineNumber.clear();
0938 
0939         drawEnabled = false;
0940         while (conflictNumber < fConflictNumHatchLineTab[hatchNumber].size()) { // while
0941           if (conflictNumber+1 == fConflictNumHatchLineTab[hatchNumber].size()) {
0942             if(drawEnabled) {
0943               drawEnabled =  false;
0944               fPoints.push_back(listConflictPoints[conflictNumber].getValue());
0945               orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]);
0946             }
0947           }
0948           else {
0949             // if the conflict point == next conflict point : that is a end/begin line conflict
0950             // else, this is not a big problem, we just have to invert the drawEnabled
0951             // (if we were drawing, we have to finish a line, else, we have to begin a line
0952             if ( !(listConflictPoints[conflictNumber].equals(listConflictPoints[conflictNumber+1],FLT_EPSILON*FLT_EPSILON*10))) {
0953               // special case of nextPointline=nextConflict point : hatch//line
0954               unsigned int follow=conflictNumber+1;
0955               bool overContour = false;
0956               while ((follow <fConflictNumHatchLineTab[hatchNumber].size()) &&
0957                      (listConflictPoints[conflictNumber].equals(listConflictPoints[follow],FLT_EPSILON*FLT_EPSILON*10))) {
0958                 follow++;
0959               }
0960               //test if next point is on the contour
0961               if(follow < fConflictNumHatchLineTab[hatchNumber].size()) {
0962                 if ((listConflictPoints[follow].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][follow]].getValue(),FLT_EPSILON*FLT_EPSILON*10))) {
0963                   if ((fConflictNumHatchLineTab[hatchNumber][follow] != 0) &&
0964                       (fConflictNumHatchLineTab[hatchNumber][follow] != numberOfPolylinePoints-1)) {
0965                     if ((listConflictPoints[conflictNumber].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][follow]-1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) ||
0966                         (listConflictPoints[conflictNumber].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][follow]+1].getValue(),FLT_EPSILON*FLT_EPSILON*10))) {
0967                       overContour = true;
0968                     }
0969                   }
0970                 }
0971               }
0972               int previous=conflictNumber-1;
0973               while ((previous >=0) &&
0974                      (listConflictPoints[conflictNumber].equals(listConflictPoints[previous],FLT_EPSILON*FLT_EPSILON*10))) {
0975                 previous--;
0976               }
0977               //test if next point is on the contour
0978               if(previous >= 0) {
0979                 if ((listConflictPoints[conflictNumber].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber]].getValue(),FLT_EPSILON*FLT_EPSILON*10))) {
0980                   if ((listConflictPoints[previous].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber]-1].getValue(),FLT_EPSILON*FLT_EPSILON*10)) ||
0981                       (listConflictPoints[previous].equals(listPoints[fConflictNumHatchLineTab[hatchNumber][conflictNumber]+1].getValue(),FLT_EPSILON*FLT_EPSILON*10))) {
0982                     overContour = true;
0983                   }
0984                 }
0985               }
0986               if (!overContour) { // we are not on a contour, we can draw
0987                 fPoints.push_back(listConflictPoints[conflictNumber].getValue());
0988                 orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]);
0989                 drawEnabled = drawEnabled?false:true;
0990                 if (drawEnabled) {
0991                   fVertices.push_back(2);
0992                 }
0993               } else { // else we have to stop drawing
0994                 if (drawEnabled) {
0995                   fPoints.push_back(listConflictPoints[conflictNumber].getValue());
0996                   orderConflictLineNumber.push_back(fConflictNumHatchLineTab[hatchNumber][conflictNumber]);
0997                   drawEnabled = false;
0998                 }
0999               }
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