Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-13 09:09:25

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