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