ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sampleMonoPoly.cc
Go to the documentation of this file.
00001 /*
00002 ** License Applicability. Except to the extent portions of this file are
00003 ** made subject to an alternative license as permitted in the SGI Free
00004 ** Software License B, Version 1.1 (the "License"), the contents of this
00005 ** file are subject only to the provisions of the License. You may not use
00006 ** this file except in compliance with the License. You may obtain a copy
00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
00009 ** 
00010 ** http://oss.sgi.com/projects/FreeB
00011 ** 
00012 ** Note that, as provided in the License, the Software is distributed on an
00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00017 ** 
00018 ** Original Code. The Original Code is: OpenGL Sample Implementation,
00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
00021 ** Copyright in any portions created by third parties is as indicated
00022 ** elsewhere herein. All Rights Reserved.
00023 ** 
00024 ** Additional Notice Provisions: The application programming interfaces
00025 ** established by SGI in conjunction with the Original Code are The
00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software
00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
00031 ** published by SGI, but has not been independently verified as being
00032 ** compliant with the OpenGL(R) version 1.2.1 Specification.
00033 **
00034 ** $Date: 2006-03-12 00:07:02 +0000 (Sun, 12 Mar 2006) $ $Revision: 1.1 $
00035 */
00036 /*
00037 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/nurbtess/sampleMonoPoly.cc,v 1.1 2004/02/02 16:39:15 navaraf Exp $
00038 */
00039 
00040 #include "gluos.h"
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <math.h>
00044 
00045 #ifndef max
00046 #define max(a,b) ((a>b)? a:b)
00047 #endif
00048 #ifndef min
00049 #define min(a,b) ((a>b)? b:a)
00050 #endif
00051 
00052 #include <GL/gl.h>
00053 
00054 #include "glimports.h"
00055 #include "zlassert.h"
00056 #include "sampleMonoPoly.h"
00057 #include "sampleComp.h"
00058 #include "polyDBG.h"
00059 #include "partitionX.h"
00060 
00061 
00062 #define ZERO 0.00001
00063 
00064 //#define  MYDEBUG
00065 
00066 //#define SHORTEN_GRID_LINE
00067 //see work/newtess/internal/test/problems
00068 
00069 
00070 /*split a polygon so that each vertex correcpond to one edge
00071  *the head of the first edge of the returned plygon must be the head of the first
00072  *edge of the origianl polygon. This is crucial for the code in sampleMonoPoly function
00073  */
00074  directedLine*  polygonConvert(directedLine* polygon)
00075 {
00076   int i;
00077   directedLine* ret;
00078   sampledLine* sline;
00079   sline = new sampledLine(2);
00080   sline->setPoint(0, polygon->getVertex(0));
00081   sline->setPoint(1, polygon->getVertex(1));
00082   ret=new directedLine(INCREASING, sline);
00083   for(i=1; i<= polygon->get_npoints()-2; i++)
00084     {
00085       sline = new sampledLine(2);
00086       sline->setPoint(0, polygon->getVertex(i));
00087       sline->setPoint(1, polygon->getVertex(i+1));
00088       ret->insert(new directedLine(INCREASING, sline));
00089     }
00090 
00091   for(directedLine *temp = polygon->getNext(); temp != polygon; temp = temp->getNext())
00092     {
00093       for(i=0; i<= temp->get_npoints()-2; i++)
00094     {
00095       sline = new sampledLine(2);
00096       sline->setPoint(0, temp->getVertex(i));
00097       sline->setPoint(1, temp->getVertex(i+1));
00098       ret->insert(new directedLine(INCREASING, sline));
00099     }
00100     }
00101   return ret;
00102 }
00103 
00104 void triangulateConvexPolyVertical(directedLine* topV, directedLine* botV, primStream *pStream)
00105 {
00106   Int i,j;
00107   Int n_leftVerts;
00108   Int n_rightVerts;
00109   Real** leftVerts;
00110   Real** rightVerts;
00111   directedLine* tempV;
00112   n_leftVerts = 0;
00113   for(tempV = topV; tempV != botV; tempV = tempV->getNext())
00114     {
00115       n_leftVerts += tempV->get_npoints();
00116     }
00117   n_rightVerts=0;
00118   for(tempV = botV; tempV != topV; tempV = tempV->getNext())
00119     {
00120       n_rightVerts += tempV->get_npoints();
00121     }
00122 
00123   Real2* temp_leftVerts = (Real2 *) malloc(sizeof(Real2) * n_leftVerts);
00124   assert(temp_leftVerts);
00125   Real2* temp_rightVerts = (Real2 *) malloc(sizeof(Real2) * n_rightVerts);
00126   assert(temp_rightVerts);
00127 
00128   leftVerts = (Real**) malloc(sizeof(Real2*) * n_leftVerts);
00129   assert(leftVerts);
00130   rightVerts = (Real**) malloc(sizeof(Real2*) * n_rightVerts);
00131   assert(rightVerts);
00132   for(i=0; i<n_leftVerts; i++)
00133     leftVerts[i] = temp_leftVerts[i];
00134   for(i=0; i<n_rightVerts; i++)
00135     rightVerts[i] = temp_rightVerts[i];
00136 
00137   i=0;
00138   for(tempV = topV; tempV != botV; tempV = tempV->getNext())
00139     {
00140       for(j=1; j<tempV->get_npoints(); j++)
00141     {
00142       leftVerts[i][0] = tempV->getVertex(j)[0];
00143       leftVerts[i][1] = tempV->getVertex(j)[1];
00144       i++;
00145     }
00146     }
00147   n_leftVerts = i;
00148   i=0;
00149   for(tempV = topV->getPrev(); tempV != botV->getPrev(); tempV = tempV->getPrev())
00150     {
00151       for(j=tempV->get_npoints()-1; j>=1; j--)
00152     {
00153       rightVerts[i][0] = tempV->getVertex(j)[0];
00154       rightVerts[i][1] = tempV->getVertex(j)[1];
00155       i++;
00156     }
00157     }
00158   n_rightVerts = i;
00159   triangulateXYMonoTB(n_leftVerts, leftVerts, n_rightVerts, rightVerts, pStream);
00160   free(leftVerts);
00161   free(rightVerts);
00162   free(temp_leftVerts);
00163   free(temp_rightVerts);
00164 }  
00165 
00166 void triangulateConvexPolyHoriz(directedLine* leftV, directedLine* rightV, primStream *pStream)
00167 {
00168   Int i,j;
00169   Int n_lowerVerts;
00170   Int n_upperVerts;
00171   Real2 *lowerVerts;
00172   Real2 *upperVerts;
00173   directedLine* tempV;
00174   n_lowerVerts=0;
00175   for(tempV = leftV; tempV != rightV; tempV = tempV->getNext())
00176     {
00177       n_lowerVerts += tempV->get_npoints();
00178     }
00179   n_upperVerts=0;
00180   for(tempV = rightV; tempV != leftV; tempV = tempV->getNext())
00181     {
00182       n_upperVerts += tempV->get_npoints();
00183     }
00184   lowerVerts = (Real2 *) malloc(sizeof(Real2) * n_lowerVerts);
00185   assert(n_lowerVerts);
00186   upperVerts = (Real2 *) malloc(sizeof(Real2) * n_upperVerts);
00187   assert(n_upperVerts);
00188   i=0;
00189   for(tempV = leftV; tempV != rightV; tempV = tempV->getNext())
00190     {
00191       for(j=0; j<tempV->get_npoints(); j++)
00192     {
00193       lowerVerts[i][0] = tempV->getVertex(j)[0];
00194       lowerVerts[i][1] = tempV->getVertex(j)[1];
00195       i++;
00196     }
00197     }
00198   i=0;
00199   for(tempV = leftV->getPrev(); tempV != rightV->getPrev(); tempV = tempV->getPrev())
00200     {
00201       for(j=tempV->get_npoints()-1; j>=0; j--)
00202     {
00203       upperVerts[i][0] = tempV->getVertex(j)[0];
00204       upperVerts[i][1] = tempV->getVertex(j)[1];
00205       i++;
00206     }
00207     }
00208   triangulateXYMono(n_upperVerts, upperVerts, n_lowerVerts, lowerVerts, pStream);
00209   free(lowerVerts);
00210   free(upperVerts);
00211 }  
00212 void triangulateConvexPoly(directedLine* polygon, Int ulinear, Int vlinear, primStream* pStream)
00213 {
00214   /*find left, right, top , bot
00215     */
00216   directedLine* tempV;
00217   directedLine* topV;
00218   directedLine* botV;
00219   directedLine* leftV;
00220   directedLine* rightV;
00221   topV = botV = polygon;
00222 
00223   for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
00224     {
00225       if(compV2InY(topV->head(), tempV->head())<0) {
00226 
00227     topV = tempV;
00228       }
00229       if(compV2InY(botV->head(), tempV->head())>0) {
00230 
00231     botV = tempV;
00232       }
00233     }
00234   //find leftV
00235   for(tempV = topV; tempV != botV; tempV = tempV->getNext())
00236     {
00237       if(tempV->tail()[0] >= tempV->head()[0])
00238     break;
00239     }
00240   leftV = tempV;
00241   //find rightV
00242   for(tempV = botV; tempV != topV; tempV = tempV->getNext())
00243     {
00244       if(tempV->tail()[0] <= tempV->head()[0])
00245     break;
00246     }
00247   rightV = tempV;
00248   if(vlinear)
00249     {
00250       triangulateConvexPolyHoriz( leftV, rightV, pStream);
00251     }
00252   else if(ulinear)
00253     {
00254       triangulateConvexPolyVertical(topV, botV, pStream);
00255     }
00256   else
00257     {
00258       if(DBG_is_U_direction(polygon))
00259     {
00260       triangulateConvexPolyHoriz( leftV, rightV, pStream);
00261     }
00262       else
00263     triangulateConvexPolyVertical(topV, botV, pStream);
00264     }
00265 }         
00266 
00267 /*for debug purpose*/
00268 void drawCorners(
00269          Real* topV, Real* botV,         
00270          vertexArray* leftChain,
00271          vertexArray* rightChain,
00272          gridBoundaryChain* leftGridChain,
00273          gridBoundaryChain* rightGridChain,
00274          Int gridIndex1,
00275          Int gridIndex2,
00276          Int leftCornerWhere,
00277          Int leftCornerIndex,
00278          Int rightCornerWhere,
00279          Int rightCornerIndex,
00280          Int bot_leftCornerWhere,
00281          Int bot_leftCornerIndex,
00282          Int bot_rightCornerWhere,
00283          Int bot_rightCornerIndex)
00284 {
00285   Real* leftCornerV;
00286   Real* rightCornerV;
00287   Real* bot_leftCornerV;
00288   Real* bot_rightCornerV;
00289 
00290   if(leftCornerWhere == 1)
00291     leftCornerV = topV;
00292   else if(leftCornerWhere == 0)
00293     leftCornerV = leftChain->getVertex(leftCornerIndex);
00294   else
00295     leftCornerV = rightChain->getVertex(leftCornerIndex);
00296 
00297   if(rightCornerWhere == 1)
00298     rightCornerV = topV;
00299   else if(rightCornerWhere == 0)
00300     rightCornerV = leftChain->getVertex(rightCornerIndex);
00301   else
00302     rightCornerV = rightChain->getVertex(rightCornerIndex);
00303 
00304   if(bot_leftCornerWhere == 1)
00305     bot_leftCornerV = botV;
00306   else if(bot_leftCornerWhere == 0)
00307     bot_leftCornerV = leftChain->getVertex(bot_leftCornerIndex);
00308   else
00309     bot_leftCornerV = rightChain->getVertex(bot_leftCornerIndex);
00310 
00311   if(bot_rightCornerWhere == 1)
00312     bot_rightCornerV = botV;
00313   else if(bot_rightCornerWhere == 0)
00314     bot_rightCornerV = leftChain->getVertex(bot_rightCornerIndex);
00315   else
00316     bot_rightCornerV = rightChain->getVertex(bot_rightCornerIndex);
00317 
00318   Real topGridV = leftGridChain->get_v_value(gridIndex1);
00319   Real topGridU1 = leftGridChain->get_u_value(gridIndex1);
00320   Real topGridU2 = rightGridChain->get_u_value(gridIndex1);
00321   Real botGridV = leftGridChain->get_v_value(gridIndex2);
00322   Real botGridU1 = leftGridChain->get_u_value(gridIndex2);
00323   Real botGridU2 = rightGridChain->get_u_value(gridIndex2);
00324   
00325   glBegin(GL_LINE_STRIP);
00326   glVertex2fv(leftCornerV);
00327   glVertex2f(topGridU1, topGridV);
00328   glEnd();
00329 
00330   glBegin(GL_LINE_STRIP);
00331   glVertex2fv(rightCornerV);
00332   glVertex2f(topGridU2, topGridV);
00333   glEnd();
00334 
00335   glBegin(GL_LINE_STRIP);
00336   glVertex2fv(bot_leftCornerV);
00337   glVertex2f(botGridU1, botGridV);
00338   glEnd();
00339 
00340   glBegin(GL_LINE_STRIP);
00341   glVertex2fv(bot_rightCornerV);
00342   glVertex2f(botGridU2, botGridV);
00343   glEnd();
00344 
00345 
00346 }
00347          
00348 void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain)
00349 {  
00350   Int i;
00351   directedLine* tempV;
00352   for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
00353     leftChain.appendVertex(topV->getVertex(i));
00354   }
00355   for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
00356     {
00357       for(i=0; i<=tempV->get_npoints()-2; i++){
00358     leftChain.appendVertex(tempV->getVertex(i));
00359       }
00360     }  
00361 
00362   for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
00363     {
00364       for(i=tempV->get_npoints()-2; i>=0; i--){
00365     rightChain.appendVertex(tempV->getVertex(i));
00366       }
00367     }
00368   for(i=botV->get_npoints()-2; i>=1; i--){ 
00369     rightChain.appendVertex(tempV->getVertex(i));
00370   }
00371 }
00372 
00373 
00374 void findTopAndBot(directedLine* polygon, directedLine*& topV, directedLine*& botV)
00375 {
00376   assert(polygon);
00377   directedLine* tempV;
00378   topV = botV = polygon;
00379    for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
00380     {
00381       if(compV2InY(topV->head(), tempV->head())<0) {
00382     topV = tempV;
00383       }
00384       if(compV2InY(botV->head(), tempV->head())>0) {
00385     botV = tempV;
00386       }
00387     }
00388 }
00389    
00390 void findGridChains(directedLine* topV, directedLine* botV, 
00391             gridWrap* grid,
00392             gridBoundaryChain*& leftGridChain,
00393             gridBoundaryChain*& rightGridChain)
00394 {
00395   /*find the first(top) and the last (bottom) grid line which intersect the
00396    *this polygon
00397    */
00398   Int firstGridIndex; /*the index in the grid*/
00399   Int lastGridIndex;
00400 
00401   firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1));
00402 
00403   if(botV->head()[1] < grid->get_v_min())
00404     lastGridIndex = 0;
00405   else
00406     lastGridIndex  = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1;
00407 
00408   /*find the interval inside  the polygon for each gridline*/
00409   Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
00410   assert(leftGridIndices);
00411   Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
00412   assert(rightGridIndices);
00413   Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
00414   assert(leftGridInnerIndices);
00415   Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
00416   assert(rightGridInnerIndices);
00417 
00418   findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid,  leftGridIndices, leftGridInnerIndices);
00419 
00420   findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid,  rightGridIndices, rightGridInnerIndices);
00421 
00422   leftGridChain =  new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices);
00423 
00424   rightGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices);
00425 
00426   free(leftGridIndices);
00427   free(rightGridIndices);
00428   free(leftGridInnerIndices);
00429   free(rightGridInnerIndices);
00430 }
00431 
00432 void findDownCorners(Real *botVertex, 
00433            vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
00434            vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
00435            Real v,
00436            Real uleft,
00437            Real uright,
00438            Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
00439            Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/
00440            Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
00441            Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/
00442            )
00443 {
00444 #ifdef MYDEBUG
00445 printf("*************enter find donw corner\n");
00446 printf("finddownCorner: v=%f, uleft=%f, uright=%f\n", v, uleft, uright);
00447 printf("(%i,%i,%i,%i)\n", leftChainStartIndex, leftChainEndIndex,rightChainStartIndex, rightChainEndIndex); 
00448 printf("left chain is\n");
00449 leftChain->print();
00450 printf("right chain is\n");
00451 rightChain->print();
00452 #endif
00453 
00454   assert(v > botVertex[1]);
00455   Real leftGridPoint[2];
00456   leftGridPoint[0] = uleft;
00457   leftGridPoint[1] = v;
00458   Real rightGridPoint[2];
00459   rightGridPoint[0] = uright;
00460   rightGridPoint[1] = v;
00461 
00462   Int i;
00463   Int index1, index2;
00464 
00465   index1 = leftChain->findIndexBelowGen(v, leftChainStartIndex, leftChainEndIndex);
00466   index2 = rightChain->findIndexBelowGen(v, rightChainStartIndex, rightChainEndIndex);
00467 
00468   if(index2 <= rightChainEndIndex) //index2 was found above
00469     index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex);
00470 
00471   if(index1>leftChainEndIndex && index2 > rightChainEndIndex) /*no point below v on left chain or right chain*/
00472     {
00473 
00474       /*the botVertex is the only vertex below v*/
00475       ret_leftCornerWhere = 1;
00476       ret_rightCornerWhere = 1;
00477     }
00478   else if(index1>leftChainEndIndex ) /*index2 <= rightChainEndIndex*/
00479     {
00480 
00481       ret_rightCornerWhere = 2; /*on right chain*/
00482       ret_rightCornerIndex = index2;
00483 
00484 
00485       Real tempMin = rightChain->getVertex(index2)[0];
00486       Int tempI = index2;
00487       for(i=index2+1; i<= rightChainEndIndex; i++)
00488     if(rightChain->getVertex(i)[0] < tempMin)
00489       {
00490         tempI = i;
00491         tempMin = rightChain->getVertex(i)[0];
00492       }
00493 
00494 
00495       //we consider whether we can use botVertex as left corner. First check 
00496       //if (leftGirdPoint, botVertex) interesects right chian or not.
00497      if(DBG_intersectChain(rightChain, rightChainStartIndex,rightChainEndIndex,
00498                     leftGridPoint, botVertex))
00499        {
00500      ret_leftCornerWhere = 2;//right
00501      ret_leftCornerIndex = index2; //should use tempI???
00502        }
00503      else if(botVertex[0] < tempMin)
00504        ret_leftCornerWhere = 1; //bot
00505      else
00506        {
00507      ret_leftCornerWhere = 2; //right
00508      ret_leftCornerIndex = tempI;
00509        }
00510     }
00511   else if(index2> rightChainEndIndex) /*index1<=leftChainEndIndex*/
00512     {
00513       ret_leftCornerWhere = 0; /*left chain*/
00514       ret_leftCornerIndex = index1;
00515       
00516       /*find the vertex on the left chain with the maximum u,
00517        *either this vertex or the botvertex can be used as the right corner
00518        */
00519 
00520       Int tempI;
00521       //skip those points which are equal to v. (avoid degeneratcy)
00522       for(tempI = index1; tempI <= leftChainEndIndex; tempI++)
00523     if(leftChain->getVertex(tempI)[1] < v) 
00524       break;
00525       if(tempI > leftChainEndIndex)
00526     ret_rightCornerWhere = 1;
00527       else
00528     {
00529       Real tempMax = leftChain->getVertex(tempI)[0];
00530       for(i=tempI; i<= leftChainEndIndex; i++)
00531         if(leftChain->getVertex(i)[0] > tempMax)
00532           {
00533         tempI = i;
00534         tempMax = leftChain->getVertex(i)[0];
00535           }
00536 
00537 
00538 
00539       //we consider whether we can use botVertex as a corner. So first we check 
00540       //whether (rightGridPoint, botVertex) interescts the left chain or not.
00541       if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex,
00542                     rightGridPoint, botVertex))
00543         {
00544           ret_rightCornerWhere = 0;
00545           ret_rightCornerIndex = index1; //should use tempI???
00546         }
00547       else if(botVertex[0] > tempMax)
00548         {
00549               
00550               ret_rightCornerWhere = 1;
00551         }
00552       else
00553         {
00554           ret_rightCornerWhere = 0;
00555           ret_rightCornerIndex = tempI;
00556         }
00557     }
00558       
00559     }
00560   else /*index1<=leftChainEndIndex and index2 <=rightChainEndIndex*/
00561     {
00562       if(leftChain->getVertex(index1)[1] >= rightChain->getVertex(index2)[1]) /*left point above right point*/
00563     {
00564       ret_leftCornerWhere = 0; /*on left chain*/
00565       ret_leftCornerIndex = index1;
00566 
00567       Real tempMax;
00568       Int tempI;
00569 
00570       tempI = index1;
00571       tempMax = leftChain->getVertex(index1)[0];
00572 
00573       /*find the maximum u for all the points on the left above the right point index2*/
00574       for(i=index1+1; i<= leftChainEndIndex; i++)
00575         {
00576           if(leftChain->getVertex(i)[1] < rightChain->getVertex(index2)[1])
00577         break;
00578 
00579           if(leftChain->getVertex(i)[0]>tempMax)
00580         {
00581           tempI = i;
00582           tempMax = leftChain->getVertex(i)[0];
00583         }
00584         }
00585       //we consider if we can use rightChain(index2) as right corner
00586       //we check if (rightChain(index2), rightGidPoint) intersecs left chain or not.
00587       if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2)))
00588         {
00589           ret_rightCornerWhere = 0;
00590           ret_rightCornerIndex = index1; //should use tempI???
00591         }
00592       else if(tempMax >= rightChain->getVertex(index2)[0] ||
00593          tempMax >= uright
00594          )
00595         {
00596 
00597           ret_rightCornerWhere = 0; /*on left Chain*/
00598           ret_rightCornerIndex = tempI;
00599         }
00600       else
00601         {
00602           ret_rightCornerWhere = 2; /*on right chain*/
00603           ret_rightCornerIndex = index2;
00604         }
00605     }
00606       else /*left below right*/
00607     {
00608       ret_rightCornerWhere = 2; /*on the right*/
00609       ret_rightCornerIndex = index2;
00610       
00611       Real tempMin;
00612       Int tempI;
00613       
00614       tempI = index2;
00615       tempMin = rightChain->getVertex(index2)[0];
00616       
00617       /*find the minimum u for all the points on the right above the left poitn index1*/
00618       for(i=index2+1; i<= rightChainEndIndex; i++)
00619         {
00620           if( rightChain->getVertex(i)[1] < leftChain->getVertex(index1)[1])
00621         break;
00622           if(rightChain->getVertex(i)[0] < tempMin)
00623         {
00624           tempI = i;
00625           tempMin = rightChain->getVertex(i)[0];
00626         }
00627         }
00628 
00629       //we consider if we can use leftchain(index1) as left corner. 
00630       //we check if (leftChain(index1) intersects right chian or not
00631       if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, leftGridPoint, leftChain->getVertex(index1)))
00632         {
00633           ret_leftCornerWhere = 2;
00634           ret_leftCornerIndex = index2; //should use tempI???
00635           }
00636       else if(tempMin <= leftChain->getVertex(index1)[0] ||
00637          tempMin <= uleft)              
00638         {
00639           ret_leftCornerWhere = 2; /* on right chain*/
00640           ret_leftCornerIndex = tempI;
00641         }
00642       else
00643         {
00644           ret_leftCornerWhere = 0; /*on left chain*/
00645           ret_leftCornerIndex = index1;
00646         }
00647     }
00648     }
00649 
00650 }
00651 
00652 
00653 void findUpCorners(Real *topVertex, 
00654            vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
00655            vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
00656            Real v,
00657            Real uleft,
00658            Real uright,
00659            Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
00660            Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/
00661            Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
00662            Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/
00663            )
00664 {
00665 #ifdef MYDEBUG
00666 printf("***********enter findUpCorners\n");
00667 #endif
00668 
00669   assert(v < topVertex[1]);
00670   Real leftGridPoint[2];
00671   leftGridPoint[0] = uleft;
00672   leftGridPoint[1] = v;
00673   Real rightGridPoint[2];
00674   rightGridPoint[0] = uright;
00675   rightGridPoint[1] = v;
00676 
00677   Int i;
00678   Int index1, index2;
00679 
00680   index1 = leftChain->findIndexFirstAboveEqualGen(v, leftChainStartIndex, leftChainEndIndex);
00681 
00682 
00683   index2 = rightChain->findIndexFirstAboveEqualGen(v, rightChainStartIndex, rightChainEndIndex);
00684 
00685   if(index2>= leftChainStartIndex)  //index2 was found above  
00686     index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex);
00687 
00688   if(index1<leftChainStartIndex && index2 <rightChainStartIndex) /*no point above v on left chain or right chain*/
00689     {
00690       /*the topVertex is the only vertex above v*/
00691       ret_leftCornerWhere = 1;
00692       ret_rightCornerWhere = 1;
00693     }
00694   else if(index1<leftChainStartIndex ) /*index2 >= rightChainStartIndex*/
00695     {
00696       ret_rightCornerWhere = 2; /*on right chain*/
00697       ret_rightCornerIndex = index2;
00698 
00699       //find the minimum u on right top, either that, or top, or right[index2] is the left corner
00700       Real tempMin = rightChain->getVertex(index2)[0];
00701       Int tempI = index2;
00702       for(i=index2-1; i>=rightChainStartIndex; i--)
00703     if(rightChain->getVertex(i)[0] < tempMin)
00704       {
00705         tempMin = rightChain->getVertex(i)[0];
00706         tempI = i;
00707       }
00708       //chech whether (leftGridPoint, top) intersects rightchai,
00709       //if yes, use right corner as left corner
00710       //if not, use top or right[tempI] as left corner
00711       if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex,
00712             leftGridPoint, topVertex))
00713     {
00714       ret_leftCornerWhere = 2; //rightChain
00715       ret_leftCornerIndex = index2; 
00716     }
00717       else if(topVertex[0] < tempMin)
00718     ret_leftCornerWhere = 1; /*topvertex*/
00719       else
00720     {
00721       ret_leftCornerWhere = 2; //right chain
00722       ret_leftCornerIndex = tempI;
00723     }
00724           
00725     }
00726   else if(index2< rightChainStartIndex) /*index1>=leftChainStartIndex*/
00727     {
00728       ret_leftCornerWhere = 0; /*left chain*/
00729       ret_leftCornerIndex = index1;
00730        
00731       //find the maximum u on the left top section. either that or topvertex, or left[index1]  is the right corner
00732       Real tempMax = leftChain->getVertex(index1)[0];
00733       Int tempI = index1;
00734 
00735       for(i=index1-1; i>=leftChainStartIndex; i--){
00736 
00737     if(leftChain->getVertex(i)[0] > tempMax)
00738       {
00739 
00740         tempMax = leftChain->getVertex(i)[0];
00741         tempI = i;
00742       }
00743       }
00744       //check whether (rightGridPoint, top) intersects leftChain or not
00745       //if yes, we use leftCorner as the right corner
00746       //if not, we use either top or left[tempI] as the right corner
00747       if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex,
00748                 rightGridPoint, topVertex))
00749      {
00750        ret_rightCornerWhere = 0; //left chan
00751        ret_rightCornerIndex = index1;
00752      }
00753       else if(topVertex[0] > tempMax)
00754     ret_rightCornerWhere = 1;//topVertex
00755       else
00756     {
00757       ret_rightCornerWhere = 0;//left chain
00758       ret_rightCornerIndex = tempI;
00759     }
00760     }
00761   else /*index1>=leftChainStartIndex and index2 >=rightChainStartIndex*/
00762     {
00763       if(leftChain->getVertex(index1)[1] <= rightChain->getVertex(index2)[1]) /*left point below right point*/
00764     {
00765       ret_leftCornerWhere = 0; /*on left chain*/
00766       ret_leftCornerIndex = index1;
00767 
00768       Real tempMax;
00769       Int tempI;
00770 
00771       tempI = index1;
00772       tempMax = leftChain->getVertex(index1)[0];
00773 
00774       /*find the maximum u for all the points on the left below the right point index2*/
00775       for(i=index1-1; i>= leftChainStartIndex; i--)
00776         {
00777           if(leftChain->getVertex(i)[1] > rightChain->getVertex(index2)[1])
00778         break;
00779 
00780           if(leftChain->getVertex(i)[0]>tempMax)
00781         {
00782           tempI = i;
00783           tempMax = leftChain->getVertex(i)[0];
00784         }
00785         }
00786       //chek whether (rightChain(index2), rightGridPoint) intersects leftchian or not
00787       if(DBG_intersectChain(leftChain, leftChainStartIndex, leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2)))
00788          {
00789            ret_rightCornerWhere = 0;
00790            ret_rightCornerIndex = index1;
00791          }
00792       else if(tempMax >= rightChain->getVertex(index2)[0] ||
00793          tempMax >= uright)
00794         {
00795           ret_rightCornerWhere = 0; /*on left Chain*/
00796           ret_rightCornerIndex = tempI;
00797         }
00798       else
00799         {
00800           ret_rightCornerWhere = 2; /*on right chain*/
00801           ret_rightCornerIndex = index2;
00802         }
00803     }
00804       else /*left above right*/
00805     {
00806       ret_rightCornerWhere = 2; /*on the right*/
00807       ret_rightCornerIndex = index2;
00808       
00809       Real tempMin;
00810       Int tempI;
00811       
00812       tempI = index2;
00813       tempMin = rightChain->getVertex(index2)[0];
00814       
00815       /*find the minimum u for all the points on the right below the left poitn index1*/
00816       for(i=index2-1; i>= rightChainStartIndex; i--)
00817         {
00818           if( rightChain->getVertex(i)[1] > leftChain->getVertex(index1)[1])
00819         break;
00820           if(rightChain->getVertex(i)[0] < tempMin)
00821         {
00822           tempI = i;
00823           tempMin = rightChain->getVertex(i)[0];
00824         }
00825         }
00826           //check whether (leftGRidPoint,left(index1)) interesect right chain 
00827       if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex,
00828                 leftGridPoint, leftChain->getVertex(index1)))
00829         {
00830           ret_leftCornerWhere = 2; //right
00831           ret_leftCornerIndex = index2;
00832         }
00833       else if(tempMin <= leftChain->getVertex(index1)[0] ||
00834          tempMin <= uleft)
00835         {
00836           ret_leftCornerWhere = 2; /* on right chain*/
00837           ret_leftCornerIndex = tempI;
00838         }
00839       else
00840         {
00841           ret_leftCornerWhere = 0; /*on left chain*/
00842           ret_leftCornerIndex = index1;
00843         }
00844     }
00845     }
00846 #ifdef MYDEBUG
00847 printf("***********leave findUpCorners\n");
00848 #endif
00849 }
00850 
00851 //return 1 if neck exists, 0 othewise
00852 Int findNeckF(vertexArray *leftChain, Int botLeftIndex,
00853           vertexArray *rightChain, Int botRightIndex,
00854           gridBoundaryChain* leftGridChain,
00855           gridBoundaryChain* rightGridChain,
00856           Int gridStartIndex,
00857           Int& neckLeft, 
00858           Int& neckRight)
00859 {
00860 /*
00861 printf("enter findNeckF, botleft, botright=%i,%i,gstartindex=%i\n",botLeftIndex,botRightIndex,gridStartIndex);
00862 printf("leftChain is\n");
00863 leftChain->print();
00864 printf("rightChain is\n");
00865 rightChain->print();
00866 */
00867 
00868   Int lowerGridIndex; //the grid below leftChain and rightChian vertices
00869   Int i;
00870   Int n_vlines = leftGridChain->get_nVlines();
00871   Real v;
00872   if(botLeftIndex >= leftChain->getNumElements() ||
00873      botRightIndex >= rightChain->getNumElements())
00874     return 0; //no neck exists
00875      
00876   v=min(leftChain->getVertex(botLeftIndex)[1], rightChain->getVertex(botRightIndex)[1]);  
00877 
00878  
00879 
00880 
00881   for(i=gridStartIndex; i<n_vlines; i++)
00882     if(leftGridChain->get_v_value(i) <= v && 
00883        leftGridChain->getUlineIndex(i)<= rightGridChain->getUlineIndex(i))
00884       break;
00885   
00886   lowerGridIndex = i;
00887 
00888   if(lowerGridIndex == n_vlines) //the two trm vertex are higher than all gridlines
00889     return 0;
00890   else 
00891     {
00892       Int botLeft2, botRight2;
00893 /*
00894 printf("leftGridChain->get_v_)value=%f\n",leftGridChain->get_v_value(lowerGridIndex), botLeftIndex); 
00895 printf("leftChain->get_vertex(0)=(%f,%f)\n", leftChain->getVertex(0)[0],leftChain->getVertex(0)[1]);
00896 printf("leftChain->get_vertex(1)=(%f,%f)\n", leftChain->getVertex(1)[0],leftChain->getVertex(1)[1]);
00897 printf("leftChain->get_vertex(2)=(%f,%f)\n", leftChain->getVertex(2)[0],leftChain->getVertex(2)[1]);
00898 */
00899       botLeft2 = leftChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botLeftIndex, leftChain->getNumElements()-1) -1 ;
00900 
00901 /*
00902 printf("botLeft2=%i\n", botLeft2);
00903 printf("leftChain->getNumElements=%i\n", leftChain->getNumElements());
00904 */
00905 
00906       botRight2 = rightChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botRightIndex, rightChain->getNumElements()-1) -1;
00907       if(botRight2 < botRightIndex) botRight2=botRightIndex;
00908 
00909       if(botLeft2 < botLeftIndex) botLeft2 = botLeftIndex;
00910 
00911       assert(botLeft2 >= botLeftIndex);
00912       assert(botRight2 >= botRightIndex);
00913       //find nectLeft so that it is th erightmost vertex on letChain
00914 
00915       Int tempI = botLeftIndex;
00916       Real temp = leftChain->getVertex(tempI)[0];
00917       for(i=botLeftIndex+1; i<= botLeft2; i++)
00918     if(leftChain->getVertex(i)[0] > temp)
00919       {
00920         temp = leftChain->getVertex(i)[0];
00921         tempI = i;
00922       }
00923       neckLeft = tempI;
00924 
00925       tempI = botRightIndex;
00926       temp = rightChain->getVertex(tempI)[0];
00927       for(i=botRightIndex+1; i<= botRight2; i++)
00928     if(rightChain->getVertex(i)[0] < temp)
00929       {
00930         temp = rightChain->getVertex(i)[0];
00931         tempI = i;
00932       }
00933       neckRight = tempI;
00934       return 1;
00935     }
00936 }
00937                             
00938   
00939               
00940 /*find i>=botLeftIndex,j>=botRightIndex so that
00941  *(leftChain[i], rightChain[j]) is a neck.
00942  */
00943 void findNeck(vertexArray *leftChain, Int botLeftIndex, 
00944           vertexArray *rightChain, Int botRightIndex, 
00945           Int& leftLastIndex, /*left point of the neck*/
00946           Int& rightLastIndex /*right point of the neck*/
00947           )
00948 {
00949   assert(botLeftIndex < leftChain->getNumElements() &&
00950      botRightIndex < rightChain->getNumElements());
00951      
00952   /*now the neck exists for sure*/
00953 
00954   if(leftChain->getVertex(botLeftIndex)[1] <= rightChain->getVertex(botRightIndex)[1]) //left below right
00955     {
00956 
00957       leftLastIndex = botLeftIndex;
00958       
00959       /*find i so that rightChain[i][1] >= leftchainbotverte[1], and i+1<
00960        */
00961       rightLastIndex=rightChain->findIndexAboveGen(leftChain->getVertex(botLeftIndex)[1], botRightIndex+1, rightChain->getNumElements()-1);    
00962     }
00963   else  //left above right
00964     {
00965 
00966       rightLastIndex = botRightIndex;
00967      
00968       leftLastIndex = leftChain->findIndexAboveGen(rightChain->getVertex(botRightIndex)[1], 
00969                           botLeftIndex+1,
00970                           leftChain->getNumElements()-1);
00971     }
00972 }
00973       
00974       
00975 
00976 void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid,  Int* ret_indices, Int* ret_innerIndices)
00977 {
00978 
00979   Int i,k,isHoriz = 0;
00980   Int n_ulines = grid->get_n_ulines();
00981   Real uMin = grid->get_u_min();
00982   Real uMax = grid->get_u_max();
00983   Real slop = 0.0f, uinterc;
00984 
00985 #ifdef SHORTEN_GRID_LINE
00986   //uintercBuf stores all the interction u value for each grid line
00987   //notice that lastGridIndex<= firstGridIndex
00988   Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
00989   assert(uintercBuf);
00990 #endif
00991 
00992   /*initialization to make vtail bigger than grid->...*/
00993   directedLine* dLine = topEdge;
00994   Real vtail = grid->get_v_value(firstGridIndex) + 1.0; 
00995   Real tempMaxU = grid->get_u_min();
00996 
00997 
00998   /*for each grid line*/
00999   for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
01000     {
01001 
01002       Real grid_v_value = grid->get_v_value(i);
01003 
01004       /*check whether this grid line is below the current trim edge.*/
01005       if(vtail > grid_v_value)
01006     {
01007       /*since the grid line is below the trim edge, we 
01008        *find the trim edge which will contain the trim line
01009        */
01010       while( (vtail=dLine->tail()[1]) > grid_v_value){
01011 
01012         tempMaxU = max(tempMaxU, dLine->tail()[0]);
01013         dLine = dLine -> getNext();
01014       }
01015 
01016       if( fabs(dLine->head()[1] - vtail) < ZERO)
01017         isHoriz = 1;
01018       else
01019         {
01020           isHoriz = 0;
01021           slop = (dLine->head()[0] - dLine->tail()[0]) / (dLine->head()[1]-vtail);
01022         }
01023     }
01024 
01025       if(isHoriz)
01026     {
01027       uinterc = max(dLine->head()[0], dLine->tail()[0]);
01028     }
01029       else
01030     {
01031       uinterc = slop * (grid_v_value - vtail) + dLine->tail()[0];
01032     }
01033       
01034       tempMaxU = max(tempMaxU, uinterc);
01035 
01036       if(uinterc < uMin && uinterc >= uMin - ZERO)
01037     uinterc = uMin;
01038       if(uinterc > uMax && uinterc <= uMax + ZERO)
01039     uinterc = uMax;
01040 
01041 #ifdef SHORTEN_GRID_LINE
01042       uintercBuf[k] = uinterc;
01043 #endif
01044 
01045       assert(uinterc >= uMin && uinterc <= uMax);
01046        if(uinterc == uMax)
01047          ret_indices[k] = n_ulines-1;
01048        else
01049      ret_indices[k] = (Int)(((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
01050       if(ret_indices[k] >= n_ulines)
01051     ret_indices[k] = n_ulines-1;
01052 
01053 
01054       ret_innerIndices[k] = (Int)(((tempMaxU-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
01055 
01056       /*reinitialize tempMaxU for next grdiLine*/
01057       tempMaxU = uinterc;
01058     }
01059 #ifdef SHORTEN_GRID_LINE
01060   //for each grid line, compare the left grid point with the 
01061   //intersection point. If the two points are too close, then
01062   //we should move the grid point one grid to the right
01063   //and accordingly we should update the inner index.
01064   for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
01065     {
01066       //check gridLine i
01067       //check ret_indices[k]
01068       Real a = grid->get_u_value(ret_indices[k]-1);
01069       Real b = grid->get_u_value(ret_indices[k]);
01070       assert(uintercBuf[k] >= a && uintercBuf < b);
01071       if( (b-uintercBuf[k]) <= 0.2 * (b-a)) //interc is very close to b
01072     {
01073       ret_indices[k]++;
01074     }
01075 
01076       //check ret_innerIndices[k]
01077       if(k>0)
01078     {
01079       if(ret_innerIndices[k] < ret_indices[k-1])
01080         ret_innerIndices[k] = ret_indices[k-1];
01081       if(ret_innerIndices[k] < ret_indices[k])
01082         ret_innerIndices[k] = ret_indices[k];
01083     }
01084     }
01085   //clean up
01086   free(uintercBuf);
01087 #endif
01088 }
01089 
01090 void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid,  Int* ret_indices, Int* ret_innerIndices)
01091 {
01092 
01093   Int i,k;
01094   Int n_ulines = grid->get_n_ulines();
01095   Real uMin = grid->get_u_min();
01096   Real uMax = grid->get_u_max();
01097   Real slop = 0.0f, uinterc;
01098 
01099 #ifdef SHORTEN_GRID_LINE
01100   //uintercBuf stores all the interction u value for each grid line
01101   //notice that firstGridIndex >= lastGridIndex
01102   Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
01103   assert(uintercBuf);
01104 #endif
01105 
01106   /*initialization to make vhead bigger than grid->v_value...*/
01107   directedLine* dLine = topEdge->getPrev();
01108   Real vhead = dLine->tail()[1];
01109   Real tempMinU = grid->get_u_max();
01110 
01111   /*for each grid line*/
01112   for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
01113     {
01114 
01115       Real grid_v_value = grid->get_v_value(i);
01116 
01117 
01118       /*check whether this grid line is below the current trim edge.*/
01119       if(vhead >= grid_v_value)
01120     {
01121       /*since the grid line is below the tail of the trim edge, we 
01122        *find the trim edge which will contain the trim line
01123        */
01124       while( (vhead=dLine->head()[1]) > grid_v_value){
01125         tempMinU = min(tempMinU, dLine->head()[0]);
01126         dLine = dLine -> getPrev();
01127       }
01128 
01129       /*skip the equality in the case of degenerat case: horizontal */
01130       while(dLine->head()[1] == grid_v_value)
01131         dLine = dLine->getPrev();
01132         
01133       assert( dLine->tail()[1] != dLine->head()[1]);
01134       slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-dLine->head()[1]);
01135       /*
01136        if(dLine->tail()[1] == vhead)
01137          isHoriz = 1;
01138          else
01139         {
01140           isHoriz = 0;
01141           slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-vhead);
01142         }
01143         */
01144     }
01145     uinterc = slop * (grid_v_value - dLine->head()[1]) + dLine->head()[0];
01146 
01147       //in case unterc is outside of the grid due to floating point
01148       if(uinterc < uMin)
01149     uinterc = uMin;
01150       else if(uinterc > uMax)
01151     uinterc = uMax;
01152 
01153 #ifdef SHORTEN_GRID_LINE
01154       uintercBuf[k] = uinterc;
01155 #endif      
01156 
01157       tempMinU = min(tempMinU, uinterc);
01158 
01159       assert(uinterc >= uMin && uinterc <= uMax);      
01160 
01161       if(uinterc == uMin)
01162     ret_indices[k] = 0;
01163       else
01164     ret_indices[k] = (int)ceil((((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
01165 /*
01166 if(ret_indices[k] >= grid->get_n_ulines())
01167   {
01168   printf("ERROR3\n");
01169   exit(0);
01170 }
01171 if(ret_indices[k] < 0)    
01172   {
01173   printf("ERROR4\n");
01174   exit(0);
01175 }
01176 */
01177       ret_innerIndices[k] = (int)ceil ((((tempMinU-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
01178 
01179       tempMinU = uinterc;
01180     }
01181 #ifdef SHORTEN_GRID_LINE
01182   //for each grid line, compare the left grid point with the 
01183   //intersection point. If the two points are too close, then
01184   //we should move the grid point one grid to the right
01185   //and accordingly we should update the inner index.
01186   for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
01187     {
01188       //check gridLine i
01189       //check ret_indices[k]
01190       Real a = grid->get_u_value(ret_indices[k]);
01191       Real b = grid->get_u_value(ret_indices[k]+1);
01192       assert(uintercBuf[k] > a && uintercBuf <= b);
01193       if( (uintercBuf[k]-a) <= 0.2 * (b-a)) //interc is very close to a
01194     {
01195       ret_indices[k]--;
01196     }
01197 
01198       //check ret_innerIndices[k]
01199       if(k>0)
01200     {
01201       if(ret_innerIndices[k] > ret_indices[k-1])
01202         ret_innerIndices[k] = ret_indices[k-1];
01203       if(ret_innerIndices[k] > ret_indices[k])
01204         ret_innerIndices[k] = ret_indices[k];
01205     }
01206     }
01207   //clean up
01208   free(uintercBuf);
01209 #endif
01210 }
01211 
01212 
01213 void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream* pStream, rectBlockArray* rbArray)
01214 {
01215 /*
01216 {
01217 grid->print();
01218 polygon->writeAllPolygons("zloutputFile");
01219 exit(0);
01220 }
01221 */
01222 
01223 if(grid->get_n_ulines() == 2 ||
01224    grid->get_n_vlines() == 2)
01225 { 
01226   if(ulinear && grid->get_n_ulines() == 2)
01227     {
01228       monoTriangulationFun(polygon, compV2InY, pStream);   
01229       return;
01230     }
01231   else if(DBG_isConvex(polygon) && polygon->numEdges() >=4)
01232      {
01233        triangulateConvexPoly(polygon, ulinear, vlinear, pStream);
01234        return;
01235      }
01236   else if(vlinear || DBG_is_U_direction(polygon))
01237     {
01238       Int n_cusps;//num interior cusps
01239       Int n_edges = polygon->numEdges();
01240       directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*) * n_edges);
01241       assert(cusps);
01242       findInteriorCuspsX(polygon, n_cusps, cusps);
01243 
01244       if(n_cusps == 0) //u_monotone
01245     {
01246 
01247       monoTriangulationFun(polygon, compV2InX, pStream);
01248 
01249           free(cusps);
01250           return;          
01251     }
01252       else if(n_cusps == 1) //one interior cusp
01253     {
01254 
01255       directedLine* new_polygon = polygonConvert(cusps[0]);
01256 
01257       directedLine* other = findDiagonal_singleCuspX( new_polygon);
01258 
01259 
01260 
01261       //<other> should NOT be null unless there are self-intersecting
01262           //trim curves. In that case, we don't want to core dump, instead,
01263           //we triangulate anyway, and print out error message.
01264       if(other == NULL)
01265         {
01266           monoTriangulationFun(polygon, compV2InX, pStream);
01267           free(cusps);
01268           return;
01269         }
01270 
01271       directedLine* ret_p1;
01272       directedLine* ret_p2;
01273 
01274       new_polygon->connectDiagonal_2slines(new_polygon, other, 
01275                        &ret_p1,
01276                        &ret_p2,
01277                        new_polygon);
01278 
01279       monoTriangulationFun(ret_p1, compV2InX, pStream);
01280       monoTriangulationFun(ret_p2, compV2InX, pStream);
01281 
01282       ret_p1->deleteSinglePolygonWithSline();         
01283       ret_p2->deleteSinglePolygonWithSline();     
01284 
01285           free(cusps);
01286           return;
01287          }
01288      free(cusps);
01289      }
01290 }
01291 
01292   /*find the top and bottom of the polygon. It is supposed to be
01293    *a V-monotone polygon
01294    */
01295 
01296   directedLine* tempV;
01297   directedLine* topV;
01298   directedLine* botV;
01299   topV = botV = polygon;
01300 
01301   for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
01302     {
01303       if(compV2InY(topV->head(), tempV->head())<0) {
01304 
01305     topV = tempV;
01306       }
01307       if(compV2InY(botV->head(), tempV->head())>0) {
01308 
01309     botV = tempV;
01310       }
01311     }
01312   
01313   /*find the first(top) and the last (bottom) grid line which intersect the
01314    *this polygon
01315    */
01316   Int firstGridIndex; /*the index in the grid*/
01317   Int lastGridIndex;
01318   firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1));
01319   lastGridIndex  = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1;
01320 
01321 
01322   /*find the interval inside  the polygon for each gridline*/
01323   Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
01324   assert(leftGridIndices);
01325   Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
01326   assert(rightGridIndices);
01327   Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
01328   assert(leftGridInnerIndices);
01329   Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
01330   assert(rightGridInnerIndices);
01331 
01332   findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid,  leftGridIndices, leftGridInnerIndices);
01333 
01334   findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid,  rightGridIndices, rightGridInnerIndices);
01335 
01336   gridBoundaryChain leftGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices);
01337 
01338   gridBoundaryChain rightGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices);
01339 
01340 
01341 
01342 //  leftGridChain.draw();
01343 //  leftGridChain.drawInner();
01344 //  rightGridChain.draw();
01345 //  rightGridChain.drawInner();
01346   /*(1) determine the grid boundaries (left and right).
01347    *(2) process polygon  into two monotone chaines: use vertexArray
01348    *(3) call sampleMonoPolyRec
01349    */
01350 
01351   /*copy the two chains into vertexArray datastructure*/
01352   Int i;
01353   vertexArray leftChain(20); /*this is a dynamic array*/
01354   for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
01355     leftChain.appendVertex(topV->getVertex(i));
01356   }
01357   for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
01358     {
01359       for(i=0; i<=tempV->get_npoints()-2; i++){
01360     leftChain.appendVertex(tempV->getVertex(i));
01361       }
01362     }
01363   
01364   vertexArray rightChain(20);
01365   for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
01366     {
01367       for(i=tempV->get_npoints()-2; i>=0; i--){
01368     rightChain.appendVertex(tempV->getVertex(i));
01369       }
01370     }
01371   for(i=botV->get_npoints()-2; i>=1; i--){ 
01372     rightChain.appendVertex(tempV->getVertex(i));
01373   }
01374 
01375   sampleMonoPolyRec(topV->head(),
01376             botV->head(),
01377             &leftChain,
01378             0,
01379             &rightChain,
01380             0,
01381             &leftGridChain,
01382             &rightGridChain,
01383             0,
01384             pStream,
01385             rbArray);
01386 
01387 
01388   /*cleanup space*/
01389   free(leftGridIndices);
01390   free(rightGridIndices);
01391   free(leftGridInnerIndices);
01392   free(rightGridInnerIndices);
01393 }
01394 
01395 void sampleMonoPolyRec(
01396                Real* topVertex,
01397                Real* botVertex,
01398                vertexArray* leftChain, 
01399                Int leftStartIndex,
01400                vertexArray* rightChain,
01401                Int rightStartIndex,
01402                gridBoundaryChain* leftGridChain, 
01403                gridBoundaryChain* rightGridChain, 
01404                Int gridStartIndex,
01405                primStream* pStream,
01406                rectBlockArray* rbArray)
01407 {
01408 
01409   /*find the first connected component, and the four corners.
01410    */
01411   Int index1, index2; /*the first and last grid line of the first connected component*/
01412 
01413   if(topVertex[1] <= botVertex[1])
01414     return;
01415     
01416   /*find i so that the grid line is below the top vertex*/
01417   Int i=gridStartIndex;
01418   while (i < leftGridChain->get_nVlines())
01419     {
01420       if(leftGridChain->get_v_value(i) < topVertex[1])
01421     break;
01422       i++;
01423     }
01424 
01425   /*find the first connected component starting with i*/
01426   /*find index1 so that left_uline_index <= right_uline_index, that is, this
01427    *grid line contains at least one inner grid point
01428    */
01429   index1=i;
01430   int num_skipped_grid_lines=0;
01431   while(index1 < leftGridChain->get_nVlines())
01432     {
01433       if(leftGridChain->getUlineIndex(index1) <= rightGridChain->getUlineIndex(index1))
01434     break;
01435       num_skipped_grid_lines++;
01436       index1++;
01437     }
01438 
01439 
01440 
01441   if(index1 >= leftGridChain->get_nVlines()) /*no grid line exists which has inner point*/
01442     {
01443       /*stop recursion, ...*/
01444       /*monotone triangulate it...*/
01445 //      printf("no grid line exists\n");      
01446 /*
01447       monoTriangulationRecOpt(topVertex, botVertex, leftChain, leftStartIndex,
01448                rightChain, rightStartIndex, pStream);
01449 */
01450 
01451 if(num_skipped_grid_lines <2)
01452   {
01453     monoTriangulationRecGenOpt(topVertex, botVertex, leftChain, leftStartIndex,
01454                    leftChain->getNumElements()-1,
01455                    rightChain, rightStartIndex, 
01456                    rightChain->getNumElements()-1,
01457                    pStream);
01458   }
01459 else
01460   {
01461     //the optimum way to triangulate is top-down since this polygon
01462     //is narrow-long.
01463     monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex,
01464              rightChain, rightStartIndex, pStream);
01465   }
01466 
01467 /*
01468       monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex,
01469                rightChain, rightStartIndex, pStream);
01470 */
01471 
01472 /*      monoTriangulationRecGenTBOpt(topVertex, botVertex, 
01473                    leftChain, leftStartIndex, leftChain->getNumElements()-1,
01474                    rightChain, rightStartIndex, rightChain->getNumElements()-1, 
01475                    pStream);*/
01476       
01477 
01478 
01479     }
01480   else
01481     {
01482 
01483       /*find index2 so that left_inner_index <= right_inner_index holds until index2*/
01484       index2=index1+1;
01485       if(index2 < leftGridChain->get_nVlines())
01486     while(leftGridChain->getInnerIndex(index2) <= rightGridChain->getInnerIndex(index2))
01487       {
01488         index2++;
01489         if(index2 >= leftGridChain->get_nVlines())
01490           break;
01491       }
01492       
01493       index2--;
01494       
01495 
01496       
01497       /*the neck*/
01498       Int neckLeftIndex;
01499       Int neckRightIndex;
01500 
01501       /*the four corners*/
01502       Int up_leftCornerWhere;
01503       Int up_leftCornerIndex;
01504       Int up_rightCornerWhere;
01505       Int up_rightCornerIndex;
01506       Int down_leftCornerWhere;
01507       Int down_leftCornerIndex;
01508       Int down_rightCornerWhere;
01509       Int down_rightCornerIndex;
01510 
01511       Real* tempBotVertex; /*the bottom vertex for this component*/
01512       Real* nextTopVertex=NULL; /*for the recursion*/
01513       Int nextLeftStartIndex=0;
01514       Int nextRightStartIndex=0;
01515 
01516       /*find the points below the grid line index2 on both chains*/
01517       Int botLeftIndex = leftChain->findIndexStrictBelowGen(
01518                               leftGridChain->get_v_value(index2),
01519                               leftStartIndex,
01520                               leftChain->getNumElements()-1);
01521       Int botRightIndex = rightChain->findIndexStrictBelowGen(
01522                             rightGridChain->get_v_value(index2),
01523                             rightStartIndex,
01524                             rightChain->getNumElements()-1);
01525       /*if either botLeftIndex>= numelements,
01526        *        or botRightIndex >= numelemnet,
01527        *then there is no neck exists. the bottom vertex is botVertex, 
01528        */
01529       if(! findNeckF(leftChain, botLeftIndex, rightChain, botRightIndex,
01530            leftGridChain, rightGridChain, index2, neckLeftIndex, neckRightIndex))
01531      /*
01532       if(botLeftIndex == leftChain->getNumElements() ||
01533      botRightIndex == rightChain->getNumElements())
01534      */
01535     {
01536 #ifdef MYDEBUG
01537       printf("neck NOT exists, botRightIndex=%i\n", botRightIndex);
01538 #endif
01539 
01540       tempBotVertex =  botVertex;
01541       nextTopVertex = botVertex;
01542       botLeftIndex = leftChain->getNumElements()-1;
01543       botRightIndex = rightChain->getNumElements()-1;
01544     }
01545       else /*neck exists*/
01546     {
01547 #ifdef MYDEBUG
01548       printf("neck exists\n");
01549 #endif
01550 
01551           /*
01552       findNeck(leftChain, botLeftIndex,
01553            rightChain, botRightIndex,
01554            neckLeftIndex,
01555            neckRightIndex);
01556            */
01557 #ifdef MYDEBUG
01558 printf("neck is found, neckLeftIndex=%i, neckRightIndex=%i\n", neckLeftIndex, neckRightIndex);
01559 glBegin(GL_LINES);
01560 glVertex2fv(leftChain->getVertex(neckLeftIndex));
01561 glVertex2fv(rightChain->getVertex(neckRightIndex));
01562 glEnd();
01563 #endif
01564 
01565       if(leftChain->getVertex(neckLeftIndex)[1] <= rightChain->getVertex(neckRightIndex)[1])
01566         {
01567           tempBotVertex = leftChain->getVertex(neckLeftIndex);
01568           botLeftIndex = neckLeftIndex-1;
01569           botRightIndex = neckRightIndex;
01570           nextTopVertex = rightChain->getVertex(neckRightIndex);
01571           nextLeftStartIndex = neckLeftIndex;
01572           nextRightStartIndex = neckRightIndex+1;
01573         }
01574       else
01575         {
01576           tempBotVertex = rightChain->getVertex(neckRightIndex);
01577           botLeftIndex = neckLeftIndex;
01578           botRightIndex = neckRightIndex-1;       
01579           nextTopVertex = leftChain->getVertex(neckLeftIndex);
01580           nextLeftStartIndex = neckLeftIndex+1;
01581           nextRightStartIndex = neckRightIndex;
01582         }
01583     }
01584 
01585       findUpCorners(topVertex,
01586             leftChain,
01587             leftStartIndex, botLeftIndex,
01588             rightChain,
01589             rightStartIndex, botRightIndex,
01590             leftGridChain->get_v_value(index1),
01591             leftGridChain->get_u_value(index1),
01592             rightGridChain->get_u_value(index1),
01593             up_leftCornerWhere,
01594             up_leftCornerIndex,
01595             up_rightCornerWhere,
01596             up_rightCornerIndex);
01597 
01598       findDownCorners(tempBotVertex,
01599               leftChain,
01600               leftStartIndex, botLeftIndex,
01601               rightChain,
01602               rightStartIndex, botRightIndex,
01603               leftGridChain->get_v_value(index2),
01604               leftGridChain->get_u_value(index2),
01605               rightGridChain->get_u_value(index2),
01606               down_leftCornerWhere,
01607               down_leftCornerIndex,
01608               down_rightCornerWhere,
01609               down_rightCornerIndex);         
01610 #ifdef MYDEBUG
01611       printf("find corners done, down_leftwhere=%i, down_righwhere=%i,\n",down_leftCornerWhere, down_rightCornerWhere );
01612       printf("find corners done, up_leftwhere=%i, up_righwhere=%i,\n",up_leftCornerWhere, up_rightCornerWhere );
01613       printf("find corners done, up_leftindex=%i, up_righindex=%i,\n",up_leftCornerIndex, up_rightCornerIndex );
01614       printf("find corners done, down_leftindex=%i, down_righindex=%i,\n",down_leftCornerIndex, down_rightCornerIndex );
01615 #endif
01616 
01617 /*
01618       drawCorners(topVertex,
01619           tempBotVertex,
01620           leftChain,
01621           rightChain,
01622           leftGridChain,
01623           rightGridChain,
01624           index1,
01625           index2,
01626           up_leftCornerWhere,
01627           up_leftCornerIndex,
01628           up_rightCornerWhere,
01629           up_rightCornerIndex,
01630           down_leftCornerWhere,
01631           down_leftCornerIndex,
01632           down_rightCornerWhere,
01633           down_rightCornerIndex);
01634 */
01635 
01636 
01637       sampleConnectedComp(topVertex, tempBotVertex,
01638               leftChain, 
01639               leftStartIndex, botLeftIndex,
01640               rightChain,
01641               rightStartIndex, botRightIndex,
01642               leftGridChain,
01643               rightGridChain,
01644               index1, index2,
01645               up_leftCornerWhere,
01646               up_leftCornerIndex,
01647               up_rightCornerWhere,
01648               up_rightCornerIndex,
01649               down_leftCornerWhere,
01650               down_leftCornerIndex,
01651               down_rightCornerWhere,
01652               down_rightCornerIndex,
01653               pStream,
01654               rbArray
01655               );
01656 
01657       /*recursion*/
01658 
01659       sampleMonoPolyRec(
01660             nextTopVertex,
01661             botVertex,
01662             leftChain, 
01663             nextLeftStartIndex,
01664             rightChain,
01665             nextRightStartIndex,
01666             leftGridChain, 
01667             rightGridChain, 
01668             index2+1,
01669             pStream, rbArray);
01670             
01671 
01672     }
01673 
01674 }
01675 
01676 void sampleLeftStrip(vertexArray* leftChain,
01677              Int topLeftIndex,
01678              Int botLeftIndex,
01679              gridBoundaryChain* leftGridChain,
01680              Int leftGridChainStartIndex,
01681              Int leftGridChainEndIndex,
01682              primStream* pStream
01683              )
01684 {
01685   assert(leftChain->getVertex(topLeftIndex)[1] > leftGridChain->get_v_value(leftGridChainStartIndex));
01686   assert(leftChain->getVertex(topLeftIndex+1)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex));
01687   assert(leftChain->getVertex(botLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainEndIndex));
01688   assert(leftChain->getVertex(botLeftIndex-1)[1] > leftGridChain->get_v_value(leftGridChainEndIndex));
01689 
01690   /*
01691    *(1)find the last grid line which doesn'; pass below
01692    * this first edge, sample this region: one trim edge and 
01693    * possily multiple grid lines.
01694    */
01695   Real *upperVert, *lowerVert; /*the end points of the first trim edge*/
01696   upperVert = leftChain->getVertex(topLeftIndex);
01697   lowerVert = leftChain->getVertex(topLeftIndex+1);
01698   
01699   Int index = leftGridChainStartIndex;
01700   while(leftGridChain->get_v_value(index) >= lowerVert[1]){
01701     index++;
01702     if(index > leftGridChainEndIndex) 
01703       break;
01704   }
01705   index--;
01706   
01707   sampleLeftSingleTrimEdgeRegion(upperVert, lowerVert,
01708                  leftGridChain,
01709                  leftGridChainStartIndex,
01710                  index,
01711                  pStream);
01712   sampleLeftStripRec(leftChain, topLeftIndex+1, botLeftIndex,
01713              leftGridChain, index, leftGridChainEndIndex,
01714              pStream);
01715 
01716 }
01717 
01718 void sampleLeftStripRec(vertexArray* leftChain,
01719              Int topLeftIndex,
01720              Int botLeftIndex,
01721              gridBoundaryChain* leftGridChain,
01722              Int leftGridChainStartIndex,
01723              Int leftGridChainEndIndex,
01724             primStream* pStream
01725              )
01726 {
01727   /*now top left trim vertex is below the top grid line.
01728    */
01729   /*stop condition: if topLeftIndex >= botLeftIndex, then stop.
01730    */
01731   if(topLeftIndex >= botLeftIndex) 
01732     return;
01733 
01734   /*find the last trim vertex which is above the second top grid line:
01735    * index1.
01736    *and sampleLeftOneGridStep(leftchain, topLeftIndex, index1, leftGridChain,
01737    * leftGridChainStartIndex).
01738    * index1 could be equal to topLeftIndex.
01739    */
01740   Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
01741   assert(leftGridChainStartIndex < leftGridChainEndIndex);
01742   Int index1 = topLeftIndex;
01743   while(leftChain->getVertex(index1)[1] > secondGridChainV)
01744     index1++;
01745   index1--;
01746   
01747   sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
01748 
01749 
01750   /* 
01751    * Let the next trim vertex be nextTrimVertIndex (which should be  
01752    *  below the second grid line).
01753    * Find the last grid line index2 which is above nextTrimVert.
01754    * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], 
01755    *                      leftGridChain, leftGridChainStartIndex+1, index2).
01756    */
01757   Real *uppervert, *lowervert;
01758   uppervert = leftChain->getVertex(index1);
01759   lowervert = leftChain->getVertex(index1+1);
01760   Int index2 = leftGridChainStartIndex+1;
01761 
01762   while(leftGridChain->get_v_value(index2) >= lowervert[1])
01763     {
01764       index2++;
01765       if(index2 > leftGridChainEndIndex)
01766     break;
01767     }
01768   index2--;
01769   sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2,  pStream);
01770 
01771    /* sampleLeftStripRec(leftChain, 
01772                         nextTrimVertIndex,
01773                         botLeftIndex,
01774                         leftGridChain,
01775             index2,
01776                         leftGridChainEndIndex
01777             )
01778    *
01779    */
01780   sampleLeftStripRec(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
01781   
01782 }
01783 
01784 
01785 /***************begin RecF***********************/
01786 /* the gridlines from leftGridChainStartIndex to 
01787  * leftGridChainEndIndex are assumed to form a
01788  * connected component.
01789  * the trim vertex of topLeftIndex is assumed to
01790  * be below the first gridline, and the tim vertex
01791  * of botLeftIndex is assumed to be above the last
01792  * grid line.
01793  * If botLeftIndex < topLeftIndex, then no connected componeent exists, and this funcion returns without
01794  * outputing any triangles.
01795  * Otherwise botLeftIndex >= topLeftIndex, there is at least one triangle to output.
01796  */
01797 void sampleLeftStripRecF(vertexArray* leftChain,
01798              Int topLeftIndex,
01799              Int botLeftIndex,
01800              gridBoundaryChain* leftGridChain,
01801              Int leftGridChainStartIndex,
01802              Int leftGridChainEndIndex,
01803             primStream* pStream
01804              )
01805 {
01806   /*now top left trim vertex is below the top grid line.
01807    */
01808   /*stop condition: if topLeftIndex > botLeftIndex, then stop.
01809    */
01810   if(topLeftIndex > botLeftIndex) 
01811     return;
01812 
01813   /*if there is only one grid Line, return.*/
01814 
01815   if(leftGridChainStartIndex>=leftGridChainEndIndex)
01816     return;
01817 
01818 
01819   assert(leftChain->getVertex(topLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex) &&
01820      leftChain->getVertex(botLeftIndex)[1] >= leftGridChain->get_v_value(leftGridChainEndIndex));
01821 
01822   /*firs find the first trim vertex which is below or equal to the second top grid line:
01823    * index1.
01824    */
01825   Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
01826 
01827 
01828   Int index1 = topLeftIndex;
01829 
01830   while(leftChain->getVertex(index1)[1] > secondGridChainV){
01831     index1++;
01832     if(index1>botLeftIndex)
01833       break;
01834   }
01835 
01836   /*now leftChain->getVertex(index-1)[1] > secondGridChainV and
01837    *    leftChain->getVertex(index)[1] <= secondGridChainV
01838    *If equality holds, then we should include the vertex index1, otherwise we include only index1-1, to
01839    *perform sampleOneGridStep.
01840    */
01841   if(index1>botLeftIndex) 
01842     index1--;
01843   else if(leftChain->getVertex(index1)[1] < secondGridChainV)
01844     index1--;
01845 
01846   /*now we have leftChain->getVertex(index1)[1] >= secondGridChainV, and 
01847    *  leftChain->getVertex(index1+1)[1] <= secondGridChainV
01848    */
01849 
01850 
01851   sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
01852 
01853 
01854   /*if leftChain->getVertex(index1)[1] == secondGridChainV, then we can recursively do the rest.
01855    */
01856   if(leftChain->getVertex(index1)[1] == secondGridChainV)
01857     {
01858 
01859       sampleLeftStripRecF(leftChain, index1, botLeftIndex,leftGridChain, leftGridChainStartIndex+1, leftGridChainEndIndex, pStream);
01860     }
01861   else if(index1 < botLeftIndex)
01862     {
01863 
01864       /* Otherwise, we have leftChain->getVertex(index1)[1] > secondGridChainV,
01865        * let the next trim vertex be nextTrimVertIndex (which should be  strictly
01866        *  below the second grid line).
01867        * Find the last grid line index2 which is above nextTrimVert.
01868        * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], 
01869        *                      leftGridChain, leftGridChainStartIndex+1, index2).
01870        */
01871       Real *uppervert, *lowervert;
01872       uppervert = leftChain->getVertex(index1);
01873       lowervert = leftChain->getVertex(index1+1); //okay since index1<botLeftIndex
01874       Int index2 = leftGridChainStartIndex+1;
01875 
01876       
01877       while(leftGridChain->get_v_value(index2) >= lowervert[1])
01878     {
01879       index2++;
01880       if(index2 > leftGridChainEndIndex)
01881         break;
01882     }
01883       index2--;
01884 
01885       
01886       sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2,  pStream);
01887       
01888       /*recursion*/
01889 
01890       sampleLeftStripRecF(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
01891     }
01892   
01893 }
01894 
01895 /***************End RecF***********************/
01896 
01897 /*sample the left area in between one trim edge and multiple grid lines.
01898  * all the grid lines should be in between the two end poins of the
01899  *trim edge.
01900  */
01901 void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
01902                     gridBoundaryChain* gridChain,
01903                     Int beginIndex,
01904                     Int endIndex,
01905                     primStream* pStream)
01906 {
01907   Int i,j,k;
01908 
01909   vertexArray vArray(endIndex-beginIndex+1);  
01910   vArray.appendVertex(gridChain->get_vertex(beginIndex));
01911 
01912   for(k=1, i=beginIndex+1; i<=endIndex; i++, k++)
01913     {
01914       vArray.appendVertex(gridChain->get_vertex(i));
01915 
01916       /*output the fan of the grid points of the (i)th and (i-1)th grid line.
01917        */
01918       if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1))
01919     {
01920       pStream->begin();   
01921       pStream->insert(gridChain->get_vertex(i-1));
01922       for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++)
01923         pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i));
01924       pStream->end(PRIMITIVE_STREAM_FAN);
01925     }
01926       else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1))
01927     {
01928       pStream->begin();
01929       pStream->insert(gridChain->get_vertex(i));
01930       for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--)
01931         pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1));
01932       pStream->end(PRIMITIVE_STREAM_FAN);
01933     }
01934       /*otherwisem, the two are equal, so there is no fan to outout*/     
01935     }
01936   
01937   monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex, 
01938              0, /*decreasing chain*/
01939              pStream);
01940 }
01941   
01942 /*return i, such that from begin to i-1 the chain is strictly u-monotone. 
01943  */              
01944 Int findIncreaseChainFromBegin(vertexArray* chain, Int begin ,Int end)
01945 {
01946   Int i=begin;
01947   Real prevU = chain->getVertex(i)[0];
01948   Real thisU;
01949   for(i=begin+1; i<=end; i++){
01950     thisU = chain->getVertex(i)[0];
01951 
01952     if(prevU < thisU){
01953       prevU = thisU;
01954     }
01955     else
01956       break;
01957   }
01958   return i;
01959 }
01960   
01961 /*check whether there is a vertex whose v value is strictly 
01962  *inbetween vup vbelow
01963  *if no middle exists return -1, else return the idnex.
01964  */
01965 Int checkMiddle(vertexArray* chain, Int begin, Int end, 
01966         Real vup, Real vbelow)
01967 {
01968   Int i;
01969   for(i=begin; i<=end; i++)
01970     {
01971       if(chain->getVertex(i)[1] < vup && chain->getVertex(i)[1]>vbelow)
01972     return i;
01973     }
01974   return -1;
01975 }
01976   
01977 /*the degenerat case of sampleLeftOneGridStep*/
01978 void sampleLeftOneGridStepNoMiddle(vertexArray* leftChain,
01979                    Int beginLeftIndex,
01980                    Int endLeftIndex,
01981                    gridBoundaryChain* leftGridChain,
01982                    Int leftGridChainStartIndex,
01983                    primStream* pStream)
01984 {
01985   /*since there is no middle, there is at most one point which is on the 
01986    *second grid line, there could be multiple points on the first (top)
01987    *grid line.
01988    */
01989 
01990   leftGridChain->leftEndFan(leftGridChainStartIndex+1, pStream);
01991 
01992   monoTriangulation2(leftGridChain->get_vertex(leftGridChainStartIndex),
01993              leftGridChain->get_vertex(leftGridChainStartIndex+1),
01994              leftChain,
01995              beginLeftIndex,
01996              endLeftIndex,
01997              1, //is increase chain.
01998              pStream);
01999 }
02000 
02001 
02002 
02003 /*sampling the left area in between two grid lines.
02004  */
02005 void sampleLeftOneGridStep(vertexArray* leftChain,
02006           Int beginLeftIndex,
02007           Int endLeftIndex,
02008           gridBoundaryChain* leftGridChain,
02009           Int leftGridChainStartIndex,
02010           primStream* pStream
02011           )
02012 {
02013   if(checkMiddle(leftChain, beginLeftIndex, endLeftIndex, 
02014          leftGridChain->get_v_value(leftGridChainStartIndex),
02015          leftGridChain->get_v_value(leftGridChainStartIndex+1))<0)
02016     
02017     {
02018       
02019       sampleLeftOneGridStepNoMiddle(leftChain, beginLeftIndex, endLeftIndex, leftGridChain, leftGridChainStartIndex, pStream);
02020       return;
02021     }
02022   
02023   //copy into a polygon
02024   {
02025     directedLine* poly = NULL;
02026     sampledLine* sline;
02027     directedLine* dline;
02028     gridWrap* grid = leftGridChain->getGrid();
02029     Real vert1[2];
02030     Real vert2[2];
02031     Int i;
02032     
02033     Int innerInd = leftGridChain->getInnerIndex(leftGridChainStartIndex+1);
02034     Int upperInd = leftGridChain->getUlineIndex(leftGridChainStartIndex);
02035     Int lowerInd = leftGridChain->getUlineIndex(leftGridChainStartIndex+1);
02036     Real upperV = leftGridChain->get_v_value(leftGridChainStartIndex);
02037     Real lowerV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
02038 
02039     //the upper gridline
02040     vert1[1] = vert2[1] = upperV;
02041     for(i=innerInd; i>upperInd; i--)
02042       {
02043     vert1[0]=grid->get_u_value(i);
02044     vert2[0]=grid->get_u_value(i-1);
02045     sline = new sampledLine(vert1, vert2);
02046     dline = new directedLine(INCREASING, sline);
02047     if(poly == NULL)
02048       poly = dline;
02049     else
02050       poly->insert(dline);
02051       }
02052 
02053     //the edge connecting upper grid with left chain
02054     vert1[0] = grid->get_u_value(upperInd);
02055     vert1[1] = upperV;
02056     sline = new sampledLine(vert1, leftChain->getVertex(beginLeftIndex));
02057     dline = new directedLine(INCREASING, sline);
02058     if(poly == NULL)
02059       poly = dline;
02060     else
02061       poly->insert(dline);    
02062  
02063     //the left chain
02064     for(i=beginLeftIndex; i<endLeftIndex; i++)
02065       {
02066     sline = new sampledLine(leftChain->getVertex(i), leftChain->getVertex(i+1));
02067     dline = new directedLine(INCREASING, sline);
02068     poly->insert(dline);
02069       }
02070 
02071     //the edge connecting left chain with lower gridline
02072     vert2[0] = grid->get_u_value(lowerInd);
02073     vert2[1] = lowerV;
02074     sline = new sampledLine(leftChain->getVertex(endLeftIndex), vert2);
02075     dline = new directedLine(INCREASING, sline);
02076     poly->insert(dline);
02077 
02078     //the lower grid line
02079     vert1[1] = vert2[1] = lowerV;
02080     for(i=lowerInd; i<innerInd; i++)
02081       {
02082     vert1[0] = grid->get_u_value(i);
02083     vert2[0] = grid->get_u_value(i+1);
02084     sline = new sampledLine(vert1, vert2);
02085     dline = new directedLine(INCREASING, sline);
02086     poly->insert(dline);       
02087       }
02088 
02089     //the vertical grid line segement
02090     vert1[0]=vert2[0] = grid->get_u_value(innerInd);
02091     vert2[1]=upperV;
02092     vert1[1]=lowerV;
02093     sline=new sampledLine(vert1, vert2);
02094     dline=new directedLine(INCREASING, sline);
02095     poly->insert(dline);
02096     monoTriangulationOpt(poly, pStream);
02097     //cleanup
02098     poly->deleteSinglePolygonWithSline();
02099     return;
02100   }
02101  
02102 
02103 
02104  
02105 
02106   Int i;
02107   if(1/*leftGridChain->getUlineIndex(leftGridChainStartIndex) >= 
02108      leftGridChain->getUlineIndex(leftGridChainStartIndex+1)*/
02109      ) /*the second grid line is beyond the first one to the left*/
02110     {
02111       /*find the maximal U-monotone chain 
02112        * of endLeftIndex, endLeftIndex-1, ..., 
02113        */
02114       i=endLeftIndex;
02115       Real prevU = leftChain->getVertex(i)[0];
02116       for(i=endLeftIndex-1; i>=beginLeftIndex; i--){
02117     Real thisU = leftChain->getVertex(i)[0];
02118     if( prevU < thisU){
02119       prevU = thisU;
02120     }
02121     else 
02122       break;
02123       }
02124       /*from endLeftIndex to i+1 is strictly U- monotone */
02125       /*if i+1==endLeftIndex and the vertex and leftchain is on the second gridline, then
02126        *we should use 2 vertices on the leftchain. If we only use one (endLeftIndex), then we
02127        *we would output degenerate triangles
02128        */
02129       if(i+1 == endLeftIndex && leftChain->getVertex(endLeftIndex)[1] == leftGridChain->get_v_value(1+leftGridChainStartIndex))
02130     i--;
02131 
02132       Int j = beginLeftIndex/*endLeftIndex*/+1;
02133 
02134 
02135       if(leftGridChain->getInnerIndex(leftGridChainStartIndex+1) > leftGridChain->getUlineIndex(leftGridChainStartIndex))
02136     {
02137       j = findIncreaseChainFromBegin(leftChain, beginLeftIndex, i+1/*endLeftIndex*/);
02138 
02139       Int temp = beginLeftIndex;
02140       /*now from begin to j-1 is strictly u-monotone*/
02141       /*if j-1 is on the first grid line, then we want to skip to the vertex which is strictly
02142        *below the grid line. This vertexmust exist since there is a 'corner turn' inbetween the two grid lines
02143        */
02144       if(j-1 == beginLeftIndex)
02145         {
02146           while(leftChain->getVertex(j-1)[1] == leftGridChain->get_v_value(leftGridChainStartIndex))
02147         j++;            
02148 
02149           Real vert[2];
02150           vert[0] = leftGridChain->get_u_value(leftGridChainStartIndex);
02151           vert[1] = leftGridChain->get_v_value(leftGridChainStartIndex);
02152 
02153           monoTriangulation2(
02154                  vert/*leftChain->getVertex(beginLeftIndex)*/,
02155                  leftChain->getVertex(j-1),
02156                  leftChain,
02157                  beginLeftIndex,
02158                  j-2,
02159                  1,
02160                  pStream //increase chain
02161                  );
02162                  
02163           temp = j-1;
02164         }
02165                  
02166       stripOfFanLeft(leftChain, j-1, temp/*beginLeftIndex*/, leftGridChain->getGrid(),
02167              leftGridChain->getVlineIndex(leftGridChainStartIndex),
02168              leftGridChain->getUlineIndex(leftGridChainStartIndex),
02169              leftGridChain->getInnerIndex(leftGridChainStartIndex+1),
02170              pStream,
02171              1 /*the grid line is above the trim line*/
02172              );
02173     }
02174       
02175       stripOfFanLeft(leftChain, endLeftIndex, i+1, leftGridChain->getGrid(), 
02176              leftGridChain->getVlineIndex(leftGridChainStartIndex+1),
02177              leftGridChain->getUlineIndex(leftGridChainStartIndex+1),
02178              leftGridChain->getInnerIndex(leftGridChainStartIndex+1),
02179              pStream,
02180              0 /*the grid line is below the trim lines*/
02181              );
02182       
02183       /*monotone triangulate the remaining left chain togther with the
02184        *two vertices on the two grid v-lines.
02185        */
02186       Real vert[2][2];
02187       vert[0][0]=vert[1][0] = leftGridChain->getInner_u_value(leftGridChainStartIndex+1);
02188       vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex);      
02189       vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1);
02190 
02191 //      vertexArray right(vert, 2);
02192 
02193       monoTriangulation2(
02194              &vert[0][0], /*top vertex */
02195              &vert[1][0], /*bottom vertex*/
02196              leftChain, 
02197              /*beginLeftIndex*/j-1,
02198              i+1,
02199              1, /*an increasing chain*/
02200              pStream);
02201     }
02202   else /*the second one is shorter than the first one to the left*/
02203     {
02204       /*find the maximal U-monotone chain of beginLeftIndex, beginLeftIndex+1,...,
02205        */
02206       i=beginLeftIndex;
02207       Real prevU = leftChain->getVertex(i)[0];
02208       for(i=beginLeftIndex+1; i<=endLeftIndex; i++){
02209     Real thisU = leftChain->getVertex(i)[0];
02210 
02211     if(prevU < thisU){
02212       prevU = thisU;
02213     }
02214     else
02215       break;
02216       }
02217       /*from beginLeftIndex to i-1 is strictly U-monotone*/
02218 
02219 
02220       stripOfFanLeft(leftChain, i-1, beginLeftIndex, leftGridChain->getGrid(),
02221              leftGridChain->getVlineIndex(leftGridChainStartIndex),
02222              leftGridChain->getUlineIndex(leftGridChainStartIndex),
02223              leftGridChain->getUlineIndex(leftGridChainStartIndex+1),
02224              pStream,
02225                  1 /*the grid line is above the trim lines*/
02226              );
02227       /*monotone triangulate the remaining left chain together with the 
02228        *two vertices on the two grid v-lines.
02229        */
02230       Real vert[2][2];
02231       vert[0][0]=vert[1][0] = leftGridChain->get_u_value(leftGridChainStartIndex+1);
02232       vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex);      
02233       vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1);
02234 
02235       vertexArray right(vert, 2);
02236 
02237       monoTriangulation2(
02238              &vert[0][0], //top vertex 
02239              &vert[1][0], //bottom vertex
02240              leftChain, 
02241              i-1,
02242              endLeftIndex,
02243              1, /*an increase chain*/
02244              pStream);
02245 
02246     }
02247 }
02248   
02249 /*n_upper>=1
02250  *n_lower>=1
02251  */
02252 void triangulateXYMono(Int n_upper, Real upperVerts[][2],
02253                Int n_lower, Real lowerVerts[][2],
02254                primStream* pStream)
02255 {
02256   Int i,j,k,l;
02257   Real* leftMostV;
02258 
02259   assert(n_upper>=1 && n_lower>=1);
02260   if(upperVerts[0][0] <= lowerVerts[0][0])
02261     {
02262       i=1;
02263       j=0;
02264       leftMostV = upperVerts[0];
02265     }
02266   else
02267     {
02268       i=0;
02269       j=1;
02270       leftMostV = lowerVerts[0];
02271     }
02272   
02273   while(1)
02274     {
02275       if(i >= n_upper) /*case1: no more in upper*/
02276     {
02277 
02278       if(j<n_lower-1) /*at least two vertices in lower*/
02279         {
02280           pStream->begin();
02281           pStream->insert(leftMostV);
02282           while(j<n_lower){
02283         pStream->insert(lowerVerts[j]);
02284         j++;
02285           }
02286           pStream->end(PRIMITIVE_STREAM_FAN);
02287         }
02288 
02289       break;    
02290     }
02291       else if(j>= n_lower) /*case2: no more in lower*/
02292     {
02293 
02294       if(i<n_upper-1) /*at least two vertices in upper*/
02295         {
02296           pStream->begin();
02297           pStream->insert(leftMostV);
02298 
02299           for(k=n_upper-1; k>=i; k--)
02300         pStream->insert(upperVerts[k]);
02301 
02302           pStream->end(PRIMITIVE_STREAM_FAN);
02303         }
02304 
02305       break;
02306     }
02307       else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
02308     {
02309 
02310       if(upperVerts[i][0] <= lowerVerts[j][0])
02311         {
02312           pStream->begin();
02313           pStream->insert(lowerVerts[j]); /*the origin of this fan*/
02314 
02315           /*find the last k>=i such that 
02316            *upperverts[k][0] <= lowerverts[j][0]
02317            */
02318           k=i;
02319           while(k<n_upper)
02320         {
02321           if(upperVerts[k][0] > lowerVerts[j][0])
02322             break;
02323           k++;
02324         }
02325           k--;
02326           for(l=k; l>=i; l--)/*the reverse is for two-face lighting*/
02327         {
02328           pStream->insert(upperVerts[l]);
02329         }
02330           pStream->insert(leftMostV);
02331 
02332           pStream->end(PRIMITIVE_STREAM_FAN);
02333           //update i for next loop
02334           i = k+1;
02335           leftMostV = upperVerts[k];
02336 
02337         }
02338       else /*upperVerts[i][0] > lowerVerts[j][0]*/
02339         {
02340           pStream->begin();
02341           pStream->insert(upperVerts[i]);/*the origion of this fan*/
02342           pStream->insert(leftMostV);
02343           /*find the last k>=j such that
02344            *lowerverts[k][0] < upperverts[i][0]*/
02345           k=j;
02346           while(k< n_lower)
02347         {
02348           if(lowerVerts[k][0] >= upperVerts[i][0])
02349             break;
02350           pStream->insert(lowerVerts[k]);
02351           k++;
02352         }
02353           pStream->end(PRIMITIVE_STREAM_FAN);
02354           j=k;
02355           leftMostV = lowerVerts[j-1];
02356         }     
02357     }
02358     }
02359 }
02360                
02361 
02362 void stripOfFanLeft(vertexArray* leftChain, 
02363             Int largeIndex,
02364             Int smallIndex,
02365             gridWrap* grid,
02366             Int vlineIndex,
02367             Int ulineSmallIndex,
02368             Int ulineLargeIndex,
02369             primStream* pStream,
02370             Int gridLineUp /*1 if the grid line is above the trim lines*/
02371              )
02372 {
02373   assert(largeIndex >= smallIndex);
02374 
02375   Real grid_v_value;
02376   grid_v_value = grid->get_v_value(vlineIndex);
02377 
02378   Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1));
02379   assert(trimVerts);
02380 
02381 
02382   Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1));
02383   assert(gridVerts);
02384 
02385   Int k,i;
02386   if(gridLineUp) /*trim line is below grid line, so trim vertices are going right when index increases*/
02387     for(k=0, i=smallIndex; i<=largeIndex; i++, k++)
02388       {
02389       trimVerts[k][0] = leftChain->getVertex(i)[0];
02390       trimVerts[k][1] = leftChain->getVertex(i)[1];
02391     }
02392   else
02393     for(k=0, i=largeIndex; i>=smallIndex; i--, k++)
02394       {
02395     trimVerts[k][0] = leftChain->getVertex(i)[0];
02396     trimVerts[k][1] = leftChain->getVertex(i)[1];
02397       }
02398 
02399   for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++)
02400     {
02401       gridVerts[k][0] = grid->get_u_value(i);
02402       gridVerts[k][1] = grid_v_value;
02403     }
02404 
02405   if(gridLineUp)
02406     triangulateXYMono(
02407               ulineLargeIndex-ulineSmallIndex+1, gridVerts,
02408               largeIndex-smallIndex+1, trimVerts,
02409               pStream);
02410   else
02411     triangulateXYMono(largeIndex-smallIndex+1, trimVerts,
02412               ulineLargeIndex-ulineSmallIndex+1, gridVerts,
02413               pStream);
02414   free(trimVerts);
02415   free(gridVerts);
02416 }
02417 
02418   
02419 
02420 
02421 

Generated on Sat May 26 2012 04:22:20 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.