Back to index

salome-gui  6.5.0
GLViewer_Tools.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  Author : OPEN CASCADE
00024 // File:      GLViewer_Tools.cxx
00025 // Created:   April, 2005
00026 //
00027 #include "GLViewer_Tools.h"
00028 
00029 #include <GL/gl.h>
00030 
00031 #include <iostream>
00032 #include <string.h>
00033 
00038 GLViewer_LineList::GLViewer_LineList( int size )
00039 {
00040   myRealSize = 2*size;
00041   mySegmentNumber = 0;
00042   myMainCoord = 0.0;
00043 
00044   myArray = new double[myRealSize];
00045 
00046   if( !myArray )
00047   {
00048     std::cout << "Can't allocate memory: " << size << std::endl;
00049     myRealSize = 0;
00050   }
00051   else
00052     memset( myArray, 0, myRealSize*sizeof(double) );
00053 }
00054 
00058 GLViewer_LineList::~GLViewer_LineList()
00059 {
00060   delete myArray;
00061 }
00062 
00067 bool GLViewer_LineList::addSegment( double coord1, double coord2 )
00068 {
00069   if( coord1 > coord2 )
00070   {
00071     double temp = coord1;
00072     coord1 = coord2;
00073     coord2 = temp;
00074   }
00075 
00076   if( 2*mySegmentNumber == myRealSize || !myArray )
00077     return false;
00078 
00079   int index = 0;
00080   double c1, c2;
00081   while( index < mySegmentNumber)
00082   {
00083     readSegment( index, c1, c2 );
00084     if( coord1 < c1 && coord2 < c1 )
00085     {
00086       for( int i = mySegmentNumber; i > index - 1; i--)
00087       {
00088         myArray[2*i] = myArray[2*i-2]; //2*(i-1)
00089         myArray[2*i+1] = myArray[2*i-1];//2*(i-1)+1
00090       }
00091       myArray[0] = coord1;
00092       myArray[1] = coord2;
00093       // mySegmentNumber; what is means ?
00094       return true;
00095     }
00096     else if( coord1 < c1 && coord2 < c2 )
00097     {
00098       myArray[index*2] = coord1;
00099       return true;
00100     }
00101     else if( c1 < coord1 && coord2 < c2 )
00102     {
00103       return true;
00104     }
00105     else if( coord1 < c2 && c2 < coord2 )
00106     {
00107       if( c1 > coord1 )
00108         myArray[2*index] = coord1;
00109 
00110       if( index != mySegmentNumber - 1 )
00111       {
00112         for( int i = index+1; i < mySegmentNumber; i++ )
00113         {
00114           if( coord2 < myArray[2*i] )
00115           {
00116             myArray[2*index+1] = coord2;
00117             if( index+1 != i )
00118             {
00119               for( int j = 0; i+j < mySegmentNumber;j++ )
00120               {
00121                 myArray[2*(index+1+j)] = myArray[2*(i+j)];
00122                 myArray[2*(index+1+j)+1] = myArray[2*(i+j)+1];
00123               }
00124               for( int k = 0; k < mySegmentNumber - i; k++ )
00125               {
00126                 myArray[2*(mySegmentNumber - 1- k)] = 0.0;
00127                 myArray[2*(mySegmentNumber - 1- k)+1] = 0.0;
00128               }
00129               mySegmentNumber -= i - index-1;
00130             }            
00131             return true;
00132           }
00133           else if( coord2 < myArray[2*i+1] )
00134           {
00135             myArray[2*index+1] = myArray[2*i+1];
00136             
00137             for( int j = index+1; j < mySegmentNumber-1;j++ )
00138             {
00139               myArray[2*j] = myArray[2*(i+j-index)];
00140               myArray[2*j+1] = myArray[2*(i+j-index)+1];
00141             }
00142             for( int k = 0; k < mySegmentNumber - i-1; k++ )
00143             {
00144               myArray[2*(mySegmentNumber - 1- k)] = 0.0;
00145               myArray[2*(mySegmentNumber - 1- k)+1] = 0.0;
00146             }
00147             mySegmentNumber -= i - index;
00148             return true;
00149           }
00150         }
00151       }
00152       else
00153       {
00154         myArray[2*index+1] = coord2;
00155         return true;
00156       }
00157     }    
00158     index++;
00159   }
00160 
00161   myArray[mySegmentNumber*2] = coord1;
00162   myArray[mySegmentNumber*2+1] = coord2;
00163   mySegmentNumber++;
00164 
00165   return true;
00166 }
00167 
00173 bool GLViewer_LineList::readSegment( int theIndex, double& coord1, double& coord2 )
00174 {
00175   if( theIndex > mySegmentNumber || !myArray)
00176     return false;
00177 
00178   coord1 = myArray[theIndex*2];
00179   coord2 = myArray[theIndex*2+1];
00180 
00181   return true;
00182 }
00183 
00188 int GLViewer_LineList::contains( double thePoint ) const
00189 {
00190   if( !myArray || mySegmentNumber == 0 )
00191     return -1;
00192 
00193   for( int i = 0; i < mySegmentNumber; i++ )
00194     if( myArray[2*i] <= thePoint && thePoint <= myArray[2*i+1] )
00195       return i;
00196 
00197   return -1;
00198 
00199 }
00200 
00205 bool GLViewer_LineList::removeSegment( int theIndex )
00206 {
00207   if( theIndex > mySegmentNumber || !myArray)
00208     return false;
00209 
00210   for( int i = theIndex; i < mySegmentNumber; i++ )
00211   {
00212     myArray[i*2] = myArray[(i+1)*2];
00213     myArray[i*2+1] = myArray[(i+1)*2+1];
00214   }
00215   mySegmentNumber--;
00216   myArray[mySegmentNumber*2] = 0.0;
00217   myArray[mySegmentNumber*2+1] = 0.0;
00218   return true;
00219 }
00220 
00225 bool GLViewer_LineList::removeSegment( double coord1, double coord2 )
00226 {
00227   if( coord1 > coord2 )
00228   {
00229     double temp = coord1;
00230     coord1 = coord2;
00231     coord2 = temp;
00232   }
00233 
00234   if( 2*mySegmentNumber == myRealSize || !myArray )
00235     return false;
00236 
00237   int index = 0;
00238   double c1, c2;
00239   while( index < mySegmentNumber)
00240   {
00241     readSegment( index, c1, c2 );
00242     if( coord1 < c1 && coord2 < c1 )
00243     {
00244       //nothing
00245       return true;
00246     }
00247     else if( coord1 < c1 && coord2 < c2 )
00248     {
00249       myArray[index*2] = coord2;
00250       return true;
00251     }
00252     else if( c1 < coord1 && coord2 < c2 )
00253     {
00254       if( 2*mySegmentNumber == myRealSize )
00255         return false;
00256       for( int i = mySegmentNumber; i > index + 1; i-- )
00257       {
00258         myArray[2*i] = myArray[2*(i-1)];
00259         myArray[2*i+1] = myArray[2*(i-1)+1];
00260       }
00261       myArray[2*(index+1)+1] = myArray[2*index+1];
00262       myArray[2*(index+1)] = coord2;
00263       myArray[2*index+1] = coord1;
00264       mySegmentNumber++;
00265       return true;
00266     }
00267     else if( coord1 < c2 && c2 < coord2 )
00268     {
00269       if( c1 < coord1 )
00270       {
00271         myArray[2*index+1] = coord1;
00272       }
00273 
00274       if( index != mySegmentNumber - 1 )
00275       {
00276         for( int i = index+1; i < mySegmentNumber; i++ )
00277         {
00278           if( coord2 < myArray[2*i] )
00279           {
00280             if( index+1 != i )
00281             {
00282               for( int j = 1; i+j-1 < mySegmentNumber;j++ )
00283               {
00284                 myArray[2*(index+j)] = myArray[2*(i+j-1)];
00285                 myArray[2*(index+j)+1] = myArray[2*(i+j-1)+1];
00286               }
00287               for( int k = 0; k < mySegmentNumber - i; k++ )
00288               {
00289                 myArray[2*(mySegmentNumber - 1- k)] = 0.0;
00290                 myArray[2*(mySegmentNumber - 1- k)+1] = 0.0;
00291               }
00292               mySegmentNumber -= i - index -1;
00293             }
00294             else
00295             {
00296               if( !(c1 < coord1) )
00297               {
00298                 for( int j = 0; index + j + 1 < mySegmentNumber;j++ )
00299                 {
00300                   myArray[2*(index+j)] = myArray[2*(index+j+1)];
00301                   myArray[2*(index+j)+1] = myArray[2*(index+j+1)+1];
00302                 }
00303                   
00304                 myArray[2*(mySegmentNumber - 1)] = 0.0;
00305                 myArray[2*(mySegmentNumber - 1)+1] = 0.0;
00306                 
00307                 mySegmentNumber --;
00308               }
00309 
00310             }
00311 
00312             return true;
00313 
00314           }
00315           else if( coord2 < myArray[2*i+1] )
00316           {
00317             if( index+1 != i )
00318             {
00319               if( c1 < coord1 )
00320                 index++;
00321 
00322               myArray[2*index] = coord2;
00323               myArray[2*index+1] = myArray[2*i+1];
00324             
00325               for( int j = 1; i+j < mySegmentNumber;j++ )
00326               {
00327                 myArray[2*(index+j)] = myArray[2*(i+j)];
00328                 myArray[2*(index+j)+1] = myArray[2*(i+j)+1];
00329               }
00330               for( int k = 0; k < mySegmentNumber - i - 1; k++ )
00331               {
00332                 myArray[2*(mySegmentNumber - 1- k)] = 0.0;
00333                 myArray[2*(mySegmentNumber - 1- k)+1] = 0.0;
00334               }
00335               mySegmentNumber -= i - index;
00336             }
00337             else
00338             {
00339               if( c1 < coord1 )
00340               {
00341                 myArray[2*(index+1)] = coord2;
00342                 return true;
00343               }
00344               else
00345               {
00346                 myArray[2*(index)] = coord2;
00347                 myArray[2*(index)+1] = myArray[2*(index+1)+1];
00348                 for( int j = index+1; j < mySegmentNumber-1; j++ )
00349                 {
00350                   myArray[2*j] = myArray[2*(j+1)];
00351                   myArray[2*j+1] = myArray[2*(j+1)+1];
00352                 }
00353                 mySegmentNumber--;
00354                 myArray[2*mySegmentNumber] = 0.0;
00355                 myArray[2*mySegmentNumber+1] = 0.0;
00356               }
00357             }
00358             return true;
00359           }
00360         }
00361       }
00362       else
00363       {
00364         if( !(c1 < coord1) )
00365         {
00366           mySegmentNumber--;
00367           myArray[2*index] = 0.0;
00368           myArray[2*index+1] = 0.0;
00369         }
00370       }
00371     }    
00372     index++;
00373   }
00374   return true;
00375 }
00376 
00380 void GLViewer_LineList::clear()
00381 {
00382   if( myArray )
00383     memset( myArray, 0, myRealSize*sizeof(double) );
00384 }
00385 
00389 void GLViewer_LineList::print()
00390 {
00391   std::cout << "MainCoord: " << myMainCoord <<" SIZE: " << myRealSize << " ENum: " << mySegmentNumber << " :::";
00392   for( int i = 0; i < mySegmentNumber; i++ )
00393     std::cout << "  " << myArray[2*i] << " " << myArray[2*i+1] << " | ";
00394 
00395   std::cout << std::endl;
00396 }
00397 
00402 void GLViewer_LineList::show( FieldDim theDim )
00403 {
00404   if( !myArray )
00405     return;
00406 
00407   glColor3f( 1.0, 0.0, 1.0 );
00408   if( theDim == FD_X )
00409   {
00410     glBegin( GL_LINES );
00411       for( int i = 0; i < mySegmentNumber; i++ )
00412       {
00413         glVertex2d( myArray[2*i], myMainCoord );
00414         glVertex2d( myArray[2*i+1], myMainCoord );
00415       }
00416     glEnd();
00417   }
00418   else if( theDim == FD_Y )
00419   {
00420     glBegin( GL_LINES );
00421       for( int i = 0; i < mySegmentNumber; i++ )
00422       {
00423         glVertex2d( myMainCoord, myArray[2*i]  );
00424         glVertex2d( myMainCoord, myArray[2*i+1] );
00425       }
00426     glEnd();
00427   }
00428 }
00429 
00430 
00434 GLViewer_LineField::GLViewer_LineField()
00435 {
00436   myCurArrayIndex = 0;
00437   myGraphArray1 = NULL;
00438   myGraphArray2 = NULL;
00439 
00440   myCurCount = 0;
00441 
00442   myXSize = 0;    
00443   myYSize = 0;
00444   myXLineArray = NULL;
00445   myYLineArray = NULL;
00446 }
00447 
00451 GLViewer_LineField::GLViewer_LineField( const int theMAXSize, const int theXN, const int theYN )
00452 {
00453   myCurArrayIndex = 0;
00454   myGraphArray1 = NULL;
00455   myGraphArray2 = NULL;
00456 
00457   myCurCount = 0;
00458 
00459   if( theXN <= 0 || theYN <= 0 )
00460   {
00461     myXSize = 0;    
00462     myYSize = 0;
00463     myXLineArray = NULL;
00464     myYLineArray = NULL;
00465   }
00466   else
00467   {
00468     myXLineArray = new GLViewer_LineList*[theXN];
00469     myYLineArray = new GLViewer_LineList*[theYN];
00470 
00471     for( int i = 0; i < theXN; i++ )
00472       myXLineArray[i] = new GLViewer_LineList( theMAXSize );
00473 
00474     for( int j = 0; j < theYN; j++ )
00475       myYLineArray[j] = new GLViewer_LineList( theMAXSize );
00476 
00477     myXSize = theXN;    
00478     myYSize = theYN;
00479   }
00480 }
00481 
00485 GLViewer_LineField::~GLViewer_LineField()
00486 {
00487   if( myXLineArray )
00488   {
00489     for( int i = 0; i < myXSize; i++ )
00490       delete myXLineArray[i];
00491 
00492     delete myXLineArray;
00493   }
00494 
00495   if( myYLineArray )
00496   {
00497     for( int j = 0; j < myYSize; j++ )
00498       delete myYLineArray[j];
00499 
00500     delete myYLineArray;
00501   }
00502 
00503   if( myGraphArray1 )
00504     delete myGraphArray1;
00505 
00506   if( myGraphArray2 )
00507     delete myGraphArray2;
00508 }
00509 
00513 void GLViewer_LineField::addLine( FieldDim theDim, GLViewer_LineList* )
00514 {
00515   //not implemented
00516 }
00517 
00525 void GLViewer_LineField:: addLine( FieldDim theDim, double theMC, double theBegin, double theEnd )
00526 {
00527   GLViewer_LineList* aLL = new GLViewer_LineList( 1 );
00528   aLL->addSegment( theBegin, theEnd );
00529   aLL->setMainCoord( theMC );
00530   addLine( theDim, aLL );
00531 }
00532 
00539 int GLViewer_LineField::insertLine( FieldDim theDim, GLViewer_LineList* theLL, int thePosition )
00540 {
00541   if( !myXLineArray || !myYLineArray )
00542     return -1;
00543 
00544   GLViewer_LineList** anArray = getLLArray( theDim );
00545   if( !anArray )
00546     return -1;
00547 
00548   int size = getDimSize( theDim ); 
00549 
00550   if( thePosition >= size )
00551     return -1;
00552   else if( thePosition < 0 )
00553   {    
00554     if( anArray[size-1]->count() != 0 ) // no more space
00555       return -1;
00556 
00557     for( int i = 0; i < size; i++ )
00558     {
00559       if( anArray[i]->count() == 0 )
00560       {
00561         delete anArray[i];
00562         anArray[i] = theLL;
00563         return i;
00564       }
00565 
00566       double cur_mc = anArray[i]->mainCoord();
00567       if( theLL->mainCoord() < cur_mc )
00568       {        
00569         for( int j = 0; j+i+1 < size; j++ )
00570         {
00571           delete anArray[size-j-1];
00572           anArray[size-j-1] = anArray[size-j-2];
00573         }
00574         delete anArray[i];
00575         anArray[i] = theLL;
00576         return i;
00577       }          
00578     }
00579   }
00580   else
00581   {
00582     delete anArray[thePosition];
00583     anArray[thePosition] = theLL;
00584     return thePosition;
00585   }
00586 
00587   return -1;
00588 }
00589 
00598 int GLViewer_LineField::insertLine( FieldDim theDim, double theMainCoord, double theBegin, double theEnd, int thePosition )
00599 {
00600   GLViewer_LineList* aLL = new GLViewer_LineList( 1 );
00601   aLL->addSegment( theBegin, theEnd );
00602   aLL->setMainCoord( theMainCoord );
00603   return insertLine( theDim, aLL, thePosition );
00604 }
00605 
00609 FieldDim GLViewer_LineField::invertDim( FieldDim theFD )
00610 {
00611   if( theFD == FD_X )
00612     return FD_Y;
00613   else
00614     return FD_X;
00615 }
00616 
00622 GLViewer_LineList* GLViewer_LineField::getLine( int theIndex, FieldDim theFD )
00623 {
00624   if( !myXLineArray || !myYLineArray )
00625     return NULL;
00626 
00627   if( theFD == FD_X )
00628   {
00629     if( theIndex > myXSize )
00630       return NULL;
00631     
00632     return myXLineArray[theIndex];
00633   }
00634   else if( theFD == FD_Y )
00635   {
00636     if( theIndex > myYSize )
00637       return NULL;
00638     
00639     return myYLineArray[theIndex];
00640   }
00641 
00642   return NULL;
00643 }
00644 
00650 void GLViewer_LineField::setBorders( double X1, double X2, double Y1, double Y2 )
00651 {
00652   if( !myXLineArray || !myYLineArray )
00653     return;
00654     
00655   for( int i = 0; i < myXSize; i++ )
00656   {
00657     myXLineArray[i]->clear();
00658     myXLineArray[i]->addSegment( X1, X2 );
00659     myXLineArray[i]->setMainCoord( Y1 + (Y2-Y1)*(double(i)/(myXSize-1)) );
00660   }
00661 
00662   for( int j = 0; j < myYSize; j++ )
00663   {
00664     myYLineArray[j]->clear();
00665     myYLineArray[j]->addSegment( Y1, Y2 );
00666     myYLineArray[j]->setMainCoord( X1 + (X2-X1)*(double(j)/(myYSize-1)) );
00667   }
00668 } 
00669 
00675 void GLViewer_LineField::addRectangle( double top, double right, double bottom, double left )
00676 {
00677   if( !myXLineArray || !myYLineArray )
00678     return;
00679   for( int i = 0; i < myXSize; i++ )
00680   {
00681     double mainCoord = myXLineArray[i]->mainCoord();
00682     if( mainCoord < top && mainCoord > bottom )
00683       myXLineArray[i]->removeSegment( left, right );
00684   }
00685 
00686   for( int j = 0; j < myYSize; j++ )
00687   {
00688     double mainCoord = myYLineArray[j]->mainCoord();
00689     if( mainCoord < right && mainCoord > left )
00690       myYLineArray[j]->removeSegment( bottom, top );
00691   }
00692 }
00693 
00697 void GLViewer_LineField::print()
00698 {
00699   std::cout << "My X matrix Number: " << myXSize << std::endl;
00700   for( int i = 0; i < myXSize; i++ )
00701     myXLineArray[i]->print();
00702 
00703   std::cout << "My Y matrix Number: " << myYSize << std::endl;
00704   for( int j = 0; j < myYSize; j++ )
00705     myYLineArray[j]->print();
00706 }
00707 
00711 void GLViewer_LineField::show()
00712 {
00713   for( int i = 0; i < myXSize; i++ )
00714     getLine( i, FD_X )->show( FD_X );
00715 
00716   for( int j = 0; j < myYSize; j++ )
00717     getLine( j, FD_Y )->show( FD_Y );
00718   int count = 0;
00719   double* anArray = solution( count );
00720   glColor3f( 1.0, 0.0, 0.0 );
00721   glBegin( GL_LINES );
00722   for( int k = 0; k < count; k++ )
00723   {
00724      glVertex2d( anArray[4*k], anArray[4*k+1] );
00725      glVertex2d( anArray[4*k+2], anArray[4*k+3] );
00726   }
00727   glEnd();
00728   delete[] anArray;
00729   std::cout << "Show function" << std::endl;
00730 }
00731 
00736 int GLViewer_LineField::getDimSize( FieldDim theDim )
00737 {
00738   if( theDim == FD_X )
00739     return myXSize;
00740   else if( theDim == FD_Y )
00741     return myYSize;
00742 
00743   return -1;
00744 }
00745 
00753 int* GLViewer_LineField::intersectIndexes( FieldDim theDim, int theIndex, const GLViewer_LineList* theLL, int& theSize )
00754 {
00755   theSize = 0;
00756   if( !myXLineArray || !myYLineArray )
00757     return NULL;
00758 
00759   int aDimSize = getDimSize( theDim );
00760   int* anArray = new int[aDimSize*2 ];
00761 
00762   for( int i = 0; i < aDimSize; i++ )
00763   {
00764     GLViewer_LineList* aLL = getLine( i, theDim );      
00765     int index = aLL->contains( theLL->mainCoord() );       
00766     if( index != -1 && theLL->contains( aLL->mainCoord() ) == theIndex )
00767     {
00768       anArray[theSize*2] = i;
00769       anArray[theSize*2+1] = index;
00770       theSize++;
00771     }
00772   }
00773   
00774   return anArray;
00775 }
00776 
00782 bool GLViewer_LineField::setPoint( FieldPoint thePoint, double theX, double theY )
00783 {
00784   if( !myXLineArray || !myYLineArray )
00785     return false;
00786 
00787   int i = -1, j = -1;
00788   int xSeg = -1, ySeg = -1;
00789   for( i = 0; i < myXSize; i++ )
00790   {
00791     GLViewer_LineList* aLL = getLine( i, FD_X );
00792     if( aLL->mainCoord() == theY )
00793     {
00794       xSeg = aLL->contains( theX );
00795       break;
00796     }
00797   }
00798 
00799   for( j = 0; j < myYSize; j++ )
00800   {
00801     GLViewer_LineList* aLL = getLine( j, FD_Y );
00802     if( aLL->mainCoord() == theX )
00803     {
00804       ySeg = aLL->contains( theY );
00805       break;
00806     }
00807   }
00808 
00809   if( xSeg != -1 && ySeg != -1 )
00810   {
00811     if( thePoint == FP_Start )
00812     {
00813       myStartPoint.myXLineIndex = i;
00814       myStartPoint.myXSegmentIndex = xSeg;
00815       myStartPoint.myYLineIndex = j;
00816       myStartPoint.myYSegmentIndex = ySeg;
00817       myStartPoint.mySolveIndex = -1;
00818     }
00819     else
00820     {
00821       myEndPoint.myXLineIndex = i;
00822       myEndPoint.myXSegmentIndex = xSeg;
00823       myEndPoint.myYLineIndex = j;
00824       myEndPoint.myYSegmentIndex = ySeg;
00825       myEndPoint.mySolveIndex = -1;
00826     }
00827     return true;
00828   }
00829   else
00830     return false;
00831 }
00832 
00836 int GLViewer_LineField::segmentNumber()
00837 {
00838   if( !(myXLineArray || myYLineArray) )
00839     return -1;
00840 
00841   int aNumber = 0;
00842   for( int aDim = 0; aDim < 2; aDim++ )
00843     for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ )
00844       aNumber += getLine( i, (FieldDim)aDim  )->count();
00845 
00846   return aNumber;
00847 }
00848 
00852 void GLViewer_LineField::optimize()
00853 {
00854   if( !myXLineArray || !myYLineArray )
00855     return;
00856 
00857   for( int aDim = 0; aDim < 2; aDim++ )
00858   {
00859     for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ )
00860     {
00861       GLViewer_LineList* aLL = getLine( i, (FieldDim)aDim  );
00862       for( int k =0, aSegNum = aLL->count(); k < aSegNum; k++ )
00863       {
00864         // int index = i; unused
00865         double a1, a2;
00866         aLL->readSegment( k, a1, a2 );
00867         for( int l = i+1, m = getDimSize( (FieldDim)aDim ); l < m; l++ )
00868         {
00869           int end = -1;
00870           GLViewer_LineList* aCurLL = getLine( l, (FieldDim)aDim );
00871           for( int j = 0, count = aCurLL->count(); j < count; j++  )
00872           {
00873             double c1, c2;
00874             aCurLL->readSegment( j, c1, c2 );
00875             if( a1 == c1 && a2 == c2 )
00876             {
00877               if( !(aDim == 0 && myStartPoint.myXLineIndex == l && myStartPoint.myXSegmentIndex == j) &&
00878                   !(aDim == 0 && myEndPoint.myXLineIndex == l && myEndPoint.myXSegmentIndex == j) &&
00879                   !(aDim == 1 && myStartPoint.myYLineIndex == l && myStartPoint.myYSegmentIndex == j) &&
00880                   !(aDim == 1 && myEndPoint.myYLineIndex == l && myEndPoint.myYSegmentIndex == j) )
00881                 aCurLL->removeSegment( j );
00882               end = 0;
00883               break;
00884             }
00885             if( a1 < c1 )
00886             {
00887               end = 1;
00888               break;
00889             }            
00890           }
00891           if( end == -1 || end == 1)
00892               break;
00893         }
00894       }
00895     }
00896   }
00897 }
00898 
00903 void GLViewer_LineField::initialize()
00904 {
00905   if( !myXLineArray || !myYLineArray )
00906     return;
00907 
00908   int size = segmentNumber();
00909 
00910   myCurArrayIndex = 0;
00911   myCurCount = 0;
00912 
00913   myGraphArray1 = new GraphNode[size];
00914   myGraphArray2 = new GraphNode[size];
00915 
00916   int index = 0;
00917   bool isXSet = false,
00918        isYSet = false;
00919   for( int aDim = 0; aDim < 2; aDim++ )
00920   {
00921     for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ )
00922     {
00923       GLViewer_LineList* aLL = getLine( i, (FieldDim)aDim  );
00924       for( int k =0, aSegNum = aLL->count(); k < aSegNum; k++ )
00925       {
00926         myGraphArray1[index].myCount = size;
00927         myGraphArray1[index].myDim = (FieldDim)aDim;
00928         myGraphArray1[index].myLineIndex = i;
00929         myGraphArray1[index].mySegmentindex = k;
00930         myGraphArray1[index].prevNodeIndex = -1;
00931 
00932         myGraphArray2[index].myCount = size;
00933         myGraphArray2[index].myDim = (FieldDim)aDim;
00934         myGraphArray2[index].myLineIndex = i;
00935         myGraphArray2[index].mySegmentindex = k;
00936         myGraphArray2[index].prevNodeIndex = -1;
00937 
00938         if( !isXSet && aDim == FD_X && myStartPoint.myXLineIndex == i && myStartPoint.myXSegmentIndex == k )
00939         {
00940           myGraphArray1[index].myCount = 0;
00941           isXSet = true;
00942         }
00943 
00944         if( aDim == FD_Y && !isYSet && myStartPoint.myYLineIndex == i && myStartPoint.myYSegmentIndex == k )
00945         {
00946           myGraphArray1[index].myCount = 0;
00947           isYSet = true;
00948         }
00949 
00950         index++;
00951       }
00952     }
00953   }
00954 }
00955 
00959 void GLViewer_LineField::iteration()
00960 {
00961   int aParam = myCurCount;
00962   myCurCount++;
00963 
00964   int* aNodes = findByCount( aParam );
00965   GraphNode* aCurArray = getCurArray();
00966 
00967   for( int i = 0; i < aParam; i++ )
00968   {
00969     GraphNode aCurNode = aCurArray[aNodes[i]];
00970     int aSize = 0;
00971     int* aInterNodes = intersectIndexes( invertDim( aCurNode.myDim ), aCurNode.mySegmentindex,
00972                                          getLine( aCurNode.myLineIndex, aCurNode.myDim ), aSize );
00973     for( int j = 0; j < aSize; j++ )
00974     {
00975       int index = findBySegment( invertDim( aCurNode.myDim ), aInterNodes[2*j], aInterNodes[2*j+1], false );
00976       if( index != -1 )
00977         if( aCurArray[index].myCount > myCurCount )
00978         {
00979           aCurArray[index].myCount = myCurCount;
00980           aCurArray[index].prevNodeIndex = aNodes[i];
00981         }
00982     }
00983 
00984     delete[] aInterNodes;
00985   }
00986 
00987   delete[] aNodes;
00988 }
00989 
00993 GLViewer_LineField::IterationStatus GLViewer_LineField::checkComplete()
00994 {
00995   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 )
00996     return IS_ERROR; 
00997    
00998   int count = 0;
00999   GraphNode* aCurArray = getCurArray(),
01000            * aSecArray = getSecArray();
01001   
01002   for( int i = 0, n = segmentNumber(); i < n; i++ )
01003   {
01004     if( aCurArray[i].myCount != aSecArray[i].myCount )
01005     {
01006       if( aCurArray[i].myDim == FD_X && 
01007           aCurArray[i].myLineIndex == myEndPoint.myXLineIndex && 
01008           aCurArray[i].mySegmentindex == myEndPoint.myXSegmentIndex )
01009       {
01010         std::cout << "Algorithm complete X!!!!!!!" << std::endl;
01011         myEndPoint.mySolveIndex = i;
01012         return IS_SOLVED;
01013       }
01014       else if( aCurArray[i].myDim == FD_Y && 
01015                aCurArray[i].myLineIndex == myEndPoint.myYLineIndex && 
01016                aCurArray[i].mySegmentindex == myEndPoint.myYSegmentIndex )
01017       {
01018         std::cout << "Algorithm complete Y!!!!!!!" << std::endl;
01019         myEndPoint.mySolveIndex = i;  
01020         return IS_SOLVED;
01021       }
01022       else
01023       {
01024         count++;
01025         aSecArray[i].myCount = aCurArray[i].myCount;
01026         aSecArray[i].prevNodeIndex = aCurArray[i].prevNodeIndex;
01027       }
01028     }
01029   }  
01030   
01031   if( myCurArrayIndex == 0)
01032     myCurArrayIndex = 1;
01033   else
01034     myCurArrayIndex = 0;
01035 
01036   std::cout << "Number of ways: " << count << std::endl;
01037   if( count == 0 )
01038     return IS_LOOP;
01039 
01040   return IS_NOT_SOLVED;
01041 }
01042 
01046 int* GLViewer_LineField::findByCount( int& theParam )
01047 {
01048   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 )
01049     return NULL;
01050 
01051   int count = segmentNumber();
01052   int* anArray = new int[count];
01053   int aSize = 0;
01054 
01055   GraphNode* aCurArray = getCurArray();  
01056   for( int i = 0; i < count; i++ )
01057   {
01058     GraphNode aCurNode = aCurArray[i];
01059     if( aCurNode.myCount == theParam )
01060     {
01061       anArray[aSize] = i;
01062       aSize++;
01063     }
01064   }
01065 
01066   theParam = aSize;
01067   return anArray;
01068 }
01069 
01073 int GLViewer_LineField::findBySegment( FieldDim theDim, int theLineIndex, int theSegment, bool inCurArray )
01074 {
01075   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 || getDimSize( theDim ) <= theLineIndex )
01076     return -1;
01077 
01078   GraphNode* aCurArray;
01079   if( inCurArray )
01080     aCurArray = getCurArray();
01081   else
01082     aCurArray = getSecArray();
01083 
01084   for( int i = 0, n = segmentNumber(); i < n; i++ )
01085   {
01086     GraphNode aCurNode = aCurArray[i];
01087     if( aCurNode.myDim == theDim && aCurNode.myLineIndex == theLineIndex && aCurNode.mySegmentindex == theSegment )
01088       return i;
01089   }
01090 
01091   return -1;
01092 }
01093 
01097 GLViewer_LineField::EndStatus GLViewer_LineField::startAlgorithm()
01098 {
01099   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 )
01100     return ES_ERROR;
01101 
01102   while( true )
01103   {
01104     std::cout << "-----------Iteration #" << myCurCount << "-------------" << std::endl;
01105     iteration();
01106 
01107     IterationStatus is = checkComplete();
01108     if( is == IS_ERROR )
01109       return ES_ERROR;
01110     else if( is == IS_LOOP )
01111       return ES_LOOP;
01112     else if( is == IS_SOLVED )
01113       return ES_SOLVED;
01114   }
01115   return ES_SOLVED;
01116 }
01117 
01121 double* GLViewer_LineField::solution( int& theSize )
01122 {
01123   if( !myXLineArray || !myYLineArray || !myGraphArray1 || !myGraphArray2 )
01124     return NULL;
01125 
01126   if( myEndPoint.mySolveIndex == -1 )
01127     return NULL;
01128 
01129   theSize = myCurCount+1;
01130   double* anArray = new double[theSize*4];
01131 
01132   GraphNode* aCurArray = getCurArray();
01133   
01134   int index = myEndPoint.mySolveIndex;
01135   for( int i = 0; i <= myCurCount; i++  )
01136   {
01137     if( index == -1 )
01138       break;
01139     double c1, c2;
01140     GLViewer_LineList* aLL = getLine( aCurArray[index].myLineIndex, aCurArray[index].myDim );
01141     aLL->readSegment( aCurArray[index].mySegmentindex, c1, c2 );
01142 
01143     if( aCurArray[index].myDim == FD_X )
01144     {
01145       anArray[i*4] = c1;
01146       anArray[i*4+1] = aLL->mainCoord();
01147       anArray[i*4+2] = c2;
01148       anArray[i*4+3] = aLL->mainCoord();
01149     }
01150     else
01151     {
01152       anArray[i*4] = aLL->mainCoord();
01153       anArray[i*4+1] = c1;
01154       anArray[i*4+2] = aLL->mainCoord();
01155       anArray[i*4+3] = c2;
01156     }
01157 
01158     index = aCurArray[index].prevNodeIndex;    
01159   }
01160 
01161   return anArray;
01162 }
01163 
01167 GraphNode* GLViewer_LineField::getCurArray()
01168 {
01169   if( !myGraphArray1 || !myGraphArray2 )
01170     return NULL;
01171 
01172   if( myCurArrayIndex == 0)
01173     return myGraphArray1;
01174   else
01175     return myGraphArray2;
01176 }
01177 
01181 GraphNode* GLViewer_LineField::getSecArray()
01182 {
01183   if( !myGraphArray1 || !myGraphArray2 )
01184     return NULL;
01185 
01186   if( myCurArrayIndex == 0)
01187     return myGraphArray2;
01188   else
01189     return myGraphArray1;
01190 }
01191 
01195 int GLViewer_LineField::maxSegmentNum()
01196 {
01197   if( !myXLineArray || !myYLineArray )
01198     return -1;
01199 
01200   int max_num = -1;
01201   for( int aDim = 0; aDim < 2; aDim++ )
01202   {
01203     for( int i = 0, n = getDimSize( (FieldDim)aDim ); i < n; i++ )
01204     {
01205       int count = getLine( i, (FieldDim)aDim  )->count();
01206       if( count > max_num )
01207         max_num = count;
01208     }
01209   }
01210 
01211   return max_num;
01212 }
01213 
01218 GLViewer_LineList** GLViewer_LineField::getLLArray( FieldDim theDim )
01219 {
01220   if( theDim == FD_X )
01221     return myXLineArray;
01222   else if( theDim == FD_Y )
01223     return myYLineArray;
01224   else
01225     return NULL;
01226 }