1f220fa62Smrg/*
2f220fa62Smrg** License Applicability. Except to the extent portions of this file are
3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free
4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this
5f220fa62Smrg** file are subject only to the provisions of the License. You may not use
6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy
7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9f220fa62Smrg**
10f220fa62Smrg** http://oss.sgi.com/projects/FreeB
11f220fa62Smrg**
12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an
13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17f220fa62Smrg**
18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation,
19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21f220fa62Smrg** Copyright in any portions created by third parties is as indicated
22f220fa62Smrg** elsewhere herein. All Rights Reserved.
23f220fa62Smrg**
24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces
25f220fa62Smrg** established by SGI in conjunction with the Original Code are The
26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software
30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31f220fa62Smrg** published by SGI, but has not been independently verified as being
32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification.
33f220fa62Smrg*/
34f220fa62Smrg
35f220fa62Smrg/*
36f220fa62Smrg * slicer.c++
37f220fa62Smrg *
38f220fa62Smrg */
39f220fa62Smrg
40f220fa62Smrg#include <stdlib.h>
41f220fa62Smrg#include <stdio.h>
42f220fa62Smrg#include <math.h>
43f220fa62Smrg#include "glimports.h"
44f220fa62Smrg#include "mystdio.h"
45f220fa62Smrg#include "myassert.h"
46f220fa62Smrg#include "bufpool.h"
47f220fa62Smrg#include "slicer.h"
48f220fa62Smrg#include "backend.h"
49f220fa62Smrg#include "arc.h"
50f220fa62Smrg#include "gridtrimvertex.h"
51f220fa62Smrg#include "simplemath.h"
52f220fa62Smrg#include "trimvertex.h"
53f220fa62Smrg#include "varray.h"
54f220fa62Smrg
55f220fa62Smrg#include "polyUtil.h" //for area()
56f220fa62Smrg
57f220fa62Smrg//static int count=0;
58f220fa62Smrg
59f220fa62Smrg/*USE_OPTTT is initiated in trimvertex.h*/
60f220fa62Smrg
61f220fa62Smrg#ifdef USE_OPTTT
62f220fa62Smrg	#include <GL/gl.h>
63f220fa62Smrg#endif
64f220fa62Smrg
65f220fa62Smrg//#define USE_READ_FLAG //whether to use new or old tesselator
66f220fa62Smrg                          //if defined, it reads "flagFile",
67f220fa62Smrg                          // if the number is 1, then use new tess
68f220fa62Smrg                          // otherwise, use the old tess.
69f220fa62Smrg                         //if not defined, then use new tess.
70f220fa62Smrg#ifdef USE_READ_FLAG
71f220fa62Smrgstatic Int read_flag(char* name);
72f220fa62SmrgInt newtess_flag = read_flag("flagFile");
73f220fa62Smrg#endif
74f220fa62Smrg
75f220fa62Smrg//#define COUNT_TRIANGLES
76f220fa62Smrg#ifdef COUNT_TRIANGLES
77f220fa62SmrgInt num_triangles = 0;
78f220fa62SmrgInt num_quads = 0;
79f220fa62Smrg#endif
80f220fa62Smrg
81f220fa62Smrg#define max(a,b) ((a>b)? a:b)
82f220fa62Smrg#define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/
83f220fa62Smrg#define equalRect(a,b) ((glu_abs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle
84f220fa62Smrg
85f220fa62Smrg#if 0 // UNUSED
86f220fa62Smrgstatic Int is_Convex(Arc_ptr loop)
87f220fa62Smrg{
88f220fa62Smrg  if(area(loop->tail(), loop->head(), loop->next->head()) <0 )
89f220fa62Smrg    return 0;
90f220fa62Smrg  for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next)
91f220fa62Smrg    {
92f220fa62Smrg      if(area(jarc->tail(), jarc->head(), jarc->next->head()) < 0)
93f220fa62Smrg	return 0;
94f220fa62Smrg    }
95f220fa62Smrg  return 1;
96f220fa62Smrg}
97f220fa62Smrg#endif
98f220fa62Smrg
99f220fa62Smrg/******triangulate a monotone polygon**************/
100f220fa62Smrg#include "monoTriangulation.h"
101f220fa62Smrg#if 0 // UNUSED
102f220fa62Smrgstatic int is_U_monotone(Arc_ptr loop)
103f220fa62Smrg{
104f220fa62Smrg  int n_changes=0;
105f220fa62Smrg  int prev_sign;
106f220fa62Smrg  int cur_sign;
107f220fa62Smrg  Arc_ptr temp;
108f220fa62Smrg
109f220fa62Smrg  cur_sign = compV2InX(loop->head(), loop->tail());
110f220fa62Smrg
111f220fa62Smrg  n_changes  = (compV2InX(loop->prev->head(), loop->prev->tail())
112f220fa62Smrg		!= cur_sign);
113f220fa62Smrg
114f220fa62Smrg  for(temp=loop->next; temp != loop; temp = temp->next)
115f220fa62Smrg    {
116f220fa62Smrg      prev_sign = cur_sign;
117f220fa62Smrg      cur_sign = compV2InX(temp->head(), temp->tail());
118f220fa62Smrg      if(cur_sign != prev_sign)
119f220fa62Smrg       {
120f220fa62Smrg#ifdef DEBUG
121f220fa62Smrg	 printf("***change signe\n");
122f220fa62Smrg#endif
123f220fa62Smrg	 n_changes++;
124f220fa62Smrg       }
125f220fa62Smrg    }
126f220fa62Smrg  if(n_changes == 2) return 1;
127f220fa62Smrg  else
128f220fa62Smrg    return 0;
129f220fa62Smrg}
130f220fa62Smrg#endif
131f220fa62Smrg
132f220fa62Smrginline int compInY(REAL a[2], REAL b[2])
133f220fa62Smrg{
134f220fa62Smrg  if(a[1] < b[1])
135f220fa62Smrg    return -1;
136f220fa62Smrg  else if (a[1] > b[1])
137f220fa62Smrg    return 1;
138f220fa62Smrg  else if(a[0] > b[0])
139f220fa62Smrg    return 1;
140f220fa62Smrg  else return -1;
141f220fa62Smrg}
142f220fa62Smrg
143f220fa62Smrgvoid monoTriangulationLoop(Arc_ptr loop, Backend& backend, primStream* pStream)
144f220fa62Smrg{
145f220fa62Smrg  int i;
146f220fa62Smrg  //find the top, bottom, increasing and decreasing chain
147f220fa62Smrg  //then call monoTrianulation
148f220fa62Smrg  Arc_ptr jarc, temp;
149f220fa62Smrg  Arc_ptr top;
150f220fa62Smrg  Arc_ptr bot;
151f220fa62Smrg  top = bot = loop;
152f220fa62Smrg  if(compInY(loop->tail(), loop->prev->tail()) < 0)
153f220fa62Smrg    {
154f220fa62Smrg      //first find bot
155f220fa62Smrg      for(temp = loop->next; temp != loop; temp = temp->next)
156f220fa62Smrg	{
157f220fa62Smrg	  if(compInY(temp->tail(), temp->prev->tail()) > 0)
158f220fa62Smrg	    break;
159f220fa62Smrg	}
160f220fa62Smrg      bot = temp->prev;
161f220fa62Smrg      //then find top
162f220fa62Smrg      for(temp=loop->prev; temp != loop; temp = temp->prev)
163f220fa62Smrg	{
164f220fa62Smrg	  if(compInY(temp->tail(), temp->prev->tail()) > 0)
165f220fa62Smrg	    break;
166f220fa62Smrg	}
167f220fa62Smrg      top = temp;
168f220fa62Smrg    }
169f220fa62Smrg  else //loop > loop->prev
170f220fa62Smrg    {
171f220fa62Smrg      for(temp=loop->next; temp != loop; temp = temp->next)
172f220fa62Smrg	{
173f220fa62Smrg	  if(compInY(temp->tail(), temp->prev->tail()) < 0)
174f220fa62Smrg	    break;
175f220fa62Smrg	}
176f220fa62Smrg      top = temp->prev;
177f220fa62Smrg      for(temp=loop->prev; temp != loop; temp = temp->prev)
178f220fa62Smrg	{
179f220fa62Smrg	  if(compInY(temp->tail(), temp->prev->tail()) < 0)
180f220fa62Smrg	    break;
181f220fa62Smrg	}
182f220fa62Smrg      bot = temp;
183f220fa62Smrg    }
184f220fa62Smrg  //creat increase and decrease chains
185f220fa62Smrg  vertexArray inc_chain(50); //this is a dynamci array
186f220fa62Smrg  for(i=1; i<=top->pwlArc->npts-2; i++)
187f220fa62Smrg    {
188f220fa62Smrg      //the first vertex is the top which doesn't below to inc_chain
189f220fa62Smrg      inc_chain.appendVertex(top->pwlArc->pts[i].param);
190f220fa62Smrg    }
191f220fa62Smrg  for(jarc=top->next; jarc != bot; jarc = jarc->next)
192f220fa62Smrg    {
193f220fa62Smrg      for(i=0; i<=jarc->pwlArc->npts-2; i++)
194f220fa62Smrg	{
195f220fa62Smrg	  inc_chain.appendVertex(jarc->pwlArc->pts[i].param);
196f220fa62Smrg	}
197f220fa62Smrg
198f220fa62Smrg    }
199f220fa62Smrg  vertexArray dec_chain(50);
200f220fa62Smrg  for(jarc = top->prev; jarc != bot; jarc = jarc->prev)
201f220fa62Smrg    {
202f220fa62Smrg      for(i=jarc->pwlArc->npts-2; i>=0; i--)
203f220fa62Smrg	{
204f220fa62Smrg	  dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
205f220fa62Smrg	}
206f220fa62Smrg    }
207f220fa62Smrg  for(i=bot->pwlArc->npts-2; i>=1; i--)
208f220fa62Smrg    {
209f220fa62Smrg      dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
210f220fa62Smrg    }
211f220fa62Smrg
212f220fa62Smrg  monoTriangulationRec(top->tail(), bot->tail(), &inc_chain, 0,
213f220fa62Smrg		       &dec_chain, 0, &backend);
214f220fa62Smrg
215f220fa62Smrg}
216f220fa62Smrg
217f220fa62Smrg/********tesselate a rectanlge (OPTIMIZATION**************/
218f220fa62Smrgstatic void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend);
219f220fa62Smrg
220f220fa62Smrgstatic Int is_rect(Arc_ptr loop)
221f220fa62Smrg{
222f220fa62Smrg  Int nlines =1;
223f220fa62Smrg  for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next)
224f220fa62Smrg    {
225f220fa62Smrg      nlines++;
226f220fa62Smrg      if(nlines == 5)
227f220fa62Smrg	break;
228f220fa62Smrg    }
229f220fa62Smrg  if(nlines != 4)
230f220fa62Smrg    return 0;
231f220fa62Smrg
232f220fa62Smrg
233f220fa62Smrg/*
234f220fa62Smrgprintf("here1\n");
235f220fa62Smrgprintf("loop->tail=(%f,%f)\n", loop->tail()[0], loop->tail()[1]);
236f220fa62Smrgprintf("loop->head=(%f,%f)\n", loop->head()[0], loop->head()[1]);
237f220fa62Smrgprintf("loop->next->tail=(%f,%f)\n", loop->next->tail()[0], loop->next->tail()[1]);
238f220fa62Smrgprintf("loop->next->head=(%f,%f)\n", loop->next->head()[0], loop->next->head()[1]);
239f220fa62Smrgif(fglu_abs(loop->tail()[0] - loop->head()[0])<0.000001)
240f220fa62Smrg	printf("equal 1\n");
241f220fa62Smrgif(loop->next->tail()[1] == loop->next->head()[1])
242f220fa62Smrg	printf("equal 2\n");
243f220fa62Smrg*/
244f220fa62Smrg
245f220fa62Smrg  if( (glu_abs(loop->tail()[0] - loop->head()[0])<=ZERO) &&
246f220fa62Smrg      (glu_abs(loop->next->tail()[1] - loop->next->head()[1])<=ZERO) &&
247f220fa62Smrg      (glu_abs(loop->prev->tail()[1] - loop->prev->head()[1])<=ZERO) &&
248f220fa62Smrg      (glu_abs(loop->prev->prev->tail()[0] - loop->prev->prev->head()[0])<=ZERO)
249f220fa62Smrg     )
250f220fa62Smrg    return 1;
251f220fa62Smrg  else if
252f220fa62Smrg    ( (glu_abs(loop->tail()[1] - loop->head()[1]) <= ZERO) &&
253f220fa62Smrg      (glu_abs(loop->next->tail()[0] - loop->next->head()[0]) <= ZERO) &&
254f220fa62Smrg      (glu_abs(loop->prev->tail()[0] - loop->prev->head()[0]) <= ZERO) &&
255f220fa62Smrg      (glu_abs(loop->prev->prev->tail()[1] - loop->prev->prev->head()[1]) <= ZERO)
256f220fa62Smrg     )
257f220fa62Smrg      return 1;
258f220fa62Smrg  else
259f220fa62Smrg    return 0;
260f220fa62Smrg}
261f220fa62Smrg
262f220fa62Smrg
263f220fa62Smrg//a line with the same u for opt
264f220fa62Smrg#ifdef USE_OPTTT
265f220fa62Smrgstatic void evalLineNOGE_BU(TrimVertex *verts, int n, Backend& backend)
266f220fa62Smrg{
267f220fa62Smrg  int i;
268f220fa62Smrg  backend.preEvaluateBU(verts[0].param[0]);
269f220fa62Smrg  for(i=0; i<n; i++)
270f220fa62Smrg    backend.tmeshvertNOGE_BU(&verts[i]);
271f220fa62Smrg}
272f220fa62Smrg#endif
273f220fa62Smrg
274f220fa62Smrg//a line with the same v for opt
275f220fa62Smrg#ifdef USE_OPTTT
276f220fa62Smrgstatic void evalLineNOGE_BV(TrimVertex *verts, int n, Backend& backend)
277f220fa62Smrg{
278f220fa62Smrg  int i;
279f220fa62Smrg  backend.preEvaluateBV(verts[0].param[1]);
280f220fa62Smrg
281f220fa62Smrg  for(i=0; i<n; i++)
282f220fa62Smrg    backend.tmeshvertNOGE_BV(&verts[i]);
283f220fa62Smrg}
284f220fa62Smrg#endif
285f220fa62Smrg
286f220fa62Smrg#ifdef USE_OPTTT
287f220fa62Smrgstatic void evalLineNOGE(TrimVertex *verts, int n, Backend& backend)
288f220fa62Smrg{
289f220fa62Smrg
290f220fa62Smrg  if(verts[0].param[0] == verts[n-1].param[0]) //all u;s are equal
291f220fa62Smrg    evalLineNOGE_BU(verts, n, backend);
292f220fa62Smrg  else if(verts[0].param[1] == verts[n-1].param[1]) //all v's are equal
293f220fa62Smrg    evalLineNOGE_BV(verts, n, backend);
294f220fa62Smrg  else
295f220fa62Smrg    {
296f220fa62Smrg      int i;
297f220fa62Smrg      for(i=0; i<n; i++)
298f220fa62Smrg	backend.tmeshvertNOGE(&verts[i]);
299f220fa62Smrg    }
300f220fa62Smrg}
301f220fa62Smrg#endif
302f220fa62Smrg
303f220fa62Smrginline void  OPT_OUTVERT(TrimVertex& vv, Backend& backend)
304f220fa62Smrg{
305f220fa62Smrg
306f220fa62Smrg#ifdef USE_OPTTT
307f220fa62Smrg  glNormal3fv(vv.cache_normal);
308f220fa62Smrg  glVertex3fv(vv.cache_point);
309f220fa62Smrg#else
310f220fa62Smrg
311f220fa62Smrg  backend.tmeshvert(&vv);
312f220fa62Smrg
313f220fa62Smrg#endif
314f220fa62Smrg
315f220fa62Smrg}
316f220fa62Smrg
317f220fa62Smrgstatic void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend);
318f220fa62Smrg
319f220fa62Smrgstatic void triangulateRect(Arc_ptr loop, Backend& backend, int TB_or_LR, int ulinear, int vlinear)
320f220fa62Smrg{
321f220fa62Smrg  //we know the loop is a rectangle, but not sure which is top
322f220fa62Smrg  Arc_ptr top, bot, left, right;
323f220fa62Smrg  if(loop->tail()[1] == loop->head()[1])
324f220fa62Smrg    {
325f220fa62Smrg      if(loop->tail()[1] > loop->prev->prev->tail()[1])
326f220fa62Smrg	{
327f220fa62Smrg
328f220fa62Smrg	top = loop;
329f220fa62Smrg	}
330f220fa62Smrg      else{
331f220fa62Smrg
332f220fa62Smrg	top = loop->prev->prev;
333f220fa62Smrg	}
334f220fa62Smrg    }
335f220fa62Smrg  else
336f220fa62Smrg    {
337f220fa62Smrg      if(loop->tail()[0] > loop->prev->prev->tail()[0])
338f220fa62Smrg	{
339f220fa62Smrg	  //loop is the right arc
340f220fa62Smrg
341f220fa62Smrg	  top = loop->next;
342f220fa62Smrg	}
343f220fa62Smrg      else
344f220fa62Smrg	{
345f220fa62Smrg
346f220fa62Smrg	  top = loop->prev;
347f220fa62Smrg	}
348f220fa62Smrg    }
349f220fa62Smrg  left = top->next;
350f220fa62Smrg  bot  = left->next;
351f220fa62Smrg  right= bot->next;
352f220fa62Smrg
353f220fa62Smrg  //if u, v are both nonlinear, then if the
354f220fa62Smrg  //boundary is tessellated dense, we also
355f220fa62Smrg  //sample the inside to get a better tesslletant.
356f220fa62Smrg  if( (!ulinear) && (!vlinear))
357f220fa62Smrg    {
358f220fa62Smrg      int nu = top->pwlArc->npts;
359f220fa62Smrg      if(nu < bot->pwlArc->npts)
360f220fa62Smrg	nu = bot->pwlArc->npts;
361f220fa62Smrg      int nv = left->pwlArc->npts;
362f220fa62Smrg      if(nv < right->pwlArc->npts)
363f220fa62Smrg	nv = right->pwlArc->npts;
364f220fa62Smrg/*
365f220fa62Smrg      if(nu > 2 && nv > 2)
366f220fa62Smrg	{
367f220fa62Smrg	  triangulateRectGen(top, nu-2,  nv-2, backend);
368f220fa62Smrg	  return;
369f220fa62Smrg	}
370f220fa62Smrg*/
371f220fa62Smrg    }
372f220fa62Smrg
373f220fa62Smrg  if(TB_or_LR == 1)
374f220fa62Smrg    triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
375f220fa62Smrg  else if(TB_or_LR == -1)
376f220fa62Smrg    triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);
377f220fa62Smrg  else
378f220fa62Smrg    {
379f220fa62Smrg      Int maxPointsTB = top->pwlArc->npts + bot->pwlArc->npts;
380f220fa62Smrg      Int maxPointsLR = left->pwlArc->npts + right->pwlArc->npts;
381f220fa62Smrg
382f220fa62Smrg      if(maxPointsTB < maxPointsLR)
383f220fa62Smrg	triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);
384f220fa62Smrg      else
385f220fa62Smrg	triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
386f220fa62Smrg    }
387f220fa62Smrg}
388f220fa62Smrg
389f220fa62Smrgstatic void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend)
390f220fa62Smrg{ //if(maxPointsTB >= maxPointsLR)
391f220fa62Smrg    {
392f220fa62Smrg
393f220fa62Smrg      Int d, topd_left, topd_right, botd_left, botd_right, i,j;
394f220fa62Smrg      d = left->npts /2;
395f220fa62Smrg
396f220fa62Smrg#ifdef USE_OPTTT
397f220fa62Smrg      evalLineNOGE(top->pts, top->npts, backend);
398f220fa62Smrg      evalLineNOGE(bot->pts, bot->npts, backend);
399f220fa62Smrg      evalLineNOGE(left->pts, left->npts, backend);
400f220fa62Smrg      evalLineNOGE(right->pts, right->npts, backend);
401f220fa62Smrg#endif
402f220fa62Smrg
403f220fa62Smrg      if(top->npts == 2) {
404f220fa62Smrg	backend.bgntfan();
405f220fa62Smrg	OPT_OUTVERT(top->pts[0], backend);//the root
406f220fa62Smrg	for(i=0; i<left->npts; i++){
407f220fa62Smrg	  OPT_OUTVERT(left->pts[i], backend);
408f220fa62Smrg	}
409f220fa62Smrg	for(i=1; i<= bot->npts-2; i++){
410f220fa62Smrg	  OPT_OUTVERT(bot->pts[i], backend);
411f220fa62Smrg	}
412f220fa62Smrg	backend.endtfan();
413f220fa62Smrg
414f220fa62Smrg	backend.bgntfan();
415f220fa62Smrg	OPT_OUTVERT(bot->pts[bot->npts-2], backend);
416f220fa62Smrg	for(i=0; i<right->npts; i++){
417f220fa62Smrg	  OPT_OUTVERT(right->pts[i], backend);
418f220fa62Smrg	}
419f220fa62Smrg	backend.endtfan();
420f220fa62Smrg      }
421f220fa62Smrg      else if(bot->npts == 2) {
422f220fa62Smrg	backend.bgntfan();
423f220fa62Smrg	OPT_OUTVERT(bot->pts[0], backend);//the root
424f220fa62Smrg	for(i=0; i<right->npts; i++){
425f220fa62Smrg	  OPT_OUTVERT(right->pts[i], backend);
426f220fa62Smrg	}
427f220fa62Smrg	for(i=1; i<= top->npts-2; i++){
428f220fa62Smrg	  OPT_OUTVERT(top->pts[i], backend);
429f220fa62Smrg	}
430f220fa62Smrg	backend.endtfan();
431f220fa62Smrg
432f220fa62Smrg	backend.bgntfan();
433f220fa62Smrg	OPT_OUTVERT(top->pts[top->npts-2], backend);
434f220fa62Smrg	for(i=0; i<left->npts; i++){
435f220fa62Smrg	  OPT_OUTVERT(left->pts[i], backend);
436f220fa62Smrg	}
437f220fa62Smrg	backend.endtfan();
438f220fa62Smrg      }
439f220fa62Smrg      else { //both top and bot have >=3 points
440f220fa62Smrg
441f220fa62Smrg	backend.bgntfan();
442f220fa62Smrg
443f220fa62Smrg	OPT_OUTVERT(top->pts[top->npts-2], backend);
444f220fa62Smrg
445f220fa62Smrg	for(i=0; i<=d; i++)
446f220fa62Smrg	  {
447f220fa62Smrg	    OPT_OUTVERT(left->pts[i], backend);
448f220fa62Smrg	  }
449f220fa62Smrg	backend.endtfan();
450f220fa62Smrg
451f220fa62Smrg	backend.bgntfan();
452f220fa62Smrg
453f220fa62Smrg	OPT_OUTVERT(bot->pts[1], backend);
454f220fa62Smrg
455f220fa62Smrg	OPT_OUTVERT(top->pts[top->npts-2], backend);
456f220fa62Smrg
457f220fa62Smrg	for(i=d; i< left->npts; i++)
458f220fa62Smrg	  {
459f220fa62Smrg	    OPT_OUTVERT(left->pts[i], backend);
460f220fa62Smrg	  }
461f220fa62Smrg	backend.endtfan();
462f220fa62Smrg
463f220fa62Smrg	d = right->npts/2;
464f220fa62Smrg	//output only when d<right->npts-1 and
465f220fa62Smrg	//
466f220fa62Smrg	if(d<right->npts-1)
467f220fa62Smrg	  {
468f220fa62Smrg	    backend.bgntfan();
469f220fa62Smrg	    //      backend.tmeshvert(& top->pts[1]);
470f220fa62Smrg	    OPT_OUTVERT(top->pts[1], backend);
471f220fa62Smrg	    for(i=d; i< right->npts; i++)
472f220fa62Smrg	      {
473f220fa62Smrg		//	  backend.tmeshvert(& right->pts[i]);
474f220fa62Smrg
475f220fa62Smrg		OPT_OUTVERT(right->pts[i], backend);
476f220fa62Smrg
477f220fa62Smrg	      }
478f220fa62Smrg	    backend.endtfan();
479f220fa62Smrg	  }
480f220fa62Smrg
481f220fa62Smrg	backend.bgntfan();
482f220fa62Smrg	//      backend.tmeshvert(& bot->pts[bot->npts-2]);
483f220fa62Smrg	OPT_OUTVERT( bot->pts[bot->npts-2], backend);
484f220fa62Smrg	for(i=0; i<=d; i++)
485f220fa62Smrg	  {
486f220fa62Smrg	    //	  backend.tmeshvert(& right->pts[i]);
487f220fa62Smrg	    OPT_OUTVERT(right->pts[i], backend);
488f220fa62Smrg
489f220fa62Smrg	  }
490f220fa62Smrg
491f220fa62Smrg	//      backend.tmeshvert(& top->pts[1]);
492f220fa62Smrg	OPT_OUTVERT(top->pts[1], backend);
493f220fa62Smrg
494f220fa62Smrg	backend.endtfan();
495f220fa62Smrg
496f220fa62Smrg
497f220fa62Smrg	topd_left = top->npts-2;
498f220fa62Smrg	topd_right = 1; //topd_left>= topd_right
499f220fa62Smrg
500f220fa62Smrg	botd_left = 1;
501f220fa62Smrg	botd_right = bot->npts-2; //botd_left<= bot_dright
502f220fa62Smrg
503f220fa62Smrg
504f220fa62Smrg	if(top->npts < bot->npts)
505f220fa62Smrg	  {
506f220fa62Smrg	    int delta=bot->npts - top->npts;
507f220fa62Smrg	    int u = delta/2;
508f220fa62Smrg	    botd_left = 1+ u;
509f220fa62Smrg	    botd_right = bot->npts-2-( delta-u);
510f220fa62Smrg
511f220fa62Smrg	    if(botd_left >1)
512f220fa62Smrg	      {
513f220fa62Smrg		backend.bgntfan();
514f220fa62Smrg		//	  backend.tmeshvert(& top->pts[top->npts-2]);
515f220fa62Smrg		OPT_OUTVERT(top->pts[top->npts-2], backend);
516f220fa62Smrg		for(i=1; i<= botd_left; i++)
517f220fa62Smrg		  {
518f220fa62Smrg		    //	      backend.tmeshvert(& bot->pts[i]);
519f220fa62Smrg		    OPT_OUTVERT(bot->pts[i] , backend);
520f220fa62Smrg		  }
521f220fa62Smrg		backend.endtfan();
522f220fa62Smrg	      }
523f220fa62Smrg	    if(botd_right < bot->npts-2)
524f220fa62Smrg	      {
525f220fa62Smrg		backend.bgntfan();
526f220fa62Smrg		OPT_OUTVERT(top->pts[1], backend);
527f220fa62Smrg		for(i=botd_right; i<= bot->npts-2; i++)
528f220fa62Smrg		  OPT_OUTVERT(bot->pts[i], backend);
529f220fa62Smrg		backend.endtfan();
530f220fa62Smrg	      }
531f220fa62Smrg	  }
532f220fa62Smrg	else if(top->npts> bot->npts)
533f220fa62Smrg	  {
534f220fa62Smrg	    int delta=top->npts-bot->npts;
535f220fa62Smrg	    int u = delta/2;
536f220fa62Smrg	    topd_left = top->npts-2 - u;
537f220fa62Smrg	    topd_right = 1+delta-u;
538f220fa62Smrg
539f220fa62Smrg	    if(topd_left < top->npts-2)
540f220fa62Smrg	      {
541f220fa62Smrg		backend.bgntfan();
542f220fa62Smrg		//	  backend.tmeshvert(& bot->pts[1]);
543f220fa62Smrg		OPT_OUTVERT(bot->pts[1], backend);
544f220fa62Smrg		for(i=topd_left; i<= top->npts-2; i++)
545f220fa62Smrg		  {
546f220fa62Smrg		    //	      backend.tmeshvert(& top->pts[i]);
547f220fa62Smrg		    OPT_OUTVERT(top->pts[i], backend);
548f220fa62Smrg		  }
549f220fa62Smrg		backend.endtfan();
550f220fa62Smrg	      }
551f220fa62Smrg	    if(topd_right > 1)
552f220fa62Smrg	      {
553f220fa62Smrg		backend.bgntfan();
554f220fa62Smrg		OPT_OUTVERT(bot->pts[bot->npts-2], backend);
555f220fa62Smrg		for(i=1; i<= topd_right; i++)
556f220fa62Smrg		  OPT_OUTVERT(top->pts[i], backend);
557f220fa62Smrg		backend.endtfan();
558f220fa62Smrg	      }
559f220fa62Smrg	  }
560f220fa62Smrg
561f220fa62Smrg	if(topd_left <= topd_right)
562f220fa62Smrg	  return;
563f220fa62Smrg
564f220fa62Smrg	backend.bgnqstrip();
565f220fa62Smrg	for(j=botd_left, i=topd_left; i>=topd_right; i--,j++)
566f220fa62Smrg	  {
567f220fa62Smrg	    //	  backend.tmeshvert(& top->pts[i]);
568f220fa62Smrg	    //	  backend.tmeshvert(& bot->pts[j]);
569f220fa62Smrg	    OPT_OUTVERT(top->pts[i], backend);
570f220fa62Smrg	    OPT_OUTVERT(bot->pts[j], backend);
571f220fa62Smrg	  }
572f220fa62Smrg	backend.endqstrip();
573f220fa62Smrg
574f220fa62Smrg      }
575f220fa62Smrg    }
576f220fa62Smrg}
577f220fa62Smrg
578f220fa62Smrg
579f220fa62Smrgstatic void triangulateRectCenter(int n_ulines, REAL* u_val,
580f220fa62Smrg				  int n_vlines, REAL* v_val,
581f220fa62Smrg				  Backend& backend)
582f220fa62Smrg{
583f220fa62Smrg
584f220fa62Smrg  // XXX this code was patched by Diego Santa Cruz <Diego.SantaCruz@epfl.ch>
585f220fa62Smrg  // to fix a problem in which glMapGrid2f() was called with bad parameters.
586f220fa62Smrg  // This has beens submitted to SGI but not integrated as of May 1, 2001.
587f220fa62Smrg  if(n_ulines>1 && n_vlines>1) {
588f220fa62Smrg    backend.surfgrid(u_val[0], u_val[n_ulines-1], n_ulines-1,
589f220fa62Smrg                     v_val[n_vlines-1], v_val[0], n_vlines-1);
590f220fa62Smrg    backend.surfmesh(0,0,n_ulines-1,n_vlines-1);
591f220fa62Smrg  }
592f220fa62Smrg
593f220fa62Smrg  return;
594f220fa62Smrg
595f220fa62Smrg  /*
596f220fa62Smrg  for(i=0; i<n_vlines-1; i++)
597f220fa62Smrg    {
598f220fa62Smrg
599f220fa62Smrg      backend.bgnqstrip();
600f220fa62Smrg      for(j=0; j<n_ulines; j++)
601f220fa62Smrg	{
602f220fa62Smrg	  trimVert.param[0] = u_val[j];
603f220fa62Smrg	  trimVert.param[1] = v_val[i+1];
604f220fa62Smrg	  backend.tmeshvert(& trimVert);
605f220fa62Smrg
606f220fa62Smrg	  trimVert.param[1] = v_val[i];
607f220fa62Smrg	  backend.tmeshvert(& trimVert);
608f220fa62Smrg	}
609f220fa62Smrg      backend.endqstrip();
610f220fa62Smrg
611f220fa62Smrg    }
612f220fa62Smrg    */
613f220fa62Smrg}
614f220fa62Smrg
615f220fa62Smrg//it works for top, bot, left ad right, you need ot select correct arguments
616f220fa62Smrgstatic void triangulateRectTopGen(Arc_ptr arc, int n_ulines, REAL* u_val, Real v, int dir, int is_u, Backend& backend)
617f220fa62Smrg{
618f220fa62Smrg
619f220fa62Smrg  if(is_u)
620f220fa62Smrg    {
621f220fa62Smrg      int i,k;
622f220fa62Smrg      REAL* upper_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
623f220fa62Smrg      assert(upper_val);
624f220fa62Smrg      if(dir)
625f220fa62Smrg	{
626f220fa62Smrg	  for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
627f220fa62Smrg	    {
628f220fa62Smrg	      upper_val[k] = arc->pwlArc->pts[i].param[0];
629f220fa62Smrg	    }
630f220fa62Smrg	  backend.evalUStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[1],
631f220fa62Smrg			     upper_val,
632f220fa62Smrg			     n_ulines, v, u_val);
633f220fa62Smrg	}
634f220fa62Smrg      else
635f220fa62Smrg	{
636f220fa62Smrg	  for(k=0,i=0;  i<arc->pwlArc->npts; i++,k++)
637f220fa62Smrg	    {
638f220fa62Smrg	      upper_val[k] = arc->pwlArc->pts[i].param[0];
639f220fa62Smrg
640f220fa62Smrg	    }
641f220fa62Smrg
642f220fa62Smrg	  backend.evalUStrip(
643f220fa62Smrg			     n_ulines, v, u_val,
644f220fa62Smrg			     arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], upper_val
645f220fa62Smrg			     );
646f220fa62Smrg	}
647f220fa62Smrg
648f220fa62Smrg      free(upper_val);
649f220fa62Smrg      return;
650f220fa62Smrg    }
651f220fa62Smrg  else //is_v
652f220fa62Smrg    {
653f220fa62Smrg      int i,k;
654f220fa62Smrg      REAL* left_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
655f220fa62Smrg      assert(left_val);
656f220fa62Smrg      if(dir)
657f220fa62Smrg	{
658f220fa62Smrg	  for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
659f220fa62Smrg	    {
660f220fa62Smrg	      left_val[k] = arc->pwlArc->pts[i].param[1];
661f220fa62Smrg	    }
662f220fa62Smrg	  backend.evalVStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[0],
663f220fa62Smrg			     left_val,
664f220fa62Smrg			     n_ulines, v, u_val);
665f220fa62Smrg	}
666f220fa62Smrg      else
667f220fa62Smrg	{
668f220fa62Smrg	  for(k=0,i=0;  i<arc->pwlArc->npts; i++,k++)
669f220fa62Smrg	    {
670f220fa62Smrg	      left_val[k] = arc->pwlArc->pts[i].param[1];
671f220fa62Smrg	    }
672f220fa62Smrg	   backend.evalVStrip(
673f220fa62Smrg			     n_ulines, v, u_val,
674f220fa62Smrg			     arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], left_val
675f220fa62Smrg			     );
676f220fa62Smrg	}
677f220fa62Smrg      free(left_val);
678f220fa62Smrg      return;
679f220fa62Smrg    }
680f220fa62Smrg
681f220fa62Smrg  //the following is a different version of the above code. If you comment
682f220fa62Smrg  //the above code, the following code will still work. The reason to leave
683f220fa62Smrg  //the folliwng code here is purely for testing purpose.
684f220fa62Smrg  /*
685f220fa62Smrg  int i,j;
686f220fa62Smrg  PwlArc* parc = arc->pwlArc;
687f220fa62Smrg  int d1 = parc->npts-1;
688f220fa62Smrg  int d2 = 0;
689f220fa62Smrg  TrimVertex trimVert;
690f220fa62Smrg  trimVert.nuid = 0;//????
691f220fa62Smrg  REAL* temp_u_val = u_val;
692f220fa62Smrg  if(dir ==0) //have to reverse u_val
693f220fa62Smrg    {
694f220fa62Smrg      temp_u_val = (REAL*) malloc(sizeof(REAL) * n_ulines);
695f220fa62Smrg      assert(temp_u_val);
696f220fa62Smrg      for(i=0; i<n_ulines; i++)
697f220fa62Smrg	temp_u_val[i] = u_val[n_ulines-1-i];
698f220fa62Smrg    }
699f220fa62Smrg  u_val = temp_u_val;
700f220fa62Smrg
701f220fa62Smrg  if(parc->npts > n_ulines)
702f220fa62Smrg    {
703f220fa62Smrg      d1 = n_ulines-1;
704f220fa62Smrg
705f220fa62Smrg      backend.bgntfan();
706f220fa62Smrg      if(is_u){
707f220fa62Smrg	trimVert.param[0] = u_val[0];
708f220fa62Smrg	trimVert.param[1] = v;
709f220fa62Smrg      }
710f220fa62Smrg      else
711f220fa62Smrg	{
712f220fa62Smrg	trimVert.param[1] = u_val[0];
713f220fa62Smrg	trimVert.param[0] = v;
714f220fa62Smrg      }
715f220fa62Smrg
716f220fa62Smrg      backend.tmeshvert(& trimVert);
717f220fa62Smrg      for(i=d1; i< parc->npts; i++)
718f220fa62Smrg	backend.tmeshvert(& parc->pts[i]);
719f220fa62Smrg      backend.endtfan();
720f220fa62Smrg
721f220fa62Smrg
722f220fa62Smrg    }
723f220fa62Smrg  else if(parc->npts < n_ulines)
724f220fa62Smrg    {
725f220fa62Smrg      d2 = n_ulines-parc->npts;
726f220fa62Smrg
727f220fa62Smrg
728f220fa62Smrg      backend.bgntfan();
729f220fa62Smrg      backend.tmeshvert(& parc->pts[parc->npts-1]);
730f220fa62Smrg      for(i=0; i<= d2; i++)
731f220fa62Smrg	{
732f220fa62Smrg	  if(is_u){
733f220fa62Smrg	    trimVert.param[0] = u_val[i];
734f220fa62Smrg	    trimVert.param[1] = v;
735f220fa62Smrg	  }
736f220fa62Smrg	  else
737f220fa62Smrg	    {
738f220fa62Smrg	      trimVert.param[1] = u_val[i];
739f220fa62Smrg	      trimVert.param[0] = v;
740f220fa62Smrg	    }
741f220fa62Smrg	  backend.tmeshvert(&trimVert);
742f220fa62Smrg	}
743f220fa62Smrg      backend.endtfan();
744f220fa62Smrg
745f220fa62Smrg    }
746f220fa62Smrg  if(d1>0){
747f220fa62Smrg
748f220fa62Smrg
749f220fa62Smrg    backend.bgnqstrip();
750f220fa62Smrg    for(i=d1, j=d2; i>=0; i--, j++)
751f220fa62Smrg      {
752f220fa62Smrg	backend.tmeshvert(& parc->pts[i]);
753f220fa62Smrg
754f220fa62Smrg	if(is_u){
755f220fa62Smrg	  trimVert.param[0] = u_val[j];
756f220fa62Smrg	  trimVert.param[1] = v;
757f220fa62Smrg	}
758f220fa62Smrg	else{
759f220fa62Smrg	  trimVert.param[1] = u_val[j];
760f220fa62Smrg	  trimVert.param[0] = v;
761f220fa62Smrg	}
762f220fa62Smrg	backend.tmeshvert(&trimVert);
763f220fa62Smrg
764f220fa62Smrg
765f220fa62Smrg
766f220fa62Smrg      }
767f220fa62Smrg    backend.endqstrip();
768f220fa62Smrg
769f220fa62Smrg
770f220fa62Smrg  }
771f220fa62Smrg  if(dir == 0)  //temp_u_val was mallocated
772f220fa62Smrg    free(temp_u_val);
773f220fa62Smrg */
774f220fa62Smrg}
775f220fa62Smrg
776f220fa62Smrg//n_ulines is the number of ulines inside, and n_vlines is the number of vlines
777f220fa62Smrg//inside, different from meanings elsewhere!!!
778f220fa62Smrgstatic void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend)
779f220fa62Smrg{
780f220fa62Smrg
781f220fa62Smrg  int i;
782f220fa62Smrg  //we know the loop is a rectangle, but not sure which is top
783f220fa62Smrg  Arc_ptr top, bot, left, right;
784f220fa62Smrg
785f220fa62Smrg  if(equalRect(loop->tail()[1] ,  loop->head()[1]))
786f220fa62Smrg    {
787f220fa62Smrg
788f220fa62Smrg      if(loop->tail()[1] > loop->prev->prev->tail()[1])
789f220fa62Smrg	{
790f220fa62Smrg
791f220fa62Smrg	top = loop;
792f220fa62Smrg	}
793f220fa62Smrg      else{
794f220fa62Smrg
795f220fa62Smrg	top = loop->prev->prev;
796f220fa62Smrg	}
797f220fa62Smrg    }
798f220fa62Smrg  else
799f220fa62Smrg    {
800f220fa62Smrg      if(loop->tail()[0] > loop->prev->prev->tail()[0])
801f220fa62Smrg	{
802f220fa62Smrg	  //loop is the right arc
803f220fa62Smrg
804f220fa62Smrg	  top = loop->next;
805f220fa62Smrg	}
806f220fa62Smrg      else
807f220fa62Smrg	{
808f220fa62Smrg
809f220fa62Smrg	  top = loop->prev;
810f220fa62Smrg	}
811f220fa62Smrg    }
812f220fa62Smrg
813f220fa62Smrg  left = top->next;
814f220fa62Smrg  bot  = left->next;
815f220fa62Smrg  right= bot->next;
816f220fa62Smrg
817f220fa62Smrg#ifdef COUNT_TRIANGLES
818f220fa62Smrg  num_triangles += loop->pwlArc->npts +
819f220fa62Smrg                 left->pwlArc->npts +
820f220fa62Smrg                 bot->pwlArc->npts +
821f220fa62Smrg		  right->pwlArc->npts
822f220fa62Smrg		      + 2*n_ulines + 2*n_vlines
823f220fa62Smrg			-8;
824f220fa62Smrg  num_quads += (n_ulines-1)*(n_vlines-1);
825f220fa62Smrg#endif
826f220fa62Smrg/*
827f220fa62Smrg  backend.surfgrid(left->tail()[0], right->tail()[0], n_ulines+1,
828f220fa62Smrg		   top->tail()[1], bot->tail()[1], n_vlines+1);
829f220fa62Smrg//  if(n_ulines>1 && n_vlines>1)
830f220fa62Smrg    backend.surfmesh(0,0,n_ulines+1,n_vlines+1);
831f220fa62Smrgreturn;
832f220fa62Smrg*/
833f220fa62Smrg  REAL* u_val=(REAL*) malloc(sizeof(REAL)*n_ulines);
834f220fa62Smrg  assert(u_val);
835f220fa62Smrg  REAL* v_val=(REAL*)malloc(sizeof(REAL) * n_vlines);
836f220fa62Smrg  assert(v_val);
837f220fa62Smrg  REAL u_stepsize = (right->tail()[0] - left->tail()[0])/( (REAL) n_ulines+1);
838f220fa62Smrg  REAL v_stepsize = (top->tail()[1] - bot->tail()[1])/( (REAL) n_vlines+1);
839f220fa62Smrg  Real temp=left->tail()[0]+u_stepsize;
840f220fa62Smrg  for(i=0; i<n_ulines; i++)
841f220fa62Smrg    {
842f220fa62Smrg      u_val[i] = temp;
843f220fa62Smrg      temp += u_stepsize;
844f220fa62Smrg    }
845f220fa62Smrg  temp = bot->tail()[1] + v_stepsize;
846f220fa62Smrg  for(i=0; i<n_vlines; i++)
847f220fa62Smrg    {
848f220fa62Smrg      v_val[i] = temp;
849f220fa62Smrg      temp += v_stepsize;
850f220fa62Smrg    }
851f220fa62Smrg
852f220fa62Smrg  triangulateRectTopGen(top, n_ulines, u_val, v_val[n_vlines-1], 1,1, backend);
853f220fa62Smrg  triangulateRectTopGen(bot, n_ulines, u_val, v_val[0], 0, 1, backend);
854f220fa62Smrg  triangulateRectTopGen(left, n_vlines, v_val, u_val[0], 1, 0, backend);
855f220fa62Smrg  triangulateRectTopGen(right, n_vlines, v_val, u_val[n_ulines-1], 0,0, backend);
856f220fa62Smrg
857f220fa62Smrg
858f220fa62Smrg
859f220fa62Smrg
860f220fa62Smrg  //triangulate the center
861f220fa62Smrg  triangulateRectCenter(n_ulines, u_val, n_vlines, v_val, backend);
862f220fa62Smrg
863f220fa62Smrg  free(u_val);
864f220fa62Smrg  free(v_val);
865f220fa62Smrg
866f220fa62Smrg}
867f220fa62Smrg
868f220fa62Smrg
869f220fa62Smrg
870f220fa62Smrg
871f220fa62Smrg/**********for reading newtess_flag from a file**********/
872f220fa62Smrg#ifdef USE_READ_FLAG
873f220fa62Smrgstatic Int read_flag(char* name)
874f220fa62Smrg{
875f220fa62Smrg  Int ret;
876f220fa62Smrg  FILE* fp = fopen(name, "r");
877f220fa62Smrg  if(fp == NULL)
878f220fa62Smrg    {
879f220fa62Smrg      fprintf(stderr, "can't open file %s\n", name);
880f220fa62Smrg      exit(1);
881f220fa62Smrg    }
882f220fa62Smrg  fscanf(fp, "%i", &ret);
883f220fa62Smrg  fclose(fp);
884f220fa62Smrg  return ret;
885f220fa62Smrg}
886f220fa62Smrg#endif
887f220fa62Smrg
888f220fa62Smrg/***********nextgen tess****************/
889f220fa62Smrg#include "sampleMonoPoly.h"
890f220fa62SmrgdirectedLine* arcToDLine(Arc_ptr arc)
891f220fa62Smrg{
892f220fa62Smrg  int i;
893f220fa62Smrg  Real vert[2];
894f220fa62Smrg  directedLine* ret;
895f220fa62Smrg  sampledLine* sline = new sampledLine(arc->pwlArc->npts);
896f220fa62Smrg  for(i=0; i<arc->pwlArc->npts; i++)
897f220fa62Smrg    {
898f220fa62Smrg      vert[0] = arc->pwlArc->pts[i].param[0];
899f220fa62Smrg      vert[1] = arc->pwlArc->pts[i].param[1];
900f220fa62Smrg      sline->setPoint(i, vert);
901f220fa62Smrg    }
902f220fa62Smrg  ret = new directedLine(INCREASING, sline);
903f220fa62Smrg  return ret;
904f220fa62Smrg}
905f220fa62Smrg
906f220fa62Smrg/*an pwlArc may not be a straight line*/
907f220fa62SmrgdirectedLine* arcToMultDLines(directedLine* original, Arc_ptr arc)
908f220fa62Smrg{
909f220fa62Smrg  directedLine* ret = original;
910f220fa62Smrg  int is_linear = 0;
911f220fa62Smrg  if(arc->pwlArc->npts == 2 )
912f220fa62Smrg    is_linear = 1;
913f220fa62Smrg  else if(area(arc->pwlArc->pts[0].param, arc->pwlArc->pts[1].param, arc->pwlArc->pts[arc->pwlArc->npts-1].param) == 0.0)
914f220fa62Smrg    is_linear = 1;
915f220fa62Smrg
916f220fa62Smrg  if(is_linear)
917f220fa62Smrg    {
918f220fa62Smrg      directedLine *dline = arcToDLine(arc);
919f220fa62Smrg      if(ret == NULL)
920f220fa62Smrg	ret = dline;
921f220fa62Smrg      else
922f220fa62Smrg	ret->insert(dline);
923f220fa62Smrg      return ret;
924f220fa62Smrg    }
925f220fa62Smrg  else /*not linear*/
926f220fa62Smrg    {
927f220fa62Smrg      for(Int i=0; i<arc->pwlArc->npts-1; i++)
928f220fa62Smrg	{
929f220fa62Smrg	  Real vert[2][2];
930f220fa62Smrg	  vert[0][0] = arc->pwlArc->pts[i].param[0];
931f220fa62Smrg	  vert[0][1] = arc->pwlArc->pts[i].param[1];
932f220fa62Smrg	  vert[1][0] = arc->pwlArc->pts[i+1].param[0];
933f220fa62Smrg	  vert[1][1] = arc->pwlArc->pts[i+1].param[1];
934f220fa62Smrg
935f220fa62Smrg	  sampledLine *sline = new sampledLine(2, vert);
936f220fa62Smrg	  directedLine *dline = new directedLine(INCREASING, sline);
937f220fa62Smrg	  if(ret == NULL)
938f220fa62Smrg	    ret = dline;
939f220fa62Smrg	  else
940f220fa62Smrg	    ret->insert(dline);
941f220fa62Smrg	}
942f220fa62Smrg      return ret;
943f220fa62Smrg    }
944f220fa62Smrg}
945f220fa62Smrg
946f220fa62Smrg
947f220fa62Smrg
948f220fa62SmrgdirectedLine* arcLoopToDLineLoop(Arc_ptr loop)
949f220fa62Smrg{
950f220fa62Smrg  directedLine* ret;
951f220fa62Smrg
952f220fa62Smrg  if(loop == NULL)
953f220fa62Smrg    return NULL;
954f220fa62Smrg  ret = arcToMultDLines(NULL, loop);
955f220fa62Smrg//ret->printSingle();
956f220fa62Smrg  for(Arc_ptr temp = loop->next; temp != loop; temp = temp->next){
957f220fa62Smrg    ret = arcToMultDLines(ret, temp);
958f220fa62Smrg//ret->printSingle();
959f220fa62Smrg  }
960f220fa62Smrg
961f220fa62Smrg  return ret;
962f220fa62Smrg}
963f220fa62Smrg
964f220fa62Smrg/*
965f220fa62Smrgvoid Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
966f220fa62Smrg{
967f220fa62Smrg  TrimVertex *trimVert = (TrimVertex*)malloc(sizeof(TrimVertex));
968f220fa62Smrg  trimVert -> nuid = 0;//????
969f220fa62Smrg
970f220fa62Smrg  Real* u_values = grid->get_u_values();
971f220fa62Smrg  Real* v_values = grid->get_v_values();
972f220fa62Smrg
973f220fa62Smrg  Int i,j,k,l;
974f220fa62Smrg
975f220fa62Smrg  for(l=0; l<rbArray->get_n_elements(); l++)
976f220fa62Smrg    {
977f220fa62Smrg      rectBlock* block = rbArray->get_element(l);
978f220fa62Smrg      for(k=0, i=block->get_upGridLineIndex(); i>block->get_lowGridLineIndex(); i--, k++)
979f220fa62Smrg	{
980f220fa62Smrg
981f220fa62Smrg	  backend.bgnqstrip();
982f220fa62Smrg	  for(j=block->get_leftIndices()[k+1]; j<= block->get_rightIndices()[k+1]; j++)
983f220fa62Smrg	    {
984f220fa62Smrg	      trimVert->param[0] = u_values[j];
985f220fa62Smrg	      trimVert->param[1] = v_values[i];
986f220fa62Smrg	      backend.tmeshvert(trimVert);
987f220fa62Smrg
988f220fa62Smrg	      trimVert->param[1] = v_values[i-1];
989f220fa62Smrg	      backend.tmeshvert(trimVert);
990f220fa62Smrg
991f220fa62Smrg	    }
992f220fa62Smrg	  backend.endqstrip();
993f220fa62Smrg
994f220fa62Smrg	}
995f220fa62Smrg    }
996f220fa62Smrg
997f220fa62Smrg  free(trimVert);
998f220fa62Smrg}
999f220fa62Smrg*/
1000f220fa62Smrg
1001f220fa62Smrgvoid Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
1002f220fa62Smrg{
1003f220fa62Smrg  Int i,j,k;
1004f220fa62Smrg
1005f220fa62Smrg  Int n_vlines=grid->get_n_vlines();
1006f220fa62Smrg  //the reason to switch the position of v_max and v_min is because of the
1007f220fa62Smrg  //the orientation problem. glEvalMesh generates quad_strip clockwise, but
1008f220fa62Smrg  //we need counter-clockwise.
1009f220fa62Smrg  backend.surfgrid(grid->get_u_min(), grid->get_u_max(), grid->get_n_ulines()-1,
1010f220fa62Smrg		   grid->get_v_max(), grid->get_v_min(), n_vlines-1);
1011f220fa62Smrg
1012f220fa62Smrg
1013f220fa62Smrg  for(j=0; j<rbArray->get_n_elements(); j++)
1014f220fa62Smrg    {
1015f220fa62Smrg      rectBlock* block = rbArray->get_element(j);
1016f220fa62Smrg      Int low = block->get_lowGridLineIndex();
1017f220fa62Smrg      Int high = block->get_upGridLineIndex();
1018f220fa62Smrg
1019f220fa62Smrg      for(k=0, i=high; i>low; i--, k++)
1020f220fa62Smrg	{
1021f220fa62Smrg	  backend.surfmesh(block->get_leftIndices()[k+1], n_vlines-1-i, block->get_rightIndices()[k+1]-block->get_leftIndices()[k+1], 1);
1022f220fa62Smrg	}
1023f220fa62Smrg    }
1024f220fa62Smrg}
1025f220fa62Smrg
1026f220fa62Smrg
1027f220fa62Smrgvoid Slicer::evalStream(primStream* pStream)
1028f220fa62Smrg{
1029f220fa62Smrg  Int i,j,k;
1030f220fa62Smrg  k=0;
1031f220fa62Smrg/*  TrimVertex X;*/
1032f220fa62Smrg  TrimVertex *trimVert =/*&X*/  (TrimVertex*)malloc(sizeof(TrimVertex));
1033f220fa62Smrg  trimVert -> nuid = 0;//???
1034f220fa62Smrg  Real* vertices = pStream->get_vertices(); //for efficiency
1035f220fa62Smrg  for(i=0; i<pStream->get_n_prims(); i++)
1036f220fa62Smrg    {
1037f220fa62Smrg
1038f220fa62Smrg     //ith primitive  has #vertices = lengths[i], type=types[i]
1039f220fa62Smrg      switch(pStream->get_type(i)){
1040f220fa62Smrg      case PRIMITIVE_STREAM_FAN:
1041f220fa62Smrg
1042f220fa62Smrg	backend.bgntfan();
1043f220fa62Smrg
1044f220fa62Smrg	for(j=0; j<pStream->get_length(i); j++)
1045f220fa62Smrg	  {
1046f220fa62Smrg	    trimVert->param[0] = vertices[k];
1047f220fa62Smrg	    trimVert->param[1] = vertices[k+1];
1048f220fa62Smrg	    backend.tmeshvert(trimVert);
1049f220fa62Smrg
1050f220fa62Smrg//	    backend.tmeshvert(vertices[k], vertices[k+1]);
1051f220fa62Smrg	    k += 2;
1052f220fa62Smrg	  }
1053f220fa62Smrg	backend.endtfan();
1054f220fa62Smrg	break;
1055f220fa62Smrg
1056f220fa62Smrg      default:
1057f220fa62Smrg	fprintf(stderr, "evalStream: not implemented yet\n");
1058f220fa62Smrg	exit(1);
1059f220fa62Smrg
1060f220fa62Smrg      }
1061f220fa62Smrg    }
1062f220fa62Smrg  free(trimVert);
1063f220fa62Smrg}
1064f220fa62Smrg
1065f220fa62Smrg
1066f220fa62Smrg
1067f220fa62Smrg
1068f220fa62Smrgvoid Slicer::slice_new(Arc_ptr loop)
1069f220fa62Smrg{
1070f220fa62Smrg//count++;
1071f220fa62Smrg//if(count == 78) count=1;
1072f220fa62Smrg//printf("count=%i\n", count);
1073f220fa62Smrg//if( ! (4<= count && count <=4)) return;
1074f220fa62Smrg
1075f220fa62Smrg
1076f220fa62Smrg  Int num_ulines;
1077f220fa62Smrg  Int num_vlines;
1078f220fa62Smrg  Real uMin, uMax, vMin, vMax;
1079f220fa62Smrg  Real mydu, mydv;
1080f220fa62Smrg  uMin = uMax = loop->tail()[0];
1081f220fa62Smrg  vMin = vMax = loop->tail()[1];
1082f220fa62Smrg  mydu = (du>0)? du: -du;
1083f220fa62Smrg  mydv = (dv>0)? dv: -dv;
1084f220fa62Smrg
1085f220fa62Smrg  for(Arc_ptr jarc=loop->next; jarc != loop; jarc = jarc->next)
1086f220fa62Smrg   {
1087f220fa62Smrg
1088f220fa62Smrg     if(jarc->tail()[0] < uMin)
1089f220fa62Smrg       uMin = jarc->tail()[0];
1090f220fa62Smrg     if(jarc->tail()[0] > uMax)
1091f220fa62Smrg       uMax = jarc->tail()[0];
1092f220fa62Smrg     if(jarc->tail()[1] < vMin)
1093f220fa62Smrg       vMin = jarc->tail()[1];
1094f220fa62Smrg     if(jarc->tail()[1] > vMax)
1095f220fa62Smrg       vMax = jarc->tail()[1];
1096f220fa62Smrg   }
1097f220fa62Smrg
1098f220fa62Smrg  if (uMax == uMin)
1099f220fa62Smrg    return; // prevent divide-by-zero.  Jon Perry.  17 June 2002
1100f220fa62Smrg
1101f220fa62Smrg  if(mydu > uMax - uMin)
1102f220fa62Smrg    num_ulines = 2;
1103f220fa62Smrg  else
1104f220fa62Smrg    {
1105f220fa62Smrg      num_ulines = 3 + (Int) ((uMax-uMin)/mydu);
1106f220fa62Smrg    }
1107f220fa62Smrg  if(mydv>=vMax-vMin)
1108f220fa62Smrg    num_vlines = 2;
1109f220fa62Smrg  else
1110f220fa62Smrg    {
1111f220fa62Smrg      num_vlines = 2+(Int)((vMax-vMin)/mydv);
1112f220fa62Smrg    }
1113f220fa62Smrg
1114f220fa62Smrg  Int isRect = is_rect(loop);
1115f220fa62Smrg
1116f220fa62Smrg  if(isRect && (num_ulines<=2 || num_vlines<=2))
1117f220fa62Smrg    {
1118f220fa62Smrg      if(vlinear)
1119f220fa62Smrg	triangulateRect(loop, backend, 1, ulinear, vlinear);
1120f220fa62Smrg      else if(ulinear)
1121f220fa62Smrg	triangulateRect(loop, backend, -1, ulinear, vlinear);
1122f220fa62Smrg      else
1123f220fa62Smrg	triangulateRect(loop, backend, 0, ulinear, vlinear);
1124f220fa62Smrg    }
1125f220fa62Smrg
1126f220fa62Smrg   else if(isRect)
1127f220fa62Smrg    {
1128f220fa62Smrg      triangulateRectGen(loop, num_ulines-2, num_vlines-2, backend);
1129f220fa62Smrg    }
1130f220fa62Smrg  else if( (num_ulines<=2 || num_vlines <=2) && ulinear)
1131f220fa62Smrg    {
1132f220fa62Smrg      monoTriangulationFunBackend(loop, compV2InY, &backend);
1133f220fa62Smrg    }
1134f220fa62Smrg  else if( (!ulinear) && (!vlinear) && (num_ulines == 2) && (num_vlines > 2))
1135f220fa62Smrg    {
1136f220fa62Smrg      monoTriangulationFunBackend(loop, compV2InY, &backend);
1137f220fa62Smrg    }
1138f220fa62Smrg  else
1139f220fa62Smrg    {
1140f220fa62Smrg      directedLine* poly = arcLoopToDLineLoop(loop);
1141f220fa62Smrg
1142f220fa62Smrg      gridWrap grid(num_ulines, num_vlines, uMin, uMax, vMin, vMax);
1143f220fa62Smrg      primStream pStream(20, 20);
1144f220fa62Smrg      rectBlockArray rbArray(20);
1145f220fa62Smrg
1146f220fa62Smrg      sampleMonoPoly(poly, &grid, ulinear, vlinear, &pStream, &rbArray);
1147f220fa62Smrg
1148f220fa62Smrg      evalStream(&pStream);
1149f220fa62Smrg
1150f220fa62Smrg      evalRBArray(&rbArray, &grid);
1151f220fa62Smrg
1152f220fa62Smrg#ifdef COUNT_TRIANGLES
1153f220fa62Smrg      num_triangles += pStream.num_triangles();
1154f220fa62Smrg      num_quads += rbArray.num_quads();
1155f220fa62Smrg#endif
1156f220fa62Smrg      poly->deleteSinglePolygonWithSline();
1157f220fa62Smrg    }
1158f220fa62Smrg
1159f220fa62Smrg#ifdef COUNT_TRIANGLES
1160f220fa62Smrg  printf("num_triangles=%i\n", num_triangles);
1161f220fa62Smrg  printf("num_quads = %i\n", num_quads);
1162f220fa62Smrg#endif
1163f220fa62Smrg}
1164f220fa62Smrg
1165f220fa62Smrgvoid Slicer::slice(Arc_ptr loop)
1166f220fa62Smrg{
1167f220fa62Smrg#ifdef USE_READ_FLAG
1168f220fa62Smrg  if(read_flag("flagFile"))
1169f220fa62Smrg    slice_new(loop);
1170f220fa62Smrg  else
1171f220fa62Smrg    slice_old(loop);
1172f220fa62Smrg
1173f220fa62Smrg#else
1174f220fa62Smrg    slice_new(loop);
1175f220fa62Smrg#endif
1176f220fa62Smrg
1177f220fa62Smrg}
1178f220fa62Smrg
1179f220fa62Smrg
1180f220fa62Smrg
1181f220fa62SmrgSlicer::Slicer( Backend &b )
1182f220fa62Smrg	: CoveAndTiler( b ), Mesher( b ), backend( b )
1183f220fa62Smrg{
1184f220fa62Smrg    oneOverDu = 0;
1185f220fa62Smrg    du = 0;
1186f220fa62Smrg    dv = 0;
1187f220fa62Smrg    isolines = 0;
1188f220fa62Smrg    ulinear = 0;
1189f220fa62Smrg    vlinear = 0;
1190f220fa62Smrg}
1191f220fa62Smrg
1192f220fa62SmrgSlicer::~Slicer()
1193f220fa62Smrg{
1194f220fa62Smrg}
1195f220fa62Smrg
1196f220fa62Smrgvoid
1197f220fa62SmrgSlicer::setisolines( int x )
1198f220fa62Smrg{
1199f220fa62Smrg    isolines = x;
1200f220fa62Smrg}
1201f220fa62Smrg
1202f220fa62Smrgvoid
1203f220fa62SmrgSlicer::setstriptessellation( REAL x, REAL y )
1204f220fa62Smrg{
1205f220fa62Smrg    assert(x > 0 && y > 0);
1206f220fa62Smrg    du = x;
1207f220fa62Smrg    dv = y;
1208f220fa62Smrg    setDu( du );
1209f220fa62Smrg}
1210f220fa62Smrg
1211f220fa62Smrgvoid
1212f220fa62SmrgSlicer::slice_old( Arc_ptr loop )
1213f220fa62Smrg{
1214f220fa62Smrg    loop->markverts();
1215f220fa62Smrg
1216f220fa62Smrg    Arc_ptr extrema[4];
1217f220fa62Smrg    loop->getextrema( extrema );
1218f220fa62Smrg
1219f220fa62Smrg    unsigned int npts = loop->numpts();
1220f220fa62Smrg    TrimRegion::init( npts, extrema[0] );
1221f220fa62Smrg
1222f220fa62Smrg    Mesher::init( npts );
1223f220fa62Smrg
1224f220fa62Smrg    long ulines = uarray.init( du, extrema[1], extrema[3] );
1225f220fa62Smrg//printf("ulines = %i\n", ulines);
1226f220fa62Smrg    Varray varray;
1227f220fa62Smrg    long vlines = varray.init( dv, extrema[0], extrema[2] );
1228f220fa62Smrg//printf("vlines = %i\n", vlines);
1229f220fa62Smrg    long botv = 0;
1230f220fa62Smrg    long topv;
1231f220fa62Smrg    TrimRegion::init( varray.varray[botv] );
1232f220fa62Smrg    getGridExtent( &extrema[0]->pwlArc->pts[0], &extrema[0]->pwlArc->pts[0] );
1233f220fa62Smrg
1234f220fa62Smrg    for( long quad=0; quad<varray.numquads; quad++ ) {
1235f220fa62Smrg	backend.surfgrid( uarray.uarray[0],
1236f220fa62Smrg		       uarray.uarray[ulines-1],
1237f220fa62Smrg	 	       ulines-1,
1238f220fa62Smrg		       varray.vval[quad],
1239f220fa62Smrg		       varray.vval[quad+1],
1240f220fa62Smrg		       varray.voffset[quad+1] - varray.voffset[quad] );
1241f220fa62Smrg
1242f220fa62Smrg	for( long i=varray.voffset[quad]+1; i <= varray.voffset[quad+1]; i++ ) {
1243f220fa62Smrg    	    topv = botv++;
1244f220fa62Smrg    	    advance( topv - varray.voffset[quad],
1245f220fa62Smrg		     botv - varray.voffset[quad],
1246f220fa62Smrg		     varray.varray[botv] );
1247f220fa62Smrg	    if( i == vlines )
1248f220fa62Smrg		getPts( extrema[2] );
1249f220fa62Smrg	    else
1250f220fa62Smrg		getPts( backend );
1251f220fa62Smrg	    getGridExtent();
1252f220fa62Smrg            if( isolines ) {
1253f220fa62Smrg	        outline();
1254f220fa62Smrg	    } else {
1255f220fa62Smrg		if( canTile() )
1256f220fa62Smrg		    coveAndTile();
1257f220fa62Smrg		else
1258f220fa62Smrg		    mesh();
1259f220fa62Smrg	    }
1260f220fa62Smrg        }
1261f220fa62Smrg   }
1262f220fa62Smrg}
1263f220fa62Smrg
1264f220fa62Smrg
1265f220fa62Smrgvoid
1266f220fa62SmrgSlicer::outline( void )
1267f220fa62Smrg{
1268f220fa62Smrg    GridTrimVertex upper, lower;
1269f220fa62Smrg    Hull::init( );
1270f220fa62Smrg
1271f220fa62Smrg    backend.bgnoutline();
1272f220fa62Smrg    while( (nextupper( &upper )) ) {
1273f220fa62Smrg	if( upper.isGridVert() )
1274f220fa62Smrg	    backend.linevert( upper.g );
1275f220fa62Smrg	else
1276f220fa62Smrg	    backend.linevert( upper.t );
1277f220fa62Smrg    }
1278f220fa62Smrg    backend.endoutline();
1279f220fa62Smrg
1280f220fa62Smrg    backend.bgnoutline();
1281f220fa62Smrg    while( (nextlower( &lower )) ) {
1282f220fa62Smrg	if( lower.isGridVert() )
1283f220fa62Smrg	    backend.linevert( lower.g );
1284f220fa62Smrg	else
1285f220fa62Smrg	    backend.linevert( lower.t );
1286f220fa62Smrg    }
1287f220fa62Smrg    backend.endoutline();
1288f220fa62Smrg}
1289f220fa62Smrg
1290f220fa62Smrg
1291f220fa62Smrgvoid
1292f220fa62SmrgSlicer::outline( Arc_ptr jarc )
1293f220fa62Smrg{
1294f220fa62Smrg    jarc->markverts();
1295f220fa62Smrg
1296f220fa62Smrg    if( jarc->pwlArc->npts >= 2 ) {
1297f220fa62Smrg	backend.bgnoutline();
1298f220fa62Smrg	for( int j = jarc->pwlArc->npts-1; j >= 0; j--  )
1299f220fa62Smrg	    backend.linevert( &(jarc->pwlArc->pts[j]) );
1300f220fa62Smrg	backend.endoutline();
1301f220fa62Smrg    }
1302f220fa62Smrg}
1303f220fa62Smrg
1304f220fa62Smrg
1305