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