Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenslicer.cc
Go to the documentation of this file.
00001 /* 00002 ** License Applicability. Except to the extent portions of this file are 00003 ** made subject to an alternative license as permitted in the SGI Free 00004 ** Software License B, Version 1.1 (the "License"), the contents of this 00005 ** file are subject only to the provisions of the License. You may not use 00006 ** this file except in compliance with the License. You may obtain a copy 00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 00009 ** 00010 ** http://oss.sgi.com/projects/FreeB 00011 ** 00012 ** Note that, as provided in the License, the Software is distributed on an 00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 00017 ** 00018 ** Original Code. The Original Code is: OpenGL Sample Implementation, 00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 00021 ** Copyright in any portions created by third parties is as indicated 00022 ** elsewhere herein. All Rights Reserved. 00023 ** 00024 ** Additional Notice Provisions: The application programming interfaces 00025 ** established by SGI in conjunction with the Original Code are The 00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software 00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation 00031 ** published by SGI, but has not been independently verified as being 00032 ** compliant with the OpenGL(R) version 1.2.1 Specification. 00033 */ 00034 00035 /* 00036 * slicer.c++ 00037 * 00038 * $Date: 2006-03-12 00:07:02 +0000 (Sun, 12 Mar 2006) $ $Revision: 1.1 $ 00039 * $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/internals/slicer.cc,v 1.1 2004/02/02 16:39:12 navaraf Exp $ 00040 */ 00041 00042 #include <stdlib.h> 00043 #include <stdio.h> 00044 #include <math.h> 00045 #include "glimports.h" 00046 #include "mystdio.h" 00047 #include "myassert.h" 00048 #include "bufpool.h" 00049 #include "slicer.h" 00050 #include "backend.h" 00051 #include "arc.h" 00052 #include "gridtrimvertex.h" 00053 #include "simplemath.h" 00054 #include "trimvertex.h" 00055 #include "varray.h" 00056 00057 #include "polyUtil.h" //for area() 00058 00059 //static int count=0; 00060 00061 /*USE_OPTTT is initiated in trimvertex.h*/ 00062 00063 #ifdef USE_OPTTT 00064 #include <GL/gl.h> 00065 #endif 00066 00067 //#define USE_READ_FLAG //whether to use new or old tesselator 00068 //if defined, it reads "flagFile", 00069 // if the number is 1, then use new tess 00070 // otherwise, use the old tess. 00071 //if not defined, then use new tess. 00072 #ifdef USE_READ_FLAG 00073 static Int read_flag(char* name); 00074 Int newtess_flag = read_flag("flagFile"); 00075 #endif 00076 00077 //#define COUNT_TRIANGLES 00078 #ifdef COUNT_TRIANGLES 00079 Int num_triangles = 0; 00080 Int num_quads = 0; 00081 #endif 00082 00083 #define max(a,b) ((a>b)? a:b) 00084 #define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/ 00085 #define equalRect(a,b) ((glu_abs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle 00086 00087 /******triangulate a monotone polygon**************/ 00088 #include "monoTriangulation.h" 00089 00090 inline int compInY(REAL a[2], REAL b[2]) 00091 { 00092 if(a[1] < b[1]) 00093 return -1; 00094 else if (a[1] > b[1]) 00095 return 1; 00096 else if(a[0] > b[0]) 00097 return 1; 00098 else return -1; 00099 } 00100 00101 void monoTriangulationLoop(Arc_ptr loop, Backend& backend, primStream* pStream) 00102 { 00103 int i; 00104 //find the top, bottom, increasing and decreasing chain 00105 //then call monoTrianulation 00106 Arc_ptr jarc, temp; 00107 Arc_ptr top; 00108 Arc_ptr bot; 00109 top = bot = loop; 00110 if(compInY(loop->tail(), loop->prev->tail()) < 0) 00111 { 00112 //first find bot 00113 for(temp = loop->next; temp != loop; temp = temp->next) 00114 { 00115 if(compInY(temp->tail(), temp->prev->tail()) > 0) 00116 break; 00117 } 00118 bot = temp->prev; 00119 //then find top 00120 for(temp=loop->prev; temp != loop; temp = temp->prev) 00121 { 00122 if(compInY(temp->tail(), temp->prev->tail()) > 0) 00123 break; 00124 } 00125 top = temp; 00126 } 00127 else //loop > loop->prev 00128 { 00129 for(temp=loop->next; temp != loop; temp = temp->next) 00130 { 00131 if(compInY(temp->tail(), temp->prev->tail()) < 0) 00132 break; 00133 } 00134 top = temp->prev; 00135 for(temp=loop->prev; temp != loop; temp = temp->prev) 00136 { 00137 if(compInY(temp->tail(), temp->prev->tail()) < 0) 00138 break; 00139 } 00140 bot = temp; 00141 } 00142 //creat increase and decrease chains 00143 vertexArray inc_chain(50); //this is a dynamci array 00144 for(i=1; i<=top->pwlArc->npts-2; i++) 00145 { 00146 //the first vertex is the top which doesn't below to inc_chain 00147 inc_chain.appendVertex(top->pwlArc->pts[i].param); 00148 } 00149 for(jarc=top->next; jarc != bot; jarc = jarc->next) 00150 { 00151 for(i=0; i<=jarc->pwlArc->npts-2; i++) 00152 { 00153 inc_chain.appendVertex(jarc->pwlArc->pts[i].param); 00154 } 00155 00156 } 00157 vertexArray dec_chain(50); 00158 for(jarc = top->prev; jarc != bot; jarc = jarc->prev) 00159 { 00160 for(i=jarc->pwlArc->npts-2; i>=0; i--) 00161 { 00162 dec_chain.appendVertex(jarc->pwlArc->pts[i].param); 00163 } 00164 } 00165 for(i=bot->pwlArc->npts-2; i>=1; i--) 00166 { 00167 dec_chain.appendVertex(jarc->pwlArc->pts[i].param); 00168 } 00169 00170 monoTriangulationRec(top->tail(), bot->tail(), &inc_chain, 0, 00171 &dec_chain, 0, &backend); 00172 00173 } 00174 00175 /********tesselate a rectanlge (OPTIMIZATION**************/ 00176 static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend); 00177 00178 static Int is_rect(Arc_ptr loop) 00179 { 00180 Int nlines =1; 00181 for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next) 00182 { 00183 nlines++; 00184 if(nlines == 5) 00185 break; 00186 } 00187 if(nlines != 4) 00188 return 0; 00189 00190 00191 /* 00192 printf("here1\n"); 00193 printf("loop->tail=(%f,%f)\n", loop->tail()[0], loop->tail()[1]); 00194 printf("loop->head=(%f,%f)\n", loop->head()[0], loop->head()[1]); 00195 printf("loop->next->tail=(%f,%f)\n", loop->next->tail()[0], loop->next->tail()[1]); 00196 printf("loop->next->head=(%f,%f)\n", loop->next->head()[0], loop->next->head()[1]); 00197 if(fglu_abs(loop->tail()[0] - loop->head()[0])<0.000001) 00198 printf("equal 1\n"); 00199 if(loop->next->tail()[1] == loop->next->head()[1]) 00200 printf("equal 2\n"); 00201 */ 00202 00203 if( (glu_abs(loop->tail()[0] - loop->head()[0])<=ZERO) && 00204 (glu_abs(loop->next->tail()[1] - loop->next->head()[1])<=ZERO) && 00205 (glu_abs(loop->prev->tail()[1] - loop->prev->head()[1])<=ZERO) && 00206 (glu_abs(loop->prev->prev->tail()[0] - loop->prev->prev->head()[0])<=ZERO) 00207 ) 00208 return 1; 00209 else if 00210 ( (glu_abs(loop->tail()[1] - loop->head()[1]) <= ZERO) && 00211 (glu_abs(loop->next->tail()[0] - loop->next->head()[0]) <= ZERO) && 00212 (glu_abs(loop->prev->tail()[0] - loop->prev->head()[0]) <= ZERO) && 00213 (glu_abs(loop->prev->prev->tail()[1] - loop->prev->prev->head()[1]) <= ZERO) 00214 ) 00215 return 1; 00216 else 00217 return 0; 00218 } 00219 00220 inline void OPT_OUTVERT(TrimVertex& vv, Backend& backend) 00221 { 00222 00223 #ifdef USE_OPTTT 00224 glNormal3fv(vv.cache_normal); 00225 glVertex3fv(vv.cache_point); 00226 #else 00227 00228 backend.tmeshvert(&vv); 00229 00230 #endif 00231 00232 } 00233 00234 static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend); 00235 00236 static void triangulateRect(Arc_ptr loop, Backend& backend, int TB_or_LR, int ulinear, int vlinear) 00237 { 00238 //we know the loop is a rectangle, but not sure which is top 00239 Arc_ptr top, bot, left, right; 00240 if(loop->tail()[1] == loop->head()[1]) 00241 { 00242 if(loop->tail()[1] > loop->prev->prev->tail()[1]) 00243 { 00244 00245 top = loop; 00246 } 00247 else{ 00248 00249 top = loop->prev->prev; 00250 } 00251 } 00252 else 00253 { 00254 if(loop->tail()[0] > loop->prev->prev->tail()[0]) 00255 { 00256 //loop is the right arc 00257 00258 top = loop->next; 00259 } 00260 else 00261 { 00262 00263 top = loop->prev; 00264 } 00265 } 00266 left = top->next; 00267 bot = left->next; 00268 right= bot->next; 00269 00270 //if u, v are both nonlinear, then if the 00271 //boundary is tessellated dense, we also 00272 //sample the inside to get a better tesslletant. 00273 if( (!ulinear) && (!vlinear)) 00274 { 00275 int nu = top->pwlArc->npts; 00276 if(nu < bot->pwlArc->npts) 00277 nu = bot->pwlArc->npts; 00278 int nv = left->pwlArc->npts; 00279 if(nv < right->pwlArc->npts) 00280 nv = right->pwlArc->npts; 00281 /* 00282 if(nu > 2 && nv > 2) 00283 { 00284 triangulateRectGen(top, nu-2, nv-2, backend); 00285 return; 00286 } 00287 */ 00288 } 00289 00290 if(TB_or_LR == 1) 00291 triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend); 00292 else if(TB_or_LR == -1) 00293 triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend); 00294 else 00295 { 00296 Int maxPointsTB = top->pwlArc->npts + bot->pwlArc->npts; 00297 Int maxPointsLR = left->pwlArc->npts + right->pwlArc->npts; 00298 00299 if(maxPointsTB < maxPointsLR) 00300 triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend); 00301 else 00302 triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend); 00303 } 00304 } 00305 00306 static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend) 00307 { //if(maxPointsTB >= maxPointsLR) 00308 { 00309 00310 Int d, topd_left, topd_right, botd_left, botd_right, i,j; 00311 d = left->npts /2; 00312 00313 #ifdef USE_OPTTT 00314 evalLineNOGE(top->pts, top->npts, backend); 00315 evalLineNOGE(bot->pts, bot->npts, backend); 00316 evalLineNOGE(left->pts, left->npts, backend); 00317 evalLineNOGE(right->pts, right->npts, backend); 00318 #endif 00319 00320 if(top->npts == 2) { 00321 backend.bgntfan(); 00322 OPT_OUTVERT(top->pts[0], backend);//the root 00323 for(i=0; i<left->npts; i++){ 00324 OPT_OUTVERT(left->pts[i], backend); 00325 } 00326 for(i=1; i<= bot->npts-2; i++){ 00327 OPT_OUTVERT(bot->pts[i], backend); 00328 } 00329 backend.endtfan(); 00330 00331 backend.bgntfan(); 00332 OPT_OUTVERT(bot->pts[bot->npts-2], backend); 00333 for(i=0; i<right->npts; i++){ 00334 OPT_OUTVERT(right->pts[i], backend); 00335 } 00336 backend.endtfan(); 00337 } 00338 else if(bot->npts == 2) { 00339 backend.bgntfan(); 00340 OPT_OUTVERT(bot->pts[0], backend);//the root 00341 for(i=0; i<right->npts; i++){ 00342 OPT_OUTVERT(right->pts[i], backend); 00343 } 00344 for(i=1; i<= top->npts-2; i++){ 00345 OPT_OUTVERT(top->pts[i], backend); 00346 } 00347 backend.endtfan(); 00348 00349 backend.bgntfan(); 00350 OPT_OUTVERT(top->pts[top->npts-2], backend); 00351 for(i=0; i<left->npts; i++){ 00352 OPT_OUTVERT(left->pts[i], backend); 00353 } 00354 backend.endtfan(); 00355 } 00356 else { //both top and bot have >=3 points 00357 00358 backend.bgntfan(); 00359 00360 OPT_OUTVERT(top->pts[top->npts-2], backend); 00361 00362 for(i=0; i<=d; i++) 00363 { 00364 OPT_OUTVERT(left->pts[i], backend); 00365 } 00366 backend.endtfan(); 00367 00368 backend.bgntfan(); 00369 00370 OPT_OUTVERT(bot->pts[1], backend); 00371 00372 OPT_OUTVERT(top->pts[top->npts-2], backend); 00373 00374 for(i=d; i< left->npts; i++) 00375 { 00376 OPT_OUTVERT(left->pts[i], backend); 00377 } 00378 backend.endtfan(); 00379 00380 d = right->npts/2; 00381 //output only when d<right->npts-1 and 00382 // 00383 if(d<right->npts-1) 00384 { 00385 backend.bgntfan(); 00386 // backend.tmeshvert(& top->pts[1]); 00387 OPT_OUTVERT(top->pts[1], backend); 00388 for(i=d; i< right->npts; i++) 00389 { 00390 // backend.tmeshvert(& right->pts[i]); 00391 00392 OPT_OUTVERT(right->pts[i], backend); 00393 00394 } 00395 backend.endtfan(); 00396 } 00397 00398 backend.bgntfan(); 00399 // backend.tmeshvert(& bot->pts[bot->npts-2]); 00400 OPT_OUTVERT( bot->pts[bot->npts-2], backend); 00401 for(i=0; i<=d; i++) 00402 { 00403 // backend.tmeshvert(& right->pts[i]); 00404 OPT_OUTVERT(right->pts[i], backend); 00405 00406 } 00407 00408 // backend.tmeshvert(& top->pts[1]); 00409 OPT_OUTVERT(top->pts[1], backend); 00410 00411 backend.endtfan(); 00412 00413 00414 topd_left = top->npts-2; 00415 topd_right = 1; //topd_left>= topd_right 00416 00417 botd_left = 1; 00418 botd_right = bot->npts-2; //botd_left<= bot_dright 00419 00420 00421 if(top->npts < bot->npts) 00422 { 00423 int delta=bot->npts - top->npts; 00424 int u = delta/2; 00425 botd_left = 1+ u; 00426 botd_right = bot->npts-2-( delta-u); 00427 00428 if(botd_left >1) 00429 { 00430 backend.bgntfan(); 00431 // backend.tmeshvert(& top->pts[top->npts-2]); 00432 OPT_OUTVERT(top->pts[top->npts-2], backend); 00433 for(i=1; i<= botd_left; i++) 00434 { 00435 // backend.tmeshvert(& bot->pts[i]); 00436 OPT_OUTVERT(bot->pts[i] , backend); 00437 } 00438 backend.endtfan(); 00439 } 00440 if(botd_right < bot->npts-2) 00441 { 00442 backend.bgntfan(); 00443 OPT_OUTVERT(top->pts[1], backend); 00444 for(i=botd_right; i<= bot->npts-2; i++) 00445 OPT_OUTVERT(bot->pts[i], backend); 00446 backend.endtfan(); 00447 } 00448 } 00449 else if(top->npts> bot->npts) 00450 { 00451 int delta=top->npts-bot->npts; 00452 int u = delta/2; 00453 topd_left = top->npts-2 - u; 00454 topd_right = 1+delta-u; 00455 00456 if(topd_left < top->npts-2) 00457 { 00458 backend.bgntfan(); 00459 // backend.tmeshvert(& bot->pts[1]); 00460 OPT_OUTVERT(bot->pts[1], backend); 00461 for(i=topd_left; i<= top->npts-2; i++) 00462 { 00463 // backend.tmeshvert(& top->pts[i]); 00464 OPT_OUTVERT(top->pts[i], backend); 00465 } 00466 backend.endtfan(); 00467 } 00468 if(topd_right > 1) 00469 { 00470 backend.bgntfan(); 00471 OPT_OUTVERT(bot->pts[bot->npts-2], backend); 00472 for(i=1; i<= topd_right; i++) 00473 OPT_OUTVERT(top->pts[i], backend); 00474 backend.endtfan(); 00475 } 00476 } 00477 00478 if(topd_left <= topd_right) 00479 return; 00480 00481 backend.bgnqstrip(); 00482 for(j=botd_left, i=topd_left; i>=topd_right; i--,j++) 00483 { 00484 // backend.tmeshvert(& top->pts[i]); 00485 // backend.tmeshvert(& bot->pts[j]); 00486 OPT_OUTVERT(top->pts[i], backend); 00487 OPT_OUTVERT(bot->pts[j], backend); 00488 } 00489 backend.endqstrip(); 00490 00491 } 00492 } 00493 } 00494 00495 00496 static void triangulateRectCenter(int n_ulines, REAL* u_val, 00497 int n_vlines, REAL* v_val, 00498 Backend& backend) 00499 { 00500 00501 // XXX this code was patched by Diego Santa Cruz <Diego.SantaCruz@epfl.ch> 00502 // to fix a problem in which glMapGrid2f() was called with bad parameters. 00503 // This has beens submitted to SGI but not integrated as of May 1, 2001. 00504 if(n_ulines>1 && n_vlines>1) { 00505 backend.surfgrid(u_val[0], u_val[n_ulines-1], n_ulines-1, 00506 v_val[n_vlines-1], v_val[0], n_vlines-1); 00507 backend.surfmesh(0,0,n_ulines-1,n_vlines-1); 00508 } 00509 00510 return; 00511 00512 /* 00513 for(i=0; i<n_vlines-1; i++) 00514 { 00515 00516 backend.bgnqstrip(); 00517 for(j=0; j<n_ulines; j++) 00518 { 00519 trimVert.param[0] = u_val[j]; 00520 trimVert.param[1] = v_val[i+1]; 00521 backend.tmeshvert(& trimVert); 00522 00523 trimVert.param[1] = v_val[i]; 00524 backend.tmeshvert(& trimVert); 00525 } 00526 backend.endqstrip(); 00527 00528 } 00529 */ 00530 } 00531 00532 //it works for top, bot, left ad right, you need ot select correct arguments 00533 static void triangulateRectTopGen(Arc_ptr arc, int n_ulines, REAL* u_val, Real v, int dir, int is_u, Backend& backend) 00534 { 00535 00536 if(is_u) 00537 { 00538 int i,k; 00539 REAL* upper_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts); 00540 assert(upper_val); 00541 if(dir) 00542 { 00543 for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++) 00544 { 00545 upper_val[k] = arc->pwlArc->pts[i].param[0]; 00546 } 00547 backend.evalUStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], 00548 upper_val, 00549 n_ulines, v, u_val); 00550 } 00551 else 00552 { 00553 for(k=0,i=0; i<arc->pwlArc->npts; i++,k++) 00554 { 00555 upper_val[k] = arc->pwlArc->pts[i].param[0]; 00556 00557 } 00558 00559 backend.evalUStrip( 00560 n_ulines, v, u_val, 00561 arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], upper_val 00562 ); 00563 } 00564 00565 free(upper_val); 00566 return; 00567 } 00568 else //is_v 00569 { 00570 int i,k; 00571 REAL* left_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts); 00572 assert(left_val); 00573 if(dir) 00574 { 00575 for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++) 00576 { 00577 left_val[k] = arc->pwlArc->pts[i].param[1]; 00578 } 00579 backend.evalVStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], 00580 left_val, 00581 n_ulines, v, u_val); 00582 } 00583 else 00584 { 00585 for(k=0,i=0; i<arc->pwlArc->npts; i++,k++) 00586 { 00587 left_val[k] = arc->pwlArc->pts[i].param[1]; 00588 } 00589 backend.evalVStrip( 00590 n_ulines, v, u_val, 00591 arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], left_val 00592 ); 00593 } 00594 free(left_val); 00595 return; 00596 } 00597 00598 //the following is a different version of the above code. If you comment 00599 //the above code, the following code will still work. The reason to leave 00600 //the folliwng code here is purely for testing purpose. 00601 /* 00602 int i,j; 00603 PwlArc* parc = arc->pwlArc; 00604 int d1 = parc->npts-1; 00605 int d2 = 0; 00606 TrimVertex trimVert; 00607 trimVert.nuid = 0;//???? 00608 REAL* temp_u_val = u_val; 00609 if(dir ==0) //have to reverse u_val 00610 { 00611 temp_u_val = (REAL*) malloc(sizeof(REAL) * n_ulines); 00612 assert(temp_u_val); 00613 for(i=0; i<n_ulines; i++) 00614 temp_u_val[i] = u_val[n_ulines-1-i]; 00615 } 00616 u_val = temp_u_val; 00617 00618 if(parc->npts > n_ulines) 00619 { 00620 d1 = n_ulines-1; 00621 00622 backend.bgntfan(); 00623 if(is_u){ 00624 trimVert.param[0] = u_val[0]; 00625 trimVert.param[1] = v; 00626 } 00627 else 00628 { 00629 trimVert.param[1] = u_val[0]; 00630 trimVert.param[0] = v; 00631 } 00632 00633 backend.tmeshvert(& trimVert); 00634 for(i=d1; i< parc->npts; i++) 00635 backend.tmeshvert(& parc->pts[i]); 00636 backend.endtfan(); 00637 00638 00639 } 00640 else if(parc->npts < n_ulines) 00641 { 00642 d2 = n_ulines-parc->npts; 00643 00644 00645 backend.bgntfan(); 00646 backend.tmeshvert(& parc->pts[parc->npts-1]); 00647 for(i=0; i<= d2; i++) 00648 { 00649 if(is_u){ 00650 trimVert.param[0] = u_val[i]; 00651 trimVert.param[1] = v; 00652 } 00653 else 00654 { 00655 trimVert.param[1] = u_val[i]; 00656 trimVert.param[0] = v; 00657 } 00658 backend.tmeshvert(&trimVert); 00659 } 00660 backend.endtfan(); 00661 00662 } 00663 if(d1>0){ 00664 00665 00666 backend.bgnqstrip(); 00667 for(i=d1, j=d2; i>=0; i--, j++) 00668 { 00669 backend.tmeshvert(& parc->pts[i]); 00670 00671 if(is_u){ 00672 trimVert.param[0] = u_val[j]; 00673 trimVert.param[1] = v; 00674 } 00675 else{ 00676 trimVert.param[1] = u_val[j]; 00677 trimVert.param[0] = v; 00678 } 00679 backend.tmeshvert(&trimVert); 00680 00681 00682 00683 } 00684 backend.endqstrip(); 00685 00686 00687 } 00688 if(dir == 0) //temp_u_val was mallocated 00689 free(temp_u_val); 00690 */ 00691 } 00692 00693 //n_ulines is the number of ulines inside, and n_vlines is the number of vlines 00694 //inside, different from meanings elsewhere!!! 00695 static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend) 00696 { 00697 00698 int i; 00699 //we know the loop is a rectangle, but not sure which is top 00700 Arc_ptr top, bot, left, right; 00701 00702 if(equalRect(loop->tail()[1] , loop->head()[1])) 00703 { 00704 00705 if(loop->tail()[1] > loop->prev->prev->tail()[1]) 00706 { 00707 00708 top = loop; 00709 } 00710 else{ 00711 00712 top = loop->prev->prev; 00713 } 00714 } 00715 else 00716 { 00717 if(loop->tail()[0] > loop->prev->prev->tail()[0]) 00718 { 00719 //loop is the right arc 00720 00721 top = loop->next; 00722 } 00723 else 00724 { 00725 00726 top = loop->prev; 00727 } 00728 } 00729 00730 left = top->next; 00731 bot = left->next; 00732 right= bot->next; 00733 00734 #ifdef COUNT_TRIANGLES 00735 num_triangles += loop->pwlArc->npts + 00736 left->pwlArc->npts + 00737 bot->pwlArc->npts + 00738 right->pwlArc->npts 00739 + 2*n_ulines + 2*n_vlines 00740 -8; 00741 num_quads += (n_ulines-1)*(n_vlines-1); 00742 #endif 00743 /* 00744 backend.surfgrid(left->tail()[0], right->tail()[0], n_ulines+1, 00745 top->tail()[1], bot->tail()[1], n_vlines+1); 00746 // if(n_ulines>1 && n_vlines>1) 00747 backend.surfmesh(0,0,n_ulines+1,n_vlines+1); 00748 return; 00749 */ 00750 REAL* u_val=(REAL*) malloc(sizeof(REAL)*n_ulines); 00751 assert(u_val); 00752 REAL* v_val=(REAL*)malloc(sizeof(REAL) * n_vlines); 00753 assert(v_val); 00754 REAL u_stepsize = (right->tail()[0] - left->tail()[0])/( (REAL) n_ulines+1); 00755 REAL v_stepsize = (top->tail()[1] - bot->tail()[1])/( (REAL) n_vlines+1); 00756 Real temp=left->tail()[0]+u_stepsize; 00757 for(i=0; i<n_ulines; i++) 00758 { 00759 u_val[i] = temp; 00760 temp += u_stepsize; 00761 } 00762 temp = bot->tail()[1] + v_stepsize; 00763 for(i=0; i<n_vlines; i++) 00764 { 00765 v_val[i] = temp; 00766 temp += v_stepsize; 00767 } 00768 00769 triangulateRectTopGen(top, n_ulines, u_val, v_val[n_vlines-1], 1,1, backend); 00770 triangulateRectTopGen(bot, n_ulines, u_val, v_val[0], 0, 1, backend); 00771 triangulateRectTopGen(left, n_vlines, v_val, u_val[0], 1, 0, backend); 00772 triangulateRectTopGen(right, n_vlines, v_val, u_val[n_ulines-1], 0,0, backend); 00773 00774 00775 00776 00777 //triangulate the center 00778 triangulateRectCenter(n_ulines, u_val, n_vlines, v_val, backend); 00779 00780 free(u_val); 00781 free(v_val); 00782 00783 } 00784 00785 /***********nextgen tess****************/ 00786 #include "sampleMonoPoly.h" 00787 directedLine* arcToDLine(Arc_ptr arc) 00788 { 00789 int i; 00790 Real vert[2]; 00791 directedLine* ret; 00792 sampledLine* sline = new sampledLine(arc->pwlArc->npts); 00793 for(i=0; i<arc->pwlArc->npts; i++) 00794 { 00795 vert[0] = arc->pwlArc->pts[i].param[0]; 00796 vert[1] = arc->pwlArc->pts[i].param[1]; 00797 sline->setPoint(i, vert); 00798 } 00799 ret = new directedLine(INCREASING, sline); 00800 return ret; 00801 } 00802 00803 /*an pwlArc may not be a straight line*/ 00804 directedLine* arcToMultDLines(directedLine* original, Arc_ptr arc) 00805 { 00806 directedLine* ret = original; 00807 int is_linear = 0; 00808 if(arc->pwlArc->npts == 2 ) 00809 is_linear = 1; 00810 else if(area(arc->pwlArc->pts[0].param, arc->pwlArc->pts[1].param, arc->pwlArc->pts[arc->pwlArc->npts-1].param) == 0.0) 00811 is_linear = 1; 00812 00813 if(is_linear) 00814 { 00815 directedLine *dline = arcToDLine(arc); 00816 if(ret == NULL) 00817 ret = dline; 00818 else 00819 ret->insert(dline); 00820 return ret; 00821 } 00822 else /*not linear*/ 00823 { 00824 for(Int i=0; i<arc->pwlArc->npts-1; i++) 00825 { 00826 Real vert[2][2]; 00827 vert[0][0] = arc->pwlArc->pts[i].param[0]; 00828 vert[0][1] = arc->pwlArc->pts[i].param[1]; 00829 vert[1][0] = arc->pwlArc->pts[i+1].param[0]; 00830 vert[1][1] = arc->pwlArc->pts[i+1].param[1]; 00831 00832 sampledLine *sline = new sampledLine(2, vert); 00833 directedLine *dline = new directedLine(INCREASING, sline); 00834 if(ret == NULL) 00835 ret = dline; 00836 else 00837 ret->insert(dline); 00838 } 00839 return ret; 00840 } 00841 } 00842 00843 00844 00845 directedLine* arcLoopToDLineLoop(Arc_ptr loop) 00846 { 00847 directedLine* ret; 00848 00849 if(loop == NULL) 00850 return NULL; 00851 ret = arcToMultDLines(NULL, loop); 00852 //ret->printSingle(); 00853 for(Arc_ptr temp = loop->next; temp != loop; temp = temp->next){ 00854 ret = arcToMultDLines(ret, temp); 00855 //ret->printSingle(); 00856 } 00857 00858 return ret; 00859 } 00860 00861 /* 00862 void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid) 00863 { 00864 TrimVertex *trimVert = (TrimVertex*)malloc(sizeof(TrimVertex)); 00865 trimVert -> nuid = 0;//???? 00866 00867 Real* u_values = grid->get_u_values(); 00868 Real* v_values = grid->get_v_values(); 00869 00870 Int i,j,k,l; 00871 00872 for(l=0; l<rbArray->get_n_elements(); l++) 00873 { 00874 rectBlock* block = rbArray->get_element(l); 00875 for(k=0, i=block->get_upGridLineIndex(); i>block->get_lowGridLineIndex(); i--, k++) 00876 { 00877 00878 backend.bgnqstrip(); 00879 for(j=block->get_leftIndices()[k+1]; j<= block->get_rightIndices()[k+1]; j++) 00880 { 00881 trimVert->param[0] = u_values[j]; 00882 trimVert->param[1] = v_values[i]; 00883 backend.tmeshvert(trimVert); 00884 00885 trimVert->param[1] = v_values[i-1]; 00886 backend.tmeshvert(trimVert); 00887 00888 } 00889 backend.endqstrip(); 00890 00891 } 00892 } 00893 00894 free(trimVert); 00895 } 00896 */ 00897 00898 void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid) 00899 { 00900 Int i,j,k; 00901 00902 Int n_vlines=grid->get_n_vlines(); 00903 //the reason to switch the position of v_max and v_min is because of the 00904 //the orientation problem. glEvalMesh generates quad_strip clockwise, but 00905 //we need counter-clockwise. 00906 backend.surfgrid(grid->get_u_min(), grid->get_u_max(), grid->get_n_ulines()-1, 00907 grid->get_v_max(), grid->get_v_min(), n_vlines-1); 00908 00909 00910 for(j=0; j<rbArray->get_n_elements(); j++) 00911 { 00912 rectBlock* block = rbArray->get_element(j); 00913 Int low = block->get_lowGridLineIndex(); 00914 Int high = block->get_upGridLineIndex(); 00915 00916 for(k=0, i=high; i>low; i--, k++) 00917 { 00918 backend.surfmesh(block->get_leftIndices()[k+1], n_vlines-1-i, block->get_rightIndices()[k+1]-block->get_leftIndices()[k+1], 1); 00919 } 00920 } 00921 } 00922 00923 00924 void Slicer::evalStream(primStream* pStream) 00925 { 00926 Int i,j,k; 00927 k=0; 00928 /* TrimVertex X;*/ 00929 TrimVertex *trimVert =/*&X*/ (TrimVertex*)malloc(sizeof(TrimVertex)); 00930 trimVert -> nuid = 0;//??? 00931 Real* vertices = pStream->get_vertices(); //for efficiency 00932 for(i=0; i<pStream->get_n_prims(); i++) 00933 { 00934 00935 //ith primitive has #vertices = lengths[i], type=types[i] 00936 switch(pStream->get_type(i)){ 00937 case PRIMITIVE_STREAM_FAN: 00938 00939 backend.bgntfan(); 00940 00941 for(j=0; j<pStream->get_length(i); j++) 00942 { 00943 trimVert->param[0] = vertices[k]; 00944 trimVert->param[1] = vertices[k+1]; 00945 backend.tmeshvert(trimVert); 00946 00947 // backend.tmeshvert(vertices[k], vertices[k+1]); 00948 k += 2; 00949 } 00950 backend.endtfan(); 00951 break; 00952 00953 default: 00954 fprintf(stderr, "evalStream: not implemented yet\n"); 00955 exit(1); 00956 00957 } 00958 } 00959 free(trimVert); 00960 } 00961 00962 00963 00964 00965 void Slicer::slice_new(Arc_ptr loop) 00966 { 00967 //count++; 00968 //if(count == 78) count=1; 00969 //printf("count=%i\n", count); 00970 //if( ! (4<= count && count <=4)) return; 00971 00972 00973 Int num_ulines; 00974 Int num_vlines; 00975 Real uMin, uMax, vMin, vMax; 00976 Real mydu, mydv; 00977 uMin = uMax = loop->tail()[0]; 00978 vMin = vMax = loop->tail()[1]; 00979 mydu = (du>0)? du: -du; 00980 mydv = (dv>0)? dv: -dv; 00981 00982 for(Arc_ptr jarc=loop->next; jarc != loop; jarc = jarc->next) 00983 { 00984 00985 if(jarc->tail()[0] < uMin) 00986 uMin = jarc->tail()[0]; 00987 if(jarc->tail()[0] > uMax) 00988 uMax = jarc->tail()[0]; 00989 if(jarc->tail()[1] < vMin) 00990 vMin = jarc->tail()[1]; 00991 if(jarc->tail()[1] > vMax) 00992 vMax = jarc->tail()[1]; 00993 } 00994 00995 if (uMax == uMin) 00996 return; // prevent divide-by-zero. Jon Perry. 17 June 2002 00997 00998 if(mydu > uMax - uMin) 00999 num_ulines = 2; 01000 else 01001 { 01002 num_ulines = 3 + (Int) ((uMax-uMin)/mydu); 01003 } 01004 if(mydv>=vMax-vMin) 01005 num_vlines = 2; 01006 else 01007 { 01008 num_vlines = 2+(Int)((vMax-vMin)/mydv); 01009 } 01010 01011 Int isRect = is_rect(loop); 01012 01013 if(isRect && (num_ulines<=2 || num_vlines<=2)) 01014 { 01015 if(vlinear) 01016 triangulateRect(loop, backend, 1, ulinear, vlinear); 01017 else if(ulinear) 01018 triangulateRect(loop, backend, -1, ulinear, vlinear); 01019 else 01020 triangulateRect(loop, backend, 0, ulinear, vlinear); 01021 } 01022 01023 else if(isRect) 01024 { 01025 triangulateRectGen(loop, num_ulines-2, num_vlines-2, backend); 01026 } 01027 else if( (num_ulines<=2 || num_vlines <=2) && ulinear) 01028 { 01029 monoTriangulationFunBackend(loop, compV2InY, &backend); 01030 } 01031 else if( (!ulinear) && (!vlinear) && (num_ulines == 2) && (num_vlines > 2)) 01032 { 01033 monoTriangulationFunBackend(loop, compV2InY, &backend); 01034 } 01035 else 01036 { 01037 directedLine* poly = arcLoopToDLineLoop(loop); 01038 01039 gridWrap grid(num_ulines, num_vlines, uMin, uMax, vMin, vMax); 01040 primStream pStream(20, 20); 01041 rectBlockArray rbArray(20); 01042 01043 sampleMonoPoly(poly, &grid, ulinear, vlinear, &pStream, &rbArray); 01044 01045 evalStream(&pStream); 01046 01047 evalRBArray(&rbArray, &grid); 01048 01049 #ifdef COUNT_TRIANGLES 01050 num_triangles += pStream.num_triangles(); 01051 num_quads += rbArray.num_quads(); 01052 #endif 01053 poly->deleteSinglePolygonWithSline(); 01054 } 01055 01056 #ifdef COUNT_TRIANGLES 01057 printf("num_triangles=%i\n", num_triangles); 01058 printf("num_quads = %i\n", num_quads); 01059 #endif 01060 } 01061 01062 void Slicer::slice(Arc_ptr loop) 01063 { 01064 #ifdef USE_READ_FLAG 01065 if(read_flag("flagFile")) 01066 slice_new(loop); 01067 else 01068 slice_old(loop); 01069 01070 #else 01071 slice_new(loop); 01072 #endif 01073 01074 } 01075 01076 01077 01078 Slicer::Slicer( Backend &b ) 01079 : CoveAndTiler( b ), Mesher( b ), backend( b ) 01080 { 01081 ulinear = 0; 01082 vlinear = 0; 01083 } 01084 01085 Slicer::~Slicer() 01086 { 01087 } 01088 01089 void 01090 Slicer::setisolines( int x ) 01091 { 01092 isolines = x; 01093 } 01094 01095 void 01096 Slicer::setstriptessellation( REAL x, REAL y ) 01097 { 01098 assert(x > 0 && y > 0); 01099 du = x; 01100 dv = y; 01101 setDu( du ); 01102 } 01103 01104 void 01105 Slicer::slice_old( Arc_ptr loop ) 01106 { 01107 loop->markverts(); 01108 01109 Arc_ptr extrema[4]; 01110 loop->getextrema( extrema ); 01111 01112 unsigned int npts = loop->numpts(); 01113 TrimRegion::init( npts, extrema[0] ); 01114 01115 Mesher::init( npts ); 01116 01117 long ulines = uarray.init( du, extrema[1], extrema[3] ); 01118 //printf("ulines = %i\n", ulines); 01119 Varray varray; 01120 long vlines = varray.init( dv, extrema[0], extrema[2] ); 01121 //printf("vlines = %i\n", vlines); 01122 long botv = 0; 01123 long topv; 01124 TrimRegion::init( varray.varray[botv] ); 01125 getGridExtent( &extrema[0]->pwlArc->pts[0], &extrema[0]->pwlArc->pts[0] ); 01126 01127 for( long quad=0; quad<varray.numquads; quad++ ) { 01128 backend.surfgrid( uarray.uarray[0], 01129 uarray.uarray[ulines-1], 01130 ulines-1, 01131 varray.vval[quad], 01132 varray.vval[quad+1], 01133 varray.voffset[quad+1] - varray.voffset[quad] ); 01134 01135 for( long i=varray.voffset[quad]+1; i <= varray.voffset[quad+1]; i++ ) { 01136 topv = botv++; 01137 advance( topv - varray.voffset[quad], 01138 botv - varray.voffset[quad], 01139 varray.varray[botv] ); 01140 if( i == vlines ) 01141 getPts( extrema[2] ); 01142 else 01143 getPts( backend ); 01144 getGridExtent(); 01145 if( isolines ) { 01146 outline(); 01147 } else { 01148 if( canTile() ) 01149 coveAndTile(); 01150 else 01151 mesh(); 01152 } 01153 } 01154 } 01155 } 01156 01157 01158 void 01159 Slicer::outline( void ) 01160 { 01161 GridTrimVertex upper, lower; 01162 Hull::init( ); 01163 01164 backend.bgnoutline(); 01165 while( (nextupper( &upper )) ) { 01166 if( upper.isGridVert() ) 01167 backend.linevert( upper.g ); 01168 else 01169 backend.linevert( upper.t ); 01170 } 01171 backend.endoutline(); 01172 01173 backend.bgnoutline(); 01174 while( (nextlower( &lower )) ) { 01175 if( lower.isGridVert() ) 01176 backend.linevert( lower.g ); 01177 else 01178 backend.linevert( lower.t ); 01179 } 01180 backend.endoutline(); 01181 } 01182 01183 01184 void 01185 Slicer::outline( Arc_ptr jarc ) 01186 { 01187 jarc->markverts(); 01188 01189 if( jarc->pwlArc->npts >= 2 ) { 01190 backend.bgnoutline(); 01191 for( int j = jarc->pwlArc->npts-1; j >= 0; j-- ) 01192 backend.linevert( &(jarc->pwlArc->pts[j]) ); 01193 backend.endoutline(); 01194 } 01195 } 01196 01197 Generated on Sun May 27 2012 04:23:41 for ReactOS by
1.7.6.1
|