Salome HOME
5af5cd9bb1ff7ccf35c1f440a99f449a20d10af6
[modules/gui.git] / src / GLViewer / GLViewer_Tools.cxx
1 // File:      GLViewer_Tools.cxx
2 // Created:   April, 2005
3 // Author:    OCC team
4
5 //#include "GLViewerAfx.h"
6 #include "GLViewer_Tools.h"
7
8 #include <GL/gl.h>
9
10 #include <iostream>
11
12 using namespace std;
13
14 /****************************************************************************
15 **  Class:   GLViewer_LineList 
16 **  Descr:   Tools for distinct line
17 **  Module:  GLViewer
18 **  Created: UI team, 27.10.05
19 *****************************************************************************/
20 GLViewer_LineList::GLViewer_LineList( int size )
21 {
22   myRealSize = 2*size;
23   mySegmentNumber = 0;
24   myMainCoord = 0.0;
25
26   myArray = new double[myRealSize];
27
28   if( !myArray )
29   {
30     cout << "Can't allocate memory: " << size << endl;
31     myRealSize = 0;
32   }
33   else
34     memset( myArray, 0, myRealSize*sizeof(double) );
35 }
36
37 GLViewer_LineList::~GLViewer_LineList()
38 {
39   delete myArray;
40 }
41
42 bool GLViewer_LineList::addSegment( double coord1, double coord2 )
43 {
44   if( coord1 > coord2 )
45   {
46     double temp = coord1;
47     coord1 = coord2;
48     coord2 = temp;
49   }
50
51   if( 2*mySegmentNumber == myRealSize || !myArray )
52     return false;
53
54   int index = 0;
55   double c1, c2;
56   while( index < mySegmentNumber)
57   {
58     readSegment( index, c1, c2 );
59     if( coord1 < c1 && coord2 < c1 )
60     {
61       for( int i = mySegmentNumber; i > index - 1; i--)
62       {
63         myArray[2*i] = myArray[2*i-2]; //2*(i-1)
64         myArray[2*i+1] = myArray[2*i-1];//2*(i-1)+1
65       }
66       myArray[0] = coord1;
67       myArray[1] = coord2;
68       // mySegmentNumber; what is means ?
69       return true;
70     }
71     else if( coord1 < c1 && coord2 < c2 )
72     {
73       myArray[index*2] = coord1;
74       return true;
75     }
76     else if( c1 < coord1 && coord2 < c2 )
77     {
78       return true;
79     }
80     else if( coord1 < c2 && c2 < coord2 )
81     {
82       if( c1 > coord1 )
83         myArray[2*index] = coord1;
84
85       if( index != mySegmentNumber - 1 )
86       {
87         for( int i = index+1; i < mySegmentNumber; i++ )
88         {
89           if( coord2 < myArray[2*i] )
90           {
91             myArray[2*index+1] = coord2;
92             if( index+1 != i )
93             {
94               for( int j = 0; i+j < mySegmentNumber;j++ )
95               {
96                 myArray[2*(index+1+j)] = myArray[2*(i+j)];
97                 myArray[2*(index+1+j)+1] = myArray[2*(i+j)+1];
98               }
99               for( int k = 0; k < mySegmentNumber - i; k++ )
100               {
101                 myArray[2*(mySegmentNumber - 1- k)] = 0.0;
102                 myArray[2*(mySegmentNumber - 1- k)+1] = 0.0;
103               }
104               mySegmentNumber -= i - index-1;
105             }            
106             return true;
107           }
108           else if( coord2 < myArray[2*i+1] )
109           {
110             myArray[2*index+1] = myArray[2*i+1];
111             
112             for( int j = index+1; j < mySegmentNumber-1;j++ )
113             {
114               myArray[2*j] = myArray[2*(i+j-index)];
115               myArray[2*j+1] = myArray[2*(i+j-index)+1];
116             }
117             for( int k = 0; k < mySegmentNumber - i-1; k++ )
118             {
119               myArray[2*(mySegmentNumber - 1- k)] = 0.0;
120               myArray[2*(mySegmentNumber - 1- k)+1] = 0.0;
121             }
122             mySegmentNumber -= i - index;
123             return true;
124           }
125         }
126       }
127       else
128       {
129         myArray[2*index+1] = coord2;
130         return true;
131       }
132     }    
133     index++;
134   }
135
136   myArray[mySegmentNumber*2] = coord1;
137   myArray[mySegmentNumber*2+1] = coord2;
138   mySegmentNumber++;
139
140   return true;
141 }
142
143 bool GLViewer_LineList::readSegment( int theIndex, double& coord1, double& coord2 )
144 {
145   if( theIndex > mySegmentNumber || !myArray)
146     return false;
147
148   coord1 = myArray[theIndex*2];
149   coord2 = myArray[theIndex*2+1];
150
151   return true;
152 }
153
154 int GLViewer_LineList::contains( double thePoint ) const
155 {
156   if( !myArray || mySegmentNumber == 0 )
157     return -1;
158
159   for( int i = 0; i < mySegmentNumber; i++ )
160     if( myArray[2*i] <= thePoint && thePoint <= myArray[2*i+1] )
161       return i;
162
163   return -1;
164
165 }
166
167 bool GLViewer_LineList::removeSegment( int theIndex )
168 {
169   if( theIndex > mySegmentNumber || !myArray)
170     return false;
171
172   for( int i = theIndex; i < mySegmentNumber; i++ )
173   {
174     myArray[i*2] = myArray[(i+1)*2];
175     myArray[i*2+1] = myArray[(i+1)*2+1];
176   }
177   mySegmentNumber--;
178   myArray[mySegmentNumber*2] = 0.0;
179   myArray[mySegmentNumber*2+1] = 0.0;
180   return true;
181 }
182
183 bool GLViewer_LineList::removeSegment( double coord1, double coord2 )
184 {
185   if( coord1 > coord2 )
186   {
187     double temp = coord1;
188     coord1 = coord2;
189     coord2 = temp;
190   }
191
192   if( 2*mySegmentNumber == myRealSize || !myArray )
193     return false;
194
195   int index = 0;
196   double c1, c2;
197   while( index < mySegmentNumber)
198   {
199     readSegment( index, c1, c2 );
200     if( coord1 < c1 && coord2 < c1 )
201     {
202       //nothing
203       return true;
204     }
205     else if( coord1 < c1 && coord2 < c2 )
206     {
207       myArray[index*2] = coord2;
208       return true;
209     }
210     else if( c1 < coord1 && coord2 < c2 )
211     {
212       if( 2*mySegmentNumber == myRealSize )
213         return false;
214       for( int i = mySegmentNumber; i > index + 1; i-- )
215       {
216         myArray[2*i] = myArray[2*(i-1)];
217         myArray[2*i+1] = myArray[2*(i-1)+1];
218       }
219       myArray[2*(index+1)+1] = myArray[2*index+1];
220       myArray[2*(index+1)] = coord2;
221       myArray[2*index+1] = coord1;
222       mySegmentNumber++;
223       return true;
224     }
225     else if( coord1 < c2 && c2 < coord2 )
226     {
227       if( c1 < coord1 )
228       {
229         myArray[2*index+1] = coord1;
230       }
231
232       if( index != mySegmentNumber - 1 )
233       {
234         for( int i = index+1; i < mySegmentNumber; i++ )
235         {
236           if( coord2 < myArray[2*i] )
237           {
238             if( index+1 != i )
239             {
240               for( int j = 1; i+j-1 < mySegmentNumber;j++ )
241               {
242                 myArray[2*(index+j)] = myArray[2*(i+j-1)];
243                 myArray[2*(index+j)+1] = myArray[2*(i+j-1)+1];
244               }
245               for( int k = 0; k < mySegmentNumber - i; k++ )
246               {
247                 myArray[2*(mySegmentNumber - 1- k)] = 0.0;
248                 myArray[2*(mySegmentNumber - 1- k)+1] = 0.0;
249               }
250               mySegmentNumber -= i - index -1;
251             }
252             else
253             {
254               if( !(c1 < coord1) )
255               {
256                 for( int j = 0; index + j + 1 < mySegmentNumber;j++ )
257                 {
258                   myArray[2*(index+j)] = myArray[2*(index+j+1)];
259                   myArray[2*(index+j)+1] = myArray[2*(index+j+1)+1];
260                 }
261                   
262                 myArray[2*(mySegmentNumber - 1)] = 0.0;
263                 myArray[2*(mySegmentNumber - 1)+1] = 0.0;
264                 
265                 mySegmentNumber --;
266               }
267
268             }
269
270             return true;
271
272           }
273           else if( coord2 < myArray[2*i+1] )
274           {
275             if( index+1 != i )
276             {
277               if( c1 < coord1 )
278                 index++;
279
280               myArray[2*index] = coord2;
281               myArray[2*index+1] = myArray[2*i+1];
282             
283               for( int j = 1; i+j < mySegmentNumber;j++ )
284               {
285                 myArray[2*(index+j)] = myArray[2*(i+j)];
286                 myArray[2*(index+j)+1] = myArray[2*(i+j)+1];
287               }
288               for( int k = 0; k < mySegmentNumber - i - 1; k++ )
289               {
290                 myArray[2*(mySegmentNumber - 1- k)] = 0.0;
291                 myArray[2*(mySegmentNumber - 1- k)+1] = 0.0;
292               }
293               mySegmentNumber -= i - index;
294             }
295             else
296             {
297               if( c1 < coord1 )
298               {
299                 myArray[2*(index+1)] = coord2;
300                 return true;
301               }
302               else
303               {
304                 myArray[2*(index)] = coord2;
305                 myArray[2*(index)+1] = myArray[2*(index+1)+1];
306                 for( int j = index+1; j < mySegmentNumber-1; j++ )
307                 {
308                   myArray[2*j] = myArray[2*(j+1)];
309                   myArray[2*j+1] = myArray[2*(j+1)+1];
310                 }
311                 mySegmentNumber--;
312                 myArray[2*mySegmentNumber] = 0.0;
313                 myArray[2*mySegmentNumber+1] = 0.0;
314               }
315             }
316             return true;
317           }
318         }
319       }
320       else
321       {
322         if( !(c1 < coord1) )
323         {
324           mySegmentNumber--;
325           myArray[2*index] = 0.0;
326           myArray[2*index+1] = 0.0;
327         }
328       }
329     }    
330     index++;
331   }
332   return true;
333 }
334
335 void GLViewer_LineList::clear()
336 {
337   if( myArray )
338     memset( myArray, 0, myRealSize*sizeof(double) );
339 }
340
341 void GLViewer_LineList::print()
342 {
343   cout << "MainCoord: " << myMainCoord <<" SIZE: " << myRealSize << " ENum: " << mySegmentNumber << " :::";
344   for( int i = 0; i < mySegmentNumber; i++ )
345     cout << "  " << myArray[2*i] << " " << myArray[2*i+1] << " | ";
346
347   cout << endl;
348 }
349
350 void GLViewer_LineList::show( FieldDim theDim )
351 {
352   if( !myArray )
353     return;
354
355   glColor3f( 1.0, 0.0, 1.0 );
356   if( theDim == FD_X )
357   {
358     glBegin( GL_LINES );
359       for( int i = 0; i < mySegmentNumber; i++ )
360       {
361         glVertex2d( myArray[2*i], myMainCoord );
362         glVertex2d( myArray[2*i+1], myMainCoord );
363       }
364     glEnd();
365   }
366   else if( theDim == FD_Y )
367   {
368     glBegin( GL_LINES );
369       for( int i = 0; i < mySegmentNumber; i++ )
370       {
371         glVertex2d( myMainCoord, myArray[2*i]  );
372         glVertex2d( myMainCoord, myArray[2*i+1] );
373       }
374     glEnd();
375   }
376 }
377
378 /****************************************************************************
379 **  Class:   GLViewer_LineField 
380 **  Descr:   Tools for solving 
381 **  Module:  GLViewer
382 **  Created: UI team, 27.10.05
383 *****************************************************************************/
384 GLViewer_LineField::GLViewer_LineField()
385 {
386   myCurArrayIndex = 0;
387   myGraphArray1 = NULL;
388   myGraphArray2 = NULL;
389
390   myCurCount = 0;
391
392   myXSize = 0;    
393   myYSize = 0;
394   myXLineArray = NULL;
395   myYLineArray = NULL;
396 }
397 GLViewer_LineField::GLViewer_LineField( const int theMAXSize, const int theXN, const int theYN )
398 {
399   myCurArrayIndex = 0;
400   myGraphArray1 = NULL;
401   myGraphArray2 = NULL;
402
403   myCurCount = 0;
404
405   if( theXN <= 0 || theYN <= 0 )
406   {
407     myXSize = 0;    
408     myYSize = 0;
409     myXLineArray = NULL;
410     myYLineArray = NULL;
411   }
412   else
413   {
414     myXLineArray = new GLViewer_LineList*[theXN];
415     myYLineArray = new GLViewer_LineList*[theYN];
416
417     for( int i = 0; i < theXN; i++ )
418       myXLineArray[i] = new GLViewer_LineList( theMAXSize );
419
420     for( int j = 0; j < theYN; j++ )
421       myYLineArray[j] = new GLViewer_LineList( theMAXSize );
422
423     myXSize = theXN;    
424     myYSize = theYN;
425   }
426 }
427
428 GLViewer_LineField::~GLViewer_LineField()
429 {
430   if( myXLineArray )
431   {
432     for( int i = 0; i < myXSize; i++ )
433       delete myXLineArray[i];
434
435     delete myXLineArray;
436   }
437
438   if( myYLineArray )
439   {
440     for( int j = 0; j < myYSize; j++ )
441       delete myYLineArray[j];
442
443     delete myYLineArray;
444   }
445
446   if( myGraphArray1 )
447     delete myGraphArray1;
448
449   if( myGraphArray2 )
450     delete myGraphArray2;
451 }
452
453 void GLViewer_LineField::addLine( FieldDim theDim, GLViewer_LineList* )
454 {
455   //not implemented
456 }
457
458 void GLViewer_LineField:: addLine( FieldDim theDim, double theMC, double theBegin, double theEnd )
459 {
460   GLViewer_LineList* aLL = new GLViewer_LineList( 1 );
461   aLL->addSegment( theBegin, theEnd );
462   aLL->setMainCoord( theMC );
463   addLine( theDim, aLL );
464 }
465
466
467 int GLViewer_LineField::insertLine( FieldDim theDim, GLViewer_LineList* theLL, int thePosition )
468 {
469   if( !myXLineArray || !myYLineArray )
470     return -1;
471
472   GLViewer_LineList** anArray = getLLArray( theDim );
473   if( !anArray )
474     return -1;
475
476   int size = getDimSize( theDim ); 
477
478   if( thePosition >= size )
479     return -1;
480   else if( thePosition < 0 )
481   {    
482     if( anArray[size-1]->count() != 0 ) // no more space
483       return -1;
484
485     for( int i = 0; i < size; i++ )
486     {
487       if( anArray[i]->count() == 0 )
488       {
489         delete anArray[i];
490         anArray[i] = theLL;
491         return i;
492       }
493
494       double cur_mc = anArray[i]->mainCoord();
495       if( theLL->mainCoord() < cur_mc )
496       {        
497         for( int j = 0; j+i+1 < size; j++ )
498         {
499           delete anArray[size-j-1];
500           anArray[size-j-1] = anArray[size-j-2];
501         }
502         delete anArray[i];
503         anArray[i] = theLL;
504         return i;
505       }          
506     }
507   }
508   else
509   {
510     delete anArray[thePosition];
511     anArray[thePosition] = theLL;
512     return thePosition;
513   }
514
515   return -1;
516 }
517
518 int GLViewer_LineField::insertLine( FieldDim theDim, double theMainCoord, double theBegin, double theEnd, int thePosition )
519 {
520   GLViewer_LineList* aLL = new GLViewer_LineList( 1 );
521   aLL->addSegment( theBegin, theEnd );
522   aLL->setMainCoord( theMainCoord );
523   return insertLine( theDim, aLL, thePosition );
524 }
525
526
527 FieldDim GLViewer_LineField::invertDim( FieldDim theFD )
528 {
529   if( theFD == FD_X )
530     return FD_Y;
531   else
532     return FD_X;
533 }
534
535 GLViewer_LineList* GLViewer_LineField::getLine( int theIndex, FieldDim theFD )
536 {
537   if( !myXLineArray || !myYLineArray )
538     return NULL;
539
540   if( theFD == FD_X )
541   {
542     if( theIndex > myXSize )
543       return NULL;
544     
545     return myXLineArray[theIndex];
546   }
547   else if( theFD == FD_Y )
548   {
549     if( theIndex > myYSize )
550       return NULL;
551     
552     return myYLineArray[theIndex];
553   }
554
555   return NULL;
556 }
557
558 void GLViewer_LineField::setBorders( double X1, double X2, double Y1, double Y2 )
559 {
560   if( !myXLineArray || !myYLineArray )
561     return;
562     
563   for( int i = 0; i < myXSize; i++ )
564   {
565     myXLineArray[i]->clear();
566     myXLineArray[i]->addSegment( X1, X2 );
567     myXLineArray[i]->setMainCoord( Y1 + (Y2-Y1)*(double(i)/(myXSize-1)) );
568   }
569
570   for( int j = 0; j < myYSize; j++ )
571   {
572     myYLineArray[j]->clear();
573     myYLineArray[j]->addSegment( Y1, Y2 );
574     myYLineArray[j]->setMainCoord( X1 + (X2-X1)*(double(j)/(myYSize-1)) );
575   }
576
577
578 void GLViewer_LineField::addRectangle( double top, double right, double bottom, double left )
579 {
580   if( !myXLineArray || !myYLineArray )
581     return;
582   for( int i = 0; i < myXSize; i++ )
583   {
584     double mainCoord = myXLineArray[i]->mainCoord();
585     if( mainCoord < top && mainCoord > bottom )
586       myXLineArray[i]->removeSegment( left, right );
587   }
588
589   for( int j = 0; j < myYSize; j++ )
590   {
591     double mainCoord = myYLineArray[j]->mainCoord();
592     if( mainCoord < right && mainCoord > left )
593       myYLineArray[j]->removeSegment( bottom, top );
594   }
595 }
596
597 void GLViewer_LineField::print()
598 {
599   cout << "My X matrix Number: " << myXSize << endl;
600   for( int i = 0; i < myXSize; i++ )
601     myXLineArray[i]->print();
602
603   cout << "My Y matrix Number: " << myYSize << endl;
604   for( int j = 0; j < myYSize; j++ )
605     myYLineArray[j]->print();
606 }
607
608 void GLViewer_LineField::show()
609 {
610   for( int i = 0; i < myXSize; i++ )
611     getLine( i, FD_X )->show( FD_X );
612
613   for( int j = 0; j < myYSize; j++ )
614     getLine( j, FD_Y )->show( FD_Y );
615   int count = 0;
616   double* anArray = solution( count );
617   glColor3f( 1.0, 0.0, 0.0 );
618   glBegin( GL_LINES );
619   for( int k = 0; k < count; k++ )
620   {
621      glVertex2d( anArray[4*k], anArray[4*k+1] );
622      glVertex2d( anArray[4*k+2], anArray[4*k+3] );
623   }
624   glEnd();
625   delete[] anArray;
626   cout << "Show function" << endl;
627 }
628
629 int GLViewer_LineField::getDimSize( FieldDim theDim )
630 {
631   if( theDim == FD_X )
632     return myXSize;
633   else if( theDim == FD_Y )
634     return myYSize;
635
636   return -1;
637 }
638
639 int* GLViewer_LineField::intersectIndexes( FieldDim theDim, int theIndex, const GLViewer_LineList* theLL, int& theSize )
640 {
641   theSize = 0;
642   if( !myXLineArray || !myYLineArray )
643     return NULL;
644
645   int aDimSize = getDimSize( theDim );
646   int* anArray = new int[aDimSize*2 ];
647
648   for( int i = 0; i < aDimSize; i++ )
649   {
650     GLViewer_LineList* aLL = getLine( i, theDim );      
651     int index = aLL->contains( theLL->mainCoord() );       
652     if( index != -1 && theLL->contains( aLL->mainCoord() ) == theIndex )
653     {
654       anArray[theSize*2] = i;
655       anArray[theSize*2+1] = index;
656       theSize++;
657     }
658   }
659   
660   return anArray;
661 }
662
663
664 bool GLViewer_LineField::setPoint( FieldPoint thePoint, double theX, double theY )
665 {
666   if( !myXLineArray || !myYLineArray )
667     return false;
668
669   int i = -1, j = -1;
670   int xSeg = -1, ySeg = -1;
671   for( i = 0; i < myXSize; i++ )
672   {
673     GLViewer_LineList* aLL = getLine( i, FD_X );
674     if( aLL->mainCoord() == theY )
675     {
676       xSeg = aLL->contains( theX );
677       break;
678     }
679   }
680
681   for( j = 0; j < myYSize; j++ )
682   {
683     GLViewer_LineList* aLL = getLine( j, FD_Y );
684     if( aLL->mainCoord() == theX )
685     {
686       ySeg = aLL->contains( theY );
687       break;
688     }
689   }
690
691   if( xSeg != -1 && ySeg != -1 )
692   {
693     if( thePoint == FP_Start )
694     {
695       myStartPoint.myXLineIndex = i;
696       myStartPoint.myXSegmentIndex = xSeg;
697       myStartPoint.myYLineIndex = j;
698       myStartPoint.myYSegmentIndex = ySeg;
699       myStartPoint.mySolveIndex = -1;
700     }
701     else
702     {
703       myEndPoint.myXLineIndex = i;
704       myEndPoint.myXSegmentIndex = xSeg;
705       myEndPoint.myYLineIndex = j;
706       myEndPoint.myYSegmentIndex = ySeg;
707       myEndPoint.mySolveIndex = -1;
708     }
709     return true;
710   }
711   else
712     return false;
713 }
714
715 int GLViewer_LineField::segmentNumber()
716 {
717   if( !(myXLineArray || myYLineArray) )
718     return -1;
719
720   int aNumber = 0;
721   for( int aDim = 0; aDim < 2; aDim++ )
722     for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ )
723       aNumber += getLine( i, (FieldDim)aDim  )->count();
724
725   return aNumber;
726 }
727
728 void GLViewer_LineField::optimize()
729 {
730   if( !myXLineArray || !myYLineArray )
731     return;
732
733   for( int aDim = 0; aDim < 2; aDim++ )
734   {
735     for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ )
736     {
737       GLViewer_LineList* aLL = getLine( i, (FieldDim)aDim  );
738       for( int k =0, aSegNum = aLL->count(); k < aSegNum; k++ )
739       {
740         // int index = i; unused
741         double a1, a2;
742         aLL->readSegment( k, a1, a2 );
743         for( int l = i+1, m = getDimSize( (FieldDim)aDim ); l < m; l++ )
744         {
745           int end = -1;
746           GLViewer_LineList* aCurLL = getLine( l, (FieldDim)aDim );
747           for( int j = 0, count = aCurLL->count(); j < count; j++  )
748           {
749             double c1, c2;
750             aCurLL->readSegment( j, c1, c2 );
751             if( a1 == c1 && a2 == c2 )
752             {
753               if( !(aDim == 0 && myStartPoint.myXLineIndex == l && myStartPoint.myXSegmentIndex == j) &&
754                   !(aDim == 0 && myEndPoint.myXLineIndex == l && myEndPoint.myXSegmentIndex == j) &&
755                   !(aDim == 1 && myStartPoint.myYLineIndex == l && myStartPoint.myYSegmentIndex == j) &&
756                   !(aDim == 1 && myEndPoint.myYLineIndex == l && myEndPoint.myYSegmentIndex == j) )
757                 aCurLL->removeSegment( j );
758               end = 0;
759               break;
760             }
761             if( a1 < c1 )
762             {
763               end = 1;
764               break;
765             }            
766           }
767           if( end == -1 || end == 1)
768               break;
769         }
770       }
771     }
772   }
773 }
774
775 void GLViewer_LineField::initialize()
776 {
777   if( !myXLineArray || !myYLineArray )
778     return;
779
780   int size = segmentNumber();
781
782   myCurArrayIndex = 0;
783   myCurCount = 0;
784
785   myGraphArray1 = new GraphNode[size];
786   myGraphArray2 = new GraphNode[size];
787
788   int index = 0;
789   bool isXSet = false,
790        isYSet = false;
791   for( int aDim = 0; aDim < 2; aDim++ )
792   {
793     for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ )
794     {
795       GLViewer_LineList* aLL = getLine( i, (FieldDim)aDim  );
796       for( int k =0, aSegNum = aLL->count(); k < aSegNum; k++ )
797       {
798         myGraphArray1[index].myCount = size;
799         myGraphArray1[index].myDim = (FieldDim)aDim;
800         myGraphArray1[index].myLineIndex = i;
801         myGraphArray1[index].mySegmentindex = k;
802         myGraphArray1[index].prevNodeIndex = -1;
803
804         myGraphArray2[index].myCount = size;
805         myGraphArray2[index].myDim = (FieldDim)aDim;
806         myGraphArray2[index].myLineIndex = i;
807         myGraphArray2[index].mySegmentindex = k;
808         myGraphArray2[index].prevNodeIndex = -1;
809
810         if( !isXSet && aDim == FD_X && myStartPoint.myXLineIndex == i && myStartPoint.myXSegmentIndex == k )
811         {
812           myGraphArray1[index].myCount = 0;
813           isXSet = true;
814         }
815
816         if( aDim == FD_Y && !isYSet && myStartPoint.myYLineIndex == i && myStartPoint.myYSegmentIndex == k )
817         {
818           myGraphArray1[index].myCount = 0;
819           isYSet = true;
820         }
821
822         index++;
823       }
824     }
825   }
826 }
827
828 void GLViewer_LineField::iteration()
829 {
830   int aParam = myCurCount;
831   myCurCount++;
832
833   int* aNodes = findByCount( aParam );
834   GraphNode* aCurArray = getCurArray();
835
836   for( int i = 0; i < aParam; i++ )
837   {
838     GraphNode aCurNode = aCurArray[aNodes[i]];
839     int aSize = 0;
840     int* aInterNodes = intersectIndexes( invertDim( aCurNode.myDim ), aCurNode.mySegmentindex,
841                                          getLine( aCurNode.myLineIndex, aCurNode.myDim ), aSize );
842     for( int j = 0; j < aSize; j++ )
843     {
844       int index = findBySegment( invertDim( aCurNode.myDim ), aInterNodes[2*j], aInterNodes[2*j+1], false );
845       if( index != -1 )
846         if( aCurArray[index].myCount > myCurCount )
847         {
848           aCurArray[index].myCount = myCurCount;
849           aCurArray[index].prevNodeIndex = aNodes[i];
850         }
851     }
852
853     delete[] aInterNodes;
854   }
855
856   delete[] aNodes;
857 }
858
859 GLViewer_LineField::IterationStatus GLViewer_LineField::checkComplete()
860 {
861   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 )
862     return IS_ERROR; 
863    
864   int count = 0;
865   GraphNode* aCurArray = getCurArray(),
866            * aSecArray = getSecArray();
867   
868   for( int i = 0, n = segmentNumber(); i < n; i++ )
869   {
870     if( aCurArray[i].myCount != aSecArray[i].myCount )
871     {
872       if( aCurArray[i].myDim == FD_X && 
873           aCurArray[i].myLineIndex == myEndPoint.myXLineIndex && 
874           aCurArray[i].mySegmentindex == myEndPoint.myXSegmentIndex )
875       {
876         cout << "Algorithm complete X!!!!!!!" << endl;
877         myEndPoint.mySolveIndex = i;
878         return IS_SOLVED;
879       }
880       else if( aCurArray[i].myDim == FD_Y && 
881                aCurArray[i].myLineIndex == myEndPoint.myYLineIndex && 
882                aCurArray[i].mySegmentindex == myEndPoint.myYSegmentIndex )
883       {
884         cout << "Algorithm complete Y!!!!!!!" << endl;
885         myEndPoint.mySolveIndex = i;  
886         return IS_SOLVED;
887       }
888       else
889       {
890         count++;
891         aSecArray[i].myCount = aCurArray[i].myCount;
892         aSecArray[i].prevNodeIndex = aCurArray[i].prevNodeIndex;
893       }
894     }
895   }  
896   
897   if( myCurArrayIndex == 0)
898     myCurArrayIndex = 1;
899   else
900     myCurArrayIndex = 0;
901
902   cout << "Number of ways: " << count << endl;
903   if( count == 0 )
904     return IS_LOOP;
905
906   return IS_NOT_SOLVED;
907 }
908
909 int* GLViewer_LineField::findByCount( int& theParam )
910 {
911   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 )
912     return NULL;
913
914   int count = segmentNumber();
915   int* anArray = new int[count];
916   int aSize = 0;
917
918   GraphNode* aCurArray = getCurArray();  
919   for( int i = 0; i < count; i++ )
920   {
921     GraphNode aCurNode = aCurArray[i];
922     if( aCurNode.myCount == theParam )
923     {
924       anArray[aSize] = i;
925       aSize++;
926     }
927   }
928
929   theParam = aSize;
930   return anArray;
931 }
932
933 int GLViewer_LineField::findBySegment( FieldDim theDim, int theLineIndex, int theSegment, bool inCurArray )
934 {
935   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 || getDimSize( theDim ) <= theLineIndex )
936     return -1;
937
938   GraphNode* aCurArray;
939   if( inCurArray )
940     aCurArray = getCurArray();
941   else
942     aCurArray = getSecArray();
943
944   for( int i = 0, n = segmentNumber(); i < n; i++ )
945   {
946     GraphNode aCurNode = aCurArray[i];
947     if( aCurNode.myDim == theDim && aCurNode.myLineIndex == theLineIndex && aCurNode.mySegmentindex == theSegment )
948       return i;
949   }
950
951   return -1;
952 }
953
954 GLViewer_LineField::EndStatus GLViewer_LineField::startAlgorithm()
955 {
956   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 )
957     return ES_ERROR;
958
959   while( true )
960   {
961     cout << "-----------Iteration #" << myCurCount << "-------------" << endl;
962     iteration();
963
964     IterationStatus is = checkComplete();
965     if( is == IS_ERROR )
966       return ES_ERROR;
967     else if( is == IS_LOOP )
968       return ES_LOOP;
969     else if( is == IS_SOLVED )
970       return ES_SOLVED;
971   }
972   return ES_SOLVED;
973 }
974
975 double* GLViewer_LineField::solution( int& theSize )
976 {
977   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 )
978     return NULL;
979
980   if( myEndPoint.mySolveIndex == -1 )
981     return NULL;
982
983   theSize = myCurCount+1;
984   double* anArray = new double[theSize*4];
985
986   GraphNode* aCurArray = getCurArray();
987   
988   int index = myEndPoint.mySolveIndex;
989   for( int i = 0; i <= myCurCount; i++  )
990   {
991     if( index == -1 )
992       break;
993     double c1, c2;
994     GLViewer_LineList* aLL = getLine( aCurArray[index].myLineIndex, aCurArray[index].myDim );
995     aLL->readSegment( aCurArray[index].mySegmentindex, c1, c2 );
996
997     if( aCurArray[index].myDim == FD_X )
998     {
999       anArray[i*4] = c1;
1000       anArray[i*4+1] = aLL->mainCoord();
1001       anArray[i*4+2] = c2;
1002       anArray[i*4+3] = aLL->mainCoord();
1003     }
1004     else
1005     {
1006       anArray[i*4] = aLL->mainCoord();
1007       anArray[i*4+1] = c1;
1008       anArray[i*4+2] = aLL->mainCoord();
1009       anArray[i*4+3] = c2;
1010     }
1011
1012     index = aCurArray[index].prevNodeIndex;    
1013   }
1014
1015   return anArray;
1016 }
1017
1018 GraphNode* GLViewer_LineField::getCurArray()
1019 {
1020   if( !myGraphArray1 || !myGraphArray2 )
1021     return NULL;
1022
1023   if( myCurArrayIndex == 0)
1024     return myGraphArray1;
1025   else
1026     return myGraphArray2;
1027 }
1028
1029 GraphNode* GLViewer_LineField::getSecArray()
1030 {
1031   if( !myGraphArray1 || !myGraphArray2 )
1032     return NULL;
1033
1034   if( myCurArrayIndex == 0)
1035     return myGraphArray2;
1036   else
1037     return myGraphArray1;
1038 }
1039
1040 int GLViewer_LineField::maxSegmentNum()
1041 {
1042   if( !myXLineArray || !myYLineArray )
1043     return -1;
1044
1045   int max_num = -1;
1046   for( int aDim = 0; aDim < 2; aDim++ )
1047   {
1048     for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ )
1049     {
1050       int count = getLine( i, (FieldDim)aDim  )->count();
1051       if( count > max_num )
1052         max_num = count;
1053     }
1054   }
1055
1056   return max_num;
1057 }
1058
1059 GLViewer_LineList** GLViewer_LineField::getLLArray( FieldDim theDim )
1060 {
1061   if( theDim == FD_X )
1062     return myXLineArray;
1063   else if( theDim == FD_Y )
1064     return myYLineArray;
1065   else
1066     return NULL;
1067 }