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