FreeWRL/FreeX3D  3.0.0
sampleCompBot.cc
1 /*
2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9 **
10 ** http://oss.sgi.com/projects/FreeB
11 **
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17 **
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
23 **
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
33 **
34 */
35 /*
36 */
37 
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include "zlassert.h"
41 #include "sampleCompBot.h"
42 #include "sampleCompRight.h"
43 
44 #define max(a,b) ((a>b)? a:b)
45 
46 //return: index_mono, index_pass
47 //from [pass, mono] is strictly U-monotone
48 //from [corner, pass] is <u
49 // vertex[pass][0] >= u
50 //if everybost is <u, then pass = end+1.
51 //otherwise both mono and pass are meanng full and we have corner<=pass<=mono<=end
52 void findBotLeftSegment(vertexArray* leftChain,
53  Int leftEnd,
54  Int leftCorner,
55  Real u,
56  Int& ret_index_mono,
57  Int& ret_index_pass)
58 {
59  Int i;
60 
61  assert(leftCorner <= leftEnd);
62  for(i=leftCorner; i<= leftEnd; i++)
63  if(leftChain->getVertex(i)[0] >= u)
64  break;
65  ret_index_pass = i;
66  if(ret_index_pass <= leftEnd)
67  {
68  for(i=ret_index_pass; i< leftEnd; i++)
69  {
70  if(leftChain->getVertex(i+1)[0] <= leftChain->getVertex(i)[0])
71  break;
72  }
73  ret_index_mono = i;
74  }
75 
76 }
77 
78 void findBotRightSegment(vertexArray* rightChain,
79  Int rightEnd,
80  Int rightCorner,
81  Real u,
82  Int& ret_index_mono,
83  Int& ret_index_pass)
84 {
85  Int i;
86  assert(rightCorner <= rightEnd);
87  for(i=rightCorner; i<= rightEnd; i++)
88  if(rightChain->getVertex(i)[0] <= u)
89  break;
90 
91 
92 
93  ret_index_pass = i;
94 
95  if(ret_index_pass <= rightEnd)
96  {
97  for(i=ret_index_pass; i< rightEnd; i++)
98  {
99  if(rightChain->getVertex(i+1)[0] >= rightChain->getVertex(i)[0])
100  break;
101  }
102  ret_index_mono = i;
103  }
104 }
105 
106 
107 void sampleBotRightWithGridLinePost(Real* botVertex,
108  vertexArray* rightChain,
109  Int rightEnd,
110  Int segIndexMono,
111  Int segIndexPass,
112  Int rightCorner,
113  gridWrap* grid,
114  Int gridV,
115  Int leftU,
116  Int rightU,
117  primStream* pStream)
118 {
119  //the possible section which is to the right of rightU
120  if(segIndexPass > rightCorner) //from corner to pass-1 is > u.
121  {
122  Real *tempBot;
123  if(segIndexPass <= rightEnd) //there is a point to the left of u
124  tempBot = rightChain->getVertex(segIndexPass);
125  else //nothing is to the left of u.
126  tempBot = botVertex;
127  Real tempTop[2];
128  tempTop[0] = grid->get_u_value(rightU);
129  tempTop[1] = grid->get_v_value(gridV);
130 
131  monoTriangulation2(tempTop, tempBot,
132  rightChain,
133  rightCorner,
134  segIndexPass-1,
135  0, // a decrease chain
136  pStream);
137  }
138 
139  //the possible section which is strictly Umonotone
140  if(segIndexPass <= rightEnd) //segIndex pass and mono exist
141  {
142  //if there are grid points which are to the left of botVertex
143  //then we should use botVertex to form a fan with these points to
144  //optimize the triangulation
145  int do_optimize = 1;
146  if(botVertex[0] <= grid->get_u_value(leftU))
147  do_optimize = 0;
148  else
149  {
150  //we also have to make sure that botVertex is the left most vertex on the chain
151  int i;
152  for(i=segIndexMono; i<=rightEnd; i++)
153  if(rightChain->getVertex(i)[0] <= botVertex[0])
154  {
155  do_optimize = 0;
156  break;
157  }
158  }
159 
160  if(do_optimize)
161  {
162  //find midU so that grid->get_u_value(midU) <= botVertex[0]
163  //and grid->get_u_value(midU) > botVertex[0]
164  int midU = leftU;
165  while(grid->get_u_value(midU) <= botVertex[0])
166  {
167  midU++;
168  if(midU > rightU)
169  break;
170  }
171  midU--;
172 
173  grid->outputFanWithPoint(gridV, leftU, midU, botVertex, pStream);
174  stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, midU, rightU, pStream, 1);
175  Real tempTop[2];
176  tempTop[0] = grid->get_u_value(midU);
177  tempTop[1] = grid->get_v_value(gridV);
178  monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream);
179  }
180  else //not optimize
181  {
182  stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1);
183  Real tempTop[2];
184  tempTop[0] = grid->get_u_value(leftU);
185  tempTop[1] = grid->get_v_value(gridV);
186  monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream);
187  }
188  }
189  else //the botVertex forms a fan witht eh grid points
190  grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
191 }
192 
193 void sampleBotRightWithGridLine(Real* botVertex,
194  vertexArray* rightChain,
195  Int rightEnd,
196  Int rightCorner,
197  gridWrap* grid,
198  Int gridV,
199  Int leftU,
200  Int rightU,
201  primStream* pStream)
202 {
203  //if right chaain is empty, then there is only one bot vertex with
204  //one grid line
205  if(rightEnd<rightCorner){
206  grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
207  return;
208  }
209 
210  Int segIndexMono, segIndexPass;
211  findBotRightSegment(rightChain,
212  rightEnd,
213  rightCorner,
214  grid->get_u_value(rightU),
215  segIndexMono,
216  segIndexPass);
217 
218  sampleBotRightWithGridLinePost(botVertex,
219  rightChain,
220  rightEnd,
221  segIndexMono,
222  segIndexPass,
223  rightCorner,
224  grid,
225  gridV,
226  leftU,
227  rightU,
228  pStream);
229 }
230 
231 
232 void sampleBotLeftWithGridLinePost(Real* botVertex,
233  vertexArray* leftChain,
234  Int leftEnd,
235  Int segIndexMono,
236  Int segIndexPass,
237  Int leftCorner,
238  gridWrap* grid,
239  Int gridV,
240  Int leftU,
241  Int rightU,
242  primStream* pStream)
243 {
244 
245  //the possible section which is to the left of leftU
246  if(segIndexPass > leftCorner) //at least leftCorner is to the left of leftU
247  {
248  Real *tempBot;
249  if(segIndexPass <= leftEnd) //from corner to pass-1 is <u
250  tempBot = leftChain->getVertex(segIndexPass);
251  else //nothing is to the rigth of u
252  tempBot = botVertex;
253  Real tempTop[2];
254  tempTop[0] = grid->get_u_value(leftU);
255  tempTop[1] = grid->get_v_value(gridV);
256  monoTriangulation2(tempTop, tempBot, leftChain, leftCorner, segIndexPass-1,
257  1, //a increase chain,
258  pStream);
259  }
260  //the possible section which is strictly Umonotone
261  if(segIndexPass <= leftEnd) //segIndexpass and mono exist
262  {
263  stripOfFanLeft(leftChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1);
264  Real tempTop[2];
265  tempTop[0] = grid->get_u_value(rightU);
266  tempTop[1] = grid->get_v_value(gridV);
267 
268  monoTriangulation2(tempTop, botVertex, leftChain, segIndexMono, leftEnd,
269  1, //increase chain
270  pStream);
271  }
272  else //the botVertex forms a fan with the grid points
273  {
274  grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
275  }
276 
277 }
278 
279 void sampleBotLeftWithGridLine(Real* botVertex,
280  vertexArray* leftChain,
281  Int leftEnd,
282  Int leftCorner,
283  gridWrap* grid,
284  Int gridV,
285  Int leftU,
286  Int rightU,
287  primStream* pStream)
288 {
289 
290  //if leftChain is empty, then there is only one botVertex with one grid line
291  if(leftEnd< leftCorner){
292  grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
293  return;
294  }
295 
296  Int segIndexPass, segIndexMono;
297  findBotLeftSegment(leftChain, leftEnd, leftCorner, grid->get_u_value(leftU), segIndexMono, segIndexPass);
298 
299  sampleBotLeftWithGridLinePost(botVertex,
300  leftChain,
301  leftEnd,
302  segIndexMono,
303  segIndexPass,
304  leftCorner,
305  grid,
306  gridV,
307  leftU, rightU, pStream);
308 }
309 
310 //return 1 if separator exists, 0 otherwise
311 Int findBotSeparator(vertexArray* leftChain,
312  Int leftEnd,
313  Int leftCorner,
314  vertexArray* rightChain,
315  Int rightEnd,
316  Int rightCorner,
317  Int& ret_sep_left,
318  Int& ret_sep_right)
319 {
320  Int oldLeftI, oldRightI, newLeftI, newRightI;
321  Int i,j,k;
322  Real leftMax /*= leftChain->getVertex(leftCorner)[0]*/;
323  Real rightMin /*= rightChain->getVertex(rightCorner)[0]*/;
324  if(leftChain->getVertex(leftCorner)[1] < rightChain->getVertex(rightCorner)[1])//leftlower
325  {
326  oldLeftI = leftCorner-1;
327  oldRightI = rightCorner;
328  leftMax = leftChain->getVertex(leftCorner)[0] - Real(1.0) ; //initilize to be left of leftCorner
329  rightMin = rightChain->getVertex(rightCorner)[0];
330  }
331  else //rightlower
332  {
333  oldLeftI = leftCorner;
334  oldRightI = rightCorner-1;
335  leftMax = leftChain->getVertex(leftCorner)[0];
336  rightMin = rightChain->getVertex(rightCorner)[0] + Real(1.0);
337  }
338 
339  //i: the current working leftChain Index
340  //j: the curent working right chian index
341  //if(left(i) is lower than right(j), then the two chains above right(j) are separated.
342  //else the two chains below left(i) are separated.
343  i = leftCorner;
344  j = rightCorner;
345  while(1)
346  {
347  newLeftI = oldLeftI;
348  newRightI = oldRightI;
349  if(i> leftEnd) //left chain is doen , go through remaining right chain
350  {
351  for(k=j+1; k<= rightEnd; k++)
352  {
353  if(rightChain->getVertex(k)[0] > leftMax) //no conflict
354  {
355  //update oldRightI if necessary
356  if(rightChain->getVertex(k)[0] < rightMin)
357  {
358  rightMin = rightChain->getVertex(k)[0];
359  oldRightI = k;
360  }
361  }
362  else //there is a conflict
363  break; //the for-loop, above right(k+1) is separated: oldLeftI, oldRightI
364  }
365  break; //the while loop
366  }
367  else if(j > rightEnd) //right Chain is doen
368  {
369  for(k=i+1; k<= leftEnd; k++)
370  {
371  if(leftChain->getVertex(k)[0] < rightMin) //no conflict
372  {
373  //update oldLeftI if necessary
374  if(leftChain->getVertex(k)[0] > leftMax)
375  {
376  leftMax = leftChain->getVertex(k)[0];
377  oldLeftI = k;
378  }
379  }
380  else //there is a conflict
381  break; //the for-loop, above left(k+1) is separated: oldLeftI, oldRightI
382  }
383  break; //the while loop
384  }
385  else if(leftChain->getVertex(i)[1] < rightChain->getVertex(j)[1]) //left lower
386  {
387 
388  if(leftChain->getVertex(i)[0] > leftMax) //update leftMax amd newLeftI
389  {
390  leftMax = leftChain->getVertex(i)[0];
391  newLeftI = i;
392  }
393  for(k=j+1; k<= rightEnd; k++) //update rightMin and newRightI;
394  {
395  if(rightChain->getVertex(k)[1] < leftChain->getVertex(i)[1]) //right gets lower
396  break;
397  if(rightChain->getVertex(k)[0] < rightMin)
398  {
399  rightMin = rightChain->getVertex(k)[0];
400  newRightI = k;
401  }
402  }
403  j = k; //next working j, since j will he lower than i in next loop
404  if(leftMax >= rightMin) //there is a conflict
405  break;
406  else //still no conflict
407  {
408  oldLeftI = newLeftI;
409  oldRightI = newRightI;
410 
411  }
412  }
413  else //right lower
414  {
415  if(rightChain->getVertex(j)[0] < rightMin)
416  {
417  rightMin = rightChain->getVertex(j)[0];
418  newRightI = j;
419  }
420  for(k=i+1; k<= leftEnd; k++)
421  {
422  if(leftChain->getVertex(k)[1] < rightChain->getVertex(j)[1])
423  break;
424  if(leftChain->getVertex(k)[0] > leftMax)
425  {
426  leftMax = leftChain->getVertex(k)[0];
427  newLeftI = k;
428  }
429  }
430  i=k; //nexct working i, since i will be lower than j next loop
431  if(leftMax >= rightMin) //there is conflict
432  break;
433  else //still no conflict
434  {
435  oldLeftI = newLeftI;
436  oldRightI = newRightI;
437  }
438  }
439  }//end of while loop
440  //now oldLeftI and oldRight I are the desired separator index notice that they are not
441  //necessarily valid
442  if(oldLeftI < leftCorner || oldRightI < rightCorner)
443  return 0; //no separator
444  else
445  {
446  ret_sep_left = oldLeftI;
447  ret_sep_right = oldRightI;
448  return 1;
449  }
450 }
451 
452 void sampleCompBot(Real* botVertex,
453  vertexArray* leftChain,
454  Int leftEnd,
455  vertexArray* rightChain,
456  Int rightEnd,
457  gridBoundaryChain* leftGridChain,
458  gridBoundaryChain* rightGridChain,
459  Int gridIndex,
460  Int down_leftCornerWhere,
461  Int down_leftCornerIndex,
462  Int down_rightCornerWhere,
463  Int down_rightCornerIndex,
464  primStream* pStream)
465 {
466 
467  if(down_leftCornerWhere == 1 && down_rightCornerWhere == 1) //the bot is botVertex with possible grid points
468  {
469 
470  leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex),
471  leftGridChain->getUlineIndex(gridIndex),
472  rightGridChain->getUlineIndex(gridIndex),
473  botVertex,
474  pStream);
475  return;
476  }
477  else if(down_leftCornerWhere != 0)
478  {
479 
480  Real* tempBot;
481  Int tempRightEnd;
482  if(down_leftCornerWhere == 1){
483  tempRightEnd = rightEnd;
484  tempBot = botVertex;
485  }
486  else
487  {
488  tempRightEnd = down_leftCornerIndex-1;
489  tempBot = rightChain->getVertex(down_leftCornerIndex);
490  }
491 
492  sampleBotRightWithGridLine(tempBot,
493  rightChain,
494  tempRightEnd,
495  down_rightCornerIndex,
496  rightGridChain->getGrid(),
497  leftGridChain->getVlineIndex(gridIndex),
498  leftGridChain->getUlineIndex(gridIndex),
499  rightGridChain->getUlineIndex(gridIndex),
500  pStream);
501  }
502  else if(down_rightCornerWhere != 2)
503  {
504 
505  Real* tempBot;
506  Int tempLeftEnd;
507  if(down_rightCornerWhere == 1){
508  tempLeftEnd = leftEnd;
509  tempBot = botVertex;
510  }
511  else //right corner is on left chain
512  {
513  tempLeftEnd = down_rightCornerIndex-1;
514  tempBot = leftChain->getVertex(down_rightCornerIndex);
515  }
516 
517 
518  sampleBotLeftWithGridLine(tempBot, leftChain, tempLeftEnd, down_leftCornerIndex,
519  leftGridChain->getGrid(),
520  leftGridChain->getVlineIndex(gridIndex),
521  leftGridChain->getUlineIndex(gridIndex),
522  rightGridChain->getUlineIndex(gridIndex),
523  pStream);
524 
525  }
526  else //down_leftCornereWhere == 0, down_rightCornerwhere == 2
527  {
528  sampleCompBotSimple(botVertex,
529  leftChain,
530  leftEnd,
531  rightChain,
532  rightEnd,
533  leftGridChain,
534  rightGridChain,
535  gridIndex,
536  down_leftCornerWhere,
537  down_leftCornerIndex,
538  down_rightCornerWhere,
539  down_rightCornerIndex,
540  pStream);
541 
542  return;
543 
544 #ifdef NOT_REACHABLE
545  //the following code is trying to do some optimization, but not quite working. so it is not reachable, but leave it here for reference
546  Int sep_left, sep_right;
547  if(findBotSeparator(leftChain, leftEnd, down_leftCornerIndex,
548  rightChain, rightEnd, down_rightCornerIndex,
549  sep_left, sep_right)
550  )//separator exiosts
551  {
552 
553  if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex) &&
554  rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))
555  {
556  Int gridSep;
557  Int segLeftMono, segLeftPass, segRightMono, segRightPass;
558  findBotLeftSegment(leftChain,
559  sep_left,
560  down_leftCornerIndex,
561  leftGridChain->get_u_value(gridIndex),
562  segLeftMono,
563  segLeftPass);
564  findBotRightSegment(rightChain,
565  sep_right,
566  down_rightCornerIndex,
567  rightGridChain->get_u_value(gridIndex),
568  segRightMono,
569  segRightPass);
570  if(leftChain->getVertex(segLeftMono)[1] <= rightChain->getVertex(segRightMono)[1])
571  {
572  gridSep = rightGridChain->getUlineIndex(gridIndex);
573  while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftMono)[0])
574  gridSep--;
575  }
576  else
577  {
578  gridSep = leftGridChain->getUlineIndex(gridIndex);
579  while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightMono)[0])
580  gridSep++;
581  }
582 
583  sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono),
584  leftChain,
585  segLeftMono-1,
586  segLeftMono-1,
587  segLeftPass,
588  down_leftCornerIndex,
589  leftGridChain->getGrid(),
590  leftGridChain->getVlineIndex(gridIndex),
591  leftGridChain->getUlineIndex(gridIndex),
592  gridSep,
593  pStream);
594  sampleBotRightWithGridLinePost(rightChain->getVertex(segRightMono),
595  rightChain,
596  segRightMono-1,
597  segRightMono-1,
598  segRightPass,
599  down_rightCornerIndex,
600  rightGridChain->getGrid(),
601  rightGridChain->getVlineIndex(gridIndex),
602  gridSep,
603  rightGridChain->getUlineIndex(gridIndex),
604  pStream);
605  Real tempTop[2];
606  tempTop[0] = leftGridChain->getGrid()->get_u_value(gridSep);
607  tempTop[1] = leftGridChain->get_v_value(gridIndex);
608  monoTriangulationRecGen(tempTop, botVertex,
609  leftChain, segLeftMono, leftEnd,
610  rightChain, segRightMono, rightEnd,
611  pStream);
612  }//end if both sides have vertices inside the gridboundary points
613  else if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex)) //left n right out
614 
615  {
616  Int segLeftMono, segLeftPass;
617  findBotLeftSegment(leftChain,
618  sep_left,
619  down_leftCornerIndex,
620  leftGridChain->get_u_value(gridIndex),
621  segLeftMono,
622  segLeftPass);
623  assert(segLeftPass <= sep_left); //make sure there is a point to the right of u.
624  monoTriangulation2(leftGridChain->get_vertex(gridIndex),
625  leftChain->getVertex(segLeftPass),
626  leftChain,
627  down_leftCornerIndex,
628  segLeftPass-1,
629  1, //a increase chain
630  pStream);
631  stripOfFanLeft(leftChain, segLeftMono, segLeftPass,
632  leftGridChain->getGrid(),
633  leftGridChain->getVlineIndex(gridIndex),
634  leftGridChain->getUlineIndex(gridIndex),
635  rightGridChain->getUlineIndex(gridIndex),
636  pStream,1 );
637 /*
638  sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono),
639  leftChain,
640  segLeftMono-1,
641  segLeftMono-1,
642  segLeftPass,
643  down_leftCornerIndex,
644  leftGridChain->getGrid(),
645  leftGridChain->getVlineIndex(gridIndex),
646  leftGridChain->getUlineIndex(gridIndex),
647  rightGridChain->getUlineIndex(gridIndex),
648  pStream);
649 */
650 
651  monoTriangulationRecGen(rightGridChain->get_vertex(gridIndex),
652  botVertex,
653  leftChain, segLeftMono, leftEnd,
654  rightChain, down_rightCornerIndex, rightEnd,
655  pStream);
656  }//end left in right out
657  else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))//left out right in
658  {
659  Int segRightMono, segRightPass;
660  findBotRightSegment(rightChain, sep_right, down_rightCornerIndex,
661  rightGridChain->get_u_value(gridIndex),
662  segRightMono,
663  segRightPass);
664 
665  assert(segRightPass <= sep_right); //make sure there is a point to the left of u.
666  monoTriangulation2(rightGridChain->get_vertex(gridIndex),
667  rightChain->getVertex(segRightPass),
668  rightChain,
669  down_rightCornerIndex,
670  segRightPass-1,
671  0, // a decrease chain
672  pStream);
673 
674  stripOfFanRight(rightChain, segRightMono, segRightPass,
675  rightGridChain->getGrid(),
676  rightGridChain->getVlineIndex(gridIndex),
677  leftGridChain->getUlineIndex(gridIndex),
678  rightGridChain->getUlineIndex(gridIndex),
679  pStream, 1);
680 
681 
682  monoTriangulationRecGen(leftGridChain->get_vertex(gridIndex),
683  botVertex,
684  leftChain, down_leftCornerIndex, leftEnd,
685  rightChain, segRightMono, rightEnd,
686  pStream);
687 
688  }//end left out right in
689  else //left out, right out
690  {
691  sampleCompBotSimple(botVertex,
692  leftChain,
693  leftEnd,
694  rightChain,
695  rightEnd,
696  leftGridChain,
697  rightGridChain,
698  gridIndex,
699  down_leftCornerWhere,
700  down_leftCornerIndex,
701  down_rightCornerWhere,
702  down_rightCornerIndex,
703  pStream);
704 
705  }//end leftout right out
706  }//end if separator exists
707  else //no separator
708  {
709 
710  sampleCompBotSimple(botVertex,
711  leftChain,
712  leftEnd,
713  rightChain,
714  rightEnd,
715  leftGridChain,
716  rightGridChain,
717  gridIndex,
718  down_leftCornerWhere,
719  down_leftCornerIndex,
720  down_rightCornerWhere,
721  down_rightCornerIndex,
722  pStream);
723  }
724 #endif
725  }//end id 0 2
726 }//end if the functin
727 
728 
729 void sampleCompBotSimple(Real* botVertex,
730  vertexArray* leftChain,
731  Int leftEnd,
732  vertexArray* rightChain,
733  Int rightEnd,
734  gridBoundaryChain* leftGridChain,
735  gridBoundaryChain* rightGridChain,
736  Int gridIndex,
737  Int down_leftCornerWhere,
738  Int down_leftCornerIndex,
739  Int down_rightCornerWhere,
740  Int down_rightCornerIndex,
741  primStream* pStream)
742 {
743  //the plan is to use monotriangulation algorithm.
744  Int i,k;
745  Real* ActualTop;
746  Real* ActualBot;
747  Int ActualLeftStart, ActualLeftEnd;
748  Int ActualRightStart, ActualRightEnd;
749 
750  //creat an array to store the points on the grid line
751  gridWrap* grid = leftGridChain->getGrid();
752  Int gridV = leftGridChain->getVlineIndex(gridIndex);
753  Int gridLeftU = leftGridChain->getUlineIndex(gridIndex);
754  Int gridRightU = rightGridChain->getUlineIndex(gridIndex);
755  Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1));
756  assert(gridPoints);
757 
758  for(k=0, i=gridRightU; i>= gridLeftU; i--, k++)
759  {
760  gridPoints[k][0] = grid->get_u_value(i);
761  gridPoints[k][1] = grid->get_v_value(gridV);
762  }
763 
764  if(down_rightCornerWhere != 0) //rightCorner is not on lef
765  ActualLeftEnd = leftEnd;
766  else
767  ActualLeftEnd = down_rightCornerIndex-1; //down_rightCornerIndex will be th actualBot
768 
769  if(down_leftCornerWhere != 0) //left corner is not on let chian
770  ActualLeftStart = leftEnd+1; //meaning that there is no actual left section
771  else
772  ActualLeftStart = down_leftCornerIndex;
773 
774  vertexArray ActualLeftChain(max(0, ActualLeftEnd - ActualLeftStart +1) + gridRightU - gridLeftU +1);
775 
776  for(i=0; i<gridRightU - gridLeftU +1 ; i++)
777  ActualLeftChain.appendVertex(gridPoints[i]);
778  for(i=ActualLeftStart; i<= ActualLeftEnd; i++)
779  ActualLeftChain.appendVertex(leftChain->getVertex(i));
780 
781  //determine ActualRightStart
782  if(down_rightCornerWhere != 2) //right is not on right
783  ActualRightStart = rightEnd +1; //meaning no section on right
784  else
785  ActualRightStart = down_rightCornerIndex;
786 
787  //determine actualrightEnd
788  if(down_leftCornerWhere != 2) //left is not on right
789  {
790 
791  ActualRightEnd = rightEnd;
792  }
793  else //left corner is on right
794  {
795  ActualRightEnd = down_leftCornerIndex-1; //down_leftCornerIndex will be the bot
796 
797  }
798 
799  //actual bot
800  if(down_rightCornerWhere == 2)
801  {
802  if(down_leftCornerWhere == 2)
803  ActualBot = rightChain->getVertex(down_leftCornerIndex);
804  else
805  ActualBot = botVertex;
806  }
807  else if(down_rightCornerWhere == 1) //right corner bot
808  ActualBot = botVertex;
809  else //down_rightCornerWhere == 0
810  ActualBot = leftChain->getVertex(down_rightCornerIndex);
811 
812  ActualTop = gridPoints[0];
813 /*
814 printf("in bot simple, actual leftChain is \n");
815 ActualLeftChain.print();
816 printf("Actual Top = %f,%f\n", ActualTop[0],ActualTop[1]);
817 printf("Actual Bot = %f,%f\n", ActualBot[0],ActualBot[1]);
818 printf("Actual right start = %i, end=%i\n",ActualRightStart, ActualRightEnd);
819 */
820  if(rightChain->getVertex(ActualRightStart)[1] == ActualTop[1])
821  monoTriangulationRecGenOpt(rightChain->getVertex(ActualRightStart),
822  ActualBot,
823  &ActualLeftChain,
824  0,
825  ActualLeftChain.getNumElements()-1,
826  rightChain,
827  ActualRightStart+1,
828  ActualRightEnd,
829  pStream);
830  else
831  monoTriangulationRecGenOpt(ActualTop, ActualBot,
832  &ActualLeftChain,
833  1, //the first one is the top vertex
834  ActualLeftChain.getNumElements()-1,
835  rightChain,
836  ActualRightStart,
837  ActualRightEnd,
838  pStream);
839  free(gridPoints);
840 }
841 
842 
843 
844