Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensubdivider.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 * subdivider.cxx 00037 * 00038 */ 00039 00040 #include "glimports.h" 00041 #include "myassert.h" 00042 #include "mystdio.h" 00043 #include "subdivider.h" 00044 #include "arc.h" 00045 #include "bezierarc.h" 00046 #include "bin.h" 00047 #include "renderhints.h" 00048 #include "backend.h" 00049 #include "mapdesc.h" 00050 #include "quilt.h" 00051 #include "patchlist.h" 00052 #include "patch.h" 00053 #include "nurbsconsts.h" 00054 #include "trimvertpool.h" 00055 #include "simplemath.h" 00056 00057 #include "polyUtil.h" //for function area() 00058 00059 //#define PARTITION_TEST 00060 #ifdef PARTITION_TEST 00061 #include "partitionY.h" 00062 #include "monoTriangulation.h" 00063 #include "dataTransform.h" 00064 #include "monoChain.h" 00065 00066 #endif 00067 00068 00069 #define OPTIMIZE_UNTRIMED_CASE 00070 00071 00072 Bin* 00073 Subdivider::makePatchBoundary( const REAL *from, const REAL *to ) 00074 { 00075 Bin* ret = new Bin(); 00076 REAL smin = from[0]; 00077 REAL smax = to[0]; 00078 REAL tmin = from[1]; 00079 REAL tmax = to[1]; 00080 00081 pjarc = 0; 00082 00083 Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 ); 00084 arctessellator.bezier( jarc, smin, smax, tmin, tmin ); 00085 ret->addarc( jarc ); 00086 pjarc = jarc->append( pjarc ); 00087 00088 jarc = new(arcpool) Arc( arc_right, 0 ); 00089 arctessellator.bezier( jarc, smax, smax, tmin, tmax ); 00090 ret->addarc( jarc ); 00091 pjarc = jarc->append( pjarc ); 00092 00093 jarc = new(arcpool) Arc( arc_top, 0 ); 00094 arctessellator.bezier( jarc, smax, smin, tmax, tmax ); 00095 ret->addarc( jarc ); 00096 pjarc = jarc->append( pjarc ); 00097 00098 jarc = new(arcpool) Arc( arc_left, 0 ); 00099 arctessellator.bezier( jarc, smin, smin, tmax, tmin ); 00100 ret->addarc( jarc ); 00101 jarc->append( pjarc ); 00102 00103 assert( jarc->check() != 0 ); 00104 return ret; 00105 } 00106 00107 /*--------------------------------------------------------------------------- 00108 * Subdivider - construct a subdivider 00109 *--------------------------------------------------------------------------- 00110 */ 00111 00112 Subdivider::Subdivider( Renderhints& r, Backend& b ) 00113 : slicer( b ), 00114 arctessellator( trimvertexpool, pwlarcpool ), 00115 arcpool( sizeof( Arc), 1, "arcpool" ), 00116 bezierarcpool( sizeof( BezierArc ), 1, "Bezarcpool" ), 00117 pwlarcpool( sizeof( PwlArc ), 1, "Pwlarcpool" ), 00118 renderhints( r ), 00119 backend( b ) 00120 { 00121 } 00122 00123 void 00124 Subdivider::setJumpbuffer( JumpBuffer *j ) 00125 { 00126 jumpbuffer = j; 00127 } 00128 00129 /*--------------------------------------------------------------------------- 00130 * clear - reset all state after possible error condition 00131 *--------------------------------------------------------------------------- 00132 */ 00133 00134 void 00135 Subdivider::clear( void ) 00136 { 00137 trimvertexpool.clear(); 00138 arcpool.clear(); 00139 pwlarcpool.clear(); 00140 bezierarcpool.clear(); 00141 } 00142 00143 /*--------------------------------------------------------------------------- 00144 * ~Subdivider - destroy a subdivider 00145 *--------------------------------------------------------------------------- 00146 */ 00147 00148 Subdivider::~Subdivider( void ) 00149 { 00150 } 00151 00152 /*--------------------------------------------------------------------------- 00153 * addArc - add a bezier arc to a trim loop and to a bin 00154 *--------------------------------------------------------------------------- 00155 */ 00156 void 00157 Subdivider::addArc( REAL *cpts, Quilt *quilt, long _nuid ) 00158 { 00159 BezierArc *bezierArc = new(bezierarcpool) BezierArc; 00160 Arc *jarc = new(arcpool) Arc( arc_none, _nuid ); 00161 jarc->pwlArc = 0; 00162 jarc->bezierArc = bezierArc; 00163 bezierArc->order = quilt->qspec->order; 00164 bezierArc->stride = quilt->qspec->stride; 00165 bezierArc->mapdesc = quilt->mapdesc; 00166 bezierArc->cpts = cpts; 00167 initialbin.addarc( jarc ); 00168 pjarc = jarc->append( pjarc ); 00169 } 00170 00171 /*--------------------------------------------------------------------------- 00172 * addArc - add a pwl arc to a trim loop and to a bin 00173 *--------------------------------------------------------------------------- 00174 */ 00175 00176 void 00177 Subdivider::addArc( int npts, TrimVertex *pts, long _nuid ) 00178 { 00179 Arc *jarc = new(arcpool) Arc( arc_none, _nuid ); 00180 jarc->pwlArc = new(pwlarcpool) PwlArc( npts, pts ); 00181 initialbin.addarc( jarc ); 00182 pjarc = jarc->append( pjarc ); 00183 } 00184 00185 void 00186 Subdivider::beginQuilts( void ) 00187 { 00188 qlist = 0; 00189 } 00190 00191 void 00192 Subdivider::addQuilt( Quilt *quilt ) 00193 { 00194 quilt->next = qlist; 00195 qlist = quilt; 00196 } 00197 00198 /*--------------------------------------------------------------------------- 00199 * drawSurfaces - main entry point for surface tessellation 00200 *--------------------------------------------------------------------------- 00201 */ 00202 00203 void 00204 Subdivider::drawSurfaces( long nuid ) 00205 { 00206 renderhints.init( ); 00207 00208 if (qlist == NULL) 00209 { 00210 //initialbin could be nonempty due to some errors 00211 freejarcs(initialbin); 00212 return; 00213 } 00214 00215 for( Quilt *q = qlist; q; q = q->next ) { 00216 if( q->isCulled( ) == CULL_TRIVIAL_REJECT ) { 00217 freejarcs( initialbin ); 00218 return; 00219 } 00220 } 00221 00222 00223 REAL from[2], to[2]; 00224 qlist->getRange( from, to, spbrkpts, tpbrkpts ); 00225 #ifdef OPTIMIZE_UNTRIMED_CASE 00226 //perform optimization only when the samplng method is 00227 //DOMAIN_DISTANCE and the display methdo is either 00228 //fill or outline_polygon. 00229 int optimize = (is_domain_distance_sampling && (renderhints.display_method != N_OUTLINE_PATCH)); 00230 #endif 00231 00232 if( ! initialbin.isnonempty() ) { 00233 #ifdef OPTIMIZE_UNTRIMED_CASE 00234 if(! optimize ) 00235 { 00236 00237 makeBorderTrim( from, to ); 00238 } 00239 #else 00240 makeBorderTrim( from, to ); 00241 #endif 00242 } else { 00243 REAL rate[2]; 00244 qlist->findRates( spbrkpts, tpbrkpts, rate ); 00245 00246 if( decompose( initialbin, min(rate[0], rate[1]) ) ) 00247 mylongjmp( jumpbuffer, 31 ); 00248 } 00249 00250 backend.bgnsurf( renderhints.wiretris, renderhints.wirequads, nuid ); 00251 00252 #ifdef PARTITION_TEST 00253 if( initialbin.isnonempty() && spbrkpts.end-2 == spbrkpts.start && 00254 tpbrkpts.end-2 == tpbrkpts.start) 00255 { 00256 for(int i=spbrkpts.start; i<spbrkpts.end-1; i++){ 00257 for(int j=tpbrkpts.start; j<tpbrkpts.end-1; j++){ 00258 Real pta[2], ptb[2]; 00259 pta[0] = spbrkpts.pts[i]; 00260 ptb[0] = spbrkpts.pts[i+1]; 00261 pta[1] = tpbrkpts.pts[j]; 00262 ptb[1] = tpbrkpts.pts[j+1]; 00263 qlist->downloadAll(pta, ptb, backend); 00264 00265 directedLine *poly; 00266 00267 { 00268 00269 poly = bin_to_DLineLoops(initialbin); 00270 00271 poly=poly->deleteDegenerateLinesAllPolygons(); 00272 00273 sampledLine* retSampledLines; 00274 //printf("before MC_partition\n"); 00275 poly = MC_partitionY(poly, &retSampledLines); 00276 //printf("after MC_partition\n"); 00277 00278 } 00279 00280 00281 { 00282 primStream pStream(5000,5000); 00283 directedLine* temp; 00284 00285 for(temp=poly; temp != NULL; temp=temp->getNextPolygon()) 00286 00287 monoTriangulation(temp, &pStream); 00288 00289 slicer.evalStream(&pStream); 00290 00291 } 00292 //need to clean up space 00293 } 00294 } 00295 freejarcs( initialbin ); 00296 backend.endsurf(); 00297 return; 00298 00299 /* 00300 printf("num_polygons=%i\n", poly->numPolygons()); 00301 printf("num_edges=%i\n", poly->numEdgesAllPolygons()); 00302 poly->writeAllPolygons("zloutputFile"); 00303 return; 00304 { 00305 primStream pStream(20,20); 00306 for(directedLine* tempD = poly; tempD != NULL; tempD = tempD->getNextPolygon()) 00307 monoTriangulation(tempD, &pStream); 00308 } 00309 return; 00310 */ 00311 } 00312 #endif //PARTITION_TEST 00313 00314 00315 #ifdef OPTIMIZE_UNTRIMED_CASE 00316 if( (!initialbin.isnonempty()) && optimize ) 00317 { 00318 int i,j; 00319 int num_u_steps; 00320 int num_v_steps; 00321 for(i=spbrkpts.start; i<spbrkpts.end-1; i++){ 00322 for(j=tpbrkpts.start; j<tpbrkpts.end-1; j++){ 00323 Real pta[2], ptb[2]; 00324 pta[0] = spbrkpts.pts[i]; 00325 ptb[0] = spbrkpts.pts[i+1]; 00326 pta[1] = tpbrkpts.pts[j]; 00327 ptb[1] = tpbrkpts.pts[j+1]; 00328 qlist->downloadAll(pta, ptb, backend); 00329 00330 num_u_steps = (int) (domain_distance_u_rate * (ptb[0]-pta[0])); 00331 num_v_steps = (int) (domain_distance_v_rate * (ptb[1]-pta[1])); 00332 00333 if(num_u_steps <= 0) num_u_steps = 1; 00334 if(num_v_steps <= 0) num_v_steps = 1; 00335 00336 backend.surfgrid(pta[0], ptb[0], num_u_steps, 00337 ptb[1], pta[1], num_v_steps); 00338 backend.surfmesh(0,0,num_u_steps,num_v_steps); 00339 00340 00341 00342 continue; 00343 /* the following is left for reference purpose, don't delete 00344 { 00345 Bin* tempSource; 00346 Patchlist patchlist(qlist, pta, ptb); 00347 patchlist.getstepsize(); 00348 00349 tempSource=makePatchBoundary(pta, ptb); 00350 00351 tessellation(*tempSource, patchlist); 00352 00353 render(*tempSource); 00354 delete tempSource; 00355 } 00356 */ 00357 } 00358 } 00359 } 00360 else 00361 subdivideInS( initialbin ); 00362 #else 00363 00364 subdivideInS( initialbin ); 00365 #endif 00366 00367 backend.endsurf(); 00368 00369 } 00370 00371 void 00372 Subdivider::subdivideInS( Bin& source ) 00373 { 00374 if( renderhints.display_method == N_OUTLINE_PARAM ) { 00375 outline( source ); 00376 freejarcs( source ); 00377 } else { 00378 setArcTypeBezier(); 00379 setNonDegenerate(); 00380 splitInS( source, spbrkpts.start, spbrkpts.end ); 00381 } 00382 } 00383 00384 00385 /*--------------------------------------------------------------------------- 00386 * splitInS - split a patch and a bin by an isoparametric line 00387 *--------------------------------------------------------------------------- 00388 */ 00389 00390 void 00391 Subdivider::splitInS( Bin& source, int start, int end ) 00392 { 00393 if( source.isnonempty() ) { 00394 if( start != end ) { 00395 int i = start + (end - start) / 2; 00396 Bin left, right; 00397 split( source, left, right, 0, spbrkpts.pts[i] ); 00398 splitInS( left, start, i ); 00399 splitInS( right, i+1, end ); 00400 } else { 00401 if( start == spbrkpts.start || start == spbrkpts.end ) { 00402 freejarcs( source ); 00403 } else if( renderhints.display_method == N_OUTLINE_PARAM_S ) { 00404 outline( source ); 00405 freejarcs( source ); 00406 } else { 00407 setArcTypeBezier(); 00408 setNonDegenerate(); 00409 s_index = start; 00410 splitInT( source, tpbrkpts.start, tpbrkpts.end ); 00411 } 00412 } 00413 } 00414 } 00415 00416 /*--------------------------------------------------------------------------- 00417 * splitInT - split a patch and a bin by an isoparametric line 00418 *--------------------------------------------------------------------------- 00419 */ 00420 00421 void 00422 Subdivider::splitInT( Bin& source, int start, int end ) 00423 { 00424 if( source.isnonempty() ) { 00425 if( start != end ) { 00426 int i = start + (end - start) / 2; 00427 Bin left, right; 00428 split( source, left, right, 1, tpbrkpts.pts[i] ); 00429 splitInT( left, start, i ); 00430 splitInT( right, i+1, end ); 00431 } else { 00432 if( start == tpbrkpts.start || start == tpbrkpts.end ) { 00433 freejarcs( source ); 00434 } else if( renderhints.display_method == N_OUTLINE_PARAM_ST ) { 00435 outline( source ); 00436 freejarcs( source ); 00437 } else { 00438 t_index = start; 00439 setArcTypeBezier(); 00440 setDegenerate(); 00441 00442 REAL pta[2], ptb[2]; 00443 pta[0] = spbrkpts.pts[s_index-1]; 00444 pta[1] = tpbrkpts.pts[t_index-1]; 00445 00446 ptb[0] = spbrkpts.pts[s_index]; 00447 ptb[1] = tpbrkpts.pts[t_index]; 00448 qlist->downloadAll( pta, ptb, backend ); 00449 00450 Patchlist patchlist( qlist, pta, ptb ); 00451 /* 00452 printf("-------samplingSplit-----\n"); 00453 source.show("samplingSplit source"); 00454 */ 00455 samplingSplit( source, patchlist, renderhints.maxsubdivisions, 0 ); 00456 setNonDegenerate(); 00457 setArcTypeBezier(); 00458 } 00459 } 00460 } 00461 } 00462 00463 /*-------------------------------------------------------------------------- 00464 * samplingSplit - recursively subdivide patch, cull check each subpatch 00465 *-------------------------------------------------------------------------- 00466 */ 00467 00468 void 00469 Subdivider::samplingSplit( 00470 Bin& source, 00471 Patchlist& patchlist, 00472 int subdivisions, 00473 int param ) 00474 { 00475 if( ! source.isnonempty() ) return; 00476 00477 if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) { 00478 freejarcs( source ); 00479 return; 00480 } 00481 00482 patchlist.getstepsize(); 00483 00484 if( renderhints.display_method == N_OUTLINE_PATCH ) { 00485 tessellation( source, patchlist ); 00486 outline( source ); 00487 freejarcs( source ); 00488 return; 00489 } 00490 00491 //patchlist.clamp(); 00492 00493 tessellation( source, patchlist ); 00494 00495 if( patchlist.needsSamplingSubdivision() && (subdivisions > 0) ) { 00496 if( ! patchlist.needsSubdivision( 0 ) ) 00497 param = 1; 00498 else if( ! patchlist.needsSubdivision( 1 ) ) 00499 param = 0; 00500 else 00501 param = 1 - param; 00502 00503 Bin left, right; 00504 REAL mid = ( patchlist.pspec[param].range[0] + 00505 patchlist.pspec[param].range[1] ) * 0.5; 00506 split( source, left, right, param, mid ); 00507 Patchlist subpatchlist( patchlist, param, mid ); 00508 samplingSplit( left, subpatchlist, subdivisions-1, param ); 00509 samplingSplit( right, patchlist, subdivisions-1, param ); 00510 } else { 00511 setArcTypePwl(); 00512 setDegenerate(); 00513 nonSamplingSplit( source, patchlist, subdivisions, param ); 00514 setDegenerate(); 00515 setArcTypeBezier(); 00516 } 00517 } 00518 00519 void 00520 Subdivider::nonSamplingSplit( 00521 Bin& source, 00522 Patchlist& patchlist, 00523 int subdivisions, 00524 int param ) 00525 { 00526 if( patchlist.needsNonSamplingSubdivision() && (subdivisions > 0) ) { 00527 param = 1 - param; 00528 00529 Bin left, right; 00530 REAL mid = ( patchlist.pspec[param].range[0] + 00531 patchlist.pspec[param].range[1] ) * 0.5; 00532 split( source, left, right, param, mid ); 00533 Patchlist subpatchlist( patchlist, param, mid ); 00534 if( left.isnonempty() ) { 00535 if( subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT ) 00536 freejarcs( left ); 00537 else 00538 nonSamplingSplit( left, subpatchlist, subdivisions-1, param ); 00539 } 00540 if( right.isnonempty() ) { 00541 if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) 00542 freejarcs( right ); 00543 else 00544 nonSamplingSplit( right, patchlist, subdivisions-1, param ); 00545 } 00546 00547 } else { 00548 // make bbox calls 00549 patchlist.bbox(); 00550 backend.patch( patchlist.pspec[0].range[0], patchlist.pspec[0].range[1], 00551 patchlist.pspec[1].range[0], patchlist.pspec[1].range[1] ); 00552 00553 if( renderhints.display_method == N_OUTLINE_SUBDIV ) { 00554 outline( source ); 00555 freejarcs( source ); 00556 } else { 00557 setArcTypePwl(); 00558 setDegenerate(); 00559 findIrregularS( source ); 00560 monosplitInS( source, smbrkpts.start, smbrkpts.end ); 00561 } 00562 } 00563 } 00564 00565 /*-------------------------------------------------------------------------- 00566 * tessellation - set tessellation of interior and boundary of patch 00567 *-------------------------------------------------------------------------- 00568 */ 00569 00570 void 00571 Subdivider::tessellation( Bin& bin, Patchlist &patchlist ) 00572 { 00573 // tessellate unsampled trim curves 00574 tessellate( bin, patchlist.pspec[1].sidestep[1], patchlist.pspec[0].sidestep[1], 00575 patchlist.pspec[1].sidestep[0], patchlist.pspec[0].sidestep[0] ); 00576 00577 // set interior sampling rates 00578 slicer.setstriptessellation( patchlist.pspec[0].stepsize, patchlist.pspec[1].stepsize ); 00579 00580 //added by zl: set the order which will be used in slicer.c++ 00581 slicer.set_ulinear( (patchlist.get_uorder() == 2)); 00582 slicer.set_vlinear( (patchlist.get_vorder() == 2)); 00583 00584 // set boundary sampling rates 00585 stepsizes[0] = patchlist.pspec[1].stepsize; 00586 stepsizes[1] = patchlist.pspec[0].stepsize; 00587 stepsizes[2] = patchlist.pspec[1].stepsize; 00588 stepsizes[3] = patchlist.pspec[0].stepsize; 00589 } 00590 00591 /*--------------------------------------------------------------------------- 00592 * monosplitInS - split a patch and a bin by an isoparametric line 00593 *--------------------------------------------------------------------------- 00594 */ 00595 00596 void 00597 Subdivider::monosplitInS( Bin& source, int start, int end ) 00598 { 00599 if( source.isnonempty() ) { 00600 if( start != end ) { 00601 int i = start + (end - start) / 2; 00602 Bin left, right; 00603 split( source, left, right, 0, smbrkpts.pts[i] ); 00604 monosplitInS( left, start, i ); 00605 monosplitInS( right, i+1, end ); 00606 } else { 00607 if( renderhints.display_method == N_OUTLINE_SUBDIV_S ) { 00608 outline( source ); 00609 freejarcs( source ); 00610 } else { 00611 setArcTypePwl(); 00612 setDegenerate(); 00613 findIrregularT( source ); 00614 monosplitInT( source, tmbrkpts.start, tmbrkpts.end ); 00615 } 00616 } 00617 } 00618 } 00619 00620 /*--------------------------------------------------------------------------- 00621 * monosplitInT - split a patch and a bin by an isoparametric line 00622 *--------------------------------------------------------------------------- 00623 */ 00624 00625 void 00626 Subdivider::monosplitInT( Bin& source, int start, int end ) 00627 { 00628 if( source.isnonempty() ) { 00629 if( start != end ) { 00630 int i = start + (end - start) / 2; 00631 Bin left, right; 00632 split( source, left, right, 1, tmbrkpts.pts[i] ); 00633 monosplitInT( left, start, i ); 00634 monosplitInT( right, i+1, end ); 00635 } else { 00636 if( renderhints.display_method == N_OUTLINE_SUBDIV_ST ) { 00637 outline( source ); 00638 freejarcs( source ); 00639 } else { 00640 /* 00641 printf("*******render\n"); 00642 source.show("source\n"); 00643 */ 00644 render( source ); 00645 freejarcs( source ); 00646 } 00647 } 00648 } 00649 } 00650 00651 00652 /*---------------------------------------------------------------------------- 00653 * findIrregularS - determine points of non-monotonicity is s direction 00654 *---------------------------------------------------------------------------- 00655 */ 00656 00657 void 00658 Subdivider::findIrregularS( Bin& bin ) 00659 { 00660 assert( bin.firstarc()->check() != 0 ); 00661 00662 smbrkpts.grow( bin.numarcs() ); 00663 00664 for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { 00665 REAL *a = jarc->prev->tail(); 00666 REAL *b = jarc->tail(); 00667 REAL *c = jarc->head(); 00668 00669 if( b[1] == a[1] && b[1] == c[1] ) continue; 00670 00671 //corrected code 00672 if((b[1]<=a[1] && b[1] <= c[1]) || 00673 (b[1]>=a[1] && b[1] >= c[1])) 00674 { 00675 //each arc (jarc, jarc->prev, jarc->next) is a 00676 //monotone arc consisting of multiple line segements. 00677 //it may happen that jarc->prev and jarc->next are the same, 00678 //that is, jarc->prev and jarc form a closed loop. 00679 //In such case, a and c will be the same. 00680 if(a[0]==c[0] && a[1] == c[1]) 00681 { 00682 if(jarc->pwlArc->npts >2) 00683 { 00684 c = jarc->pwlArc->pts[jarc->pwlArc->npts-2].param; 00685 } 00686 else 00687 { 00688 assert(jarc->prev->pwlArc->npts>2); 00689 a = jarc->prev->pwlArc->pts[jarc->prev->pwlArc->npts-2].param; 00690 } 00691 00692 } 00693 if(area(a,b,c) < 0) 00694 { 00695 smbrkpts.add(b[0]); 00696 } 00697 00698 } 00699 00700 /* old code, 00701 if( b[1] <= a[1] && b[1] <= c[1] ) { 00702 if( ! ccwTurn_tr( jarc->prev, jarc ) ) 00703 smbrkpts.add( b[0] ); 00704 } else if( b[1] >= a[1] && b[1] >= c[1] ) { 00705 if( ! ccwTurn_tl( jarc->prev, jarc ) ) 00706 smbrkpts.add( b[0] ); 00707 } 00708 */ 00709 00710 } 00711 00712 smbrkpts.filter(); 00713 } 00714 00715 /*---------------------------------------------------------------------------- 00716 * findIrregularT - determine points of non-monotonicity in t direction 00717 * where one arc is parallel to the s axis. 00718 *---------------------------------------------------------------------------- 00719 */ 00720 00721 void 00722 Subdivider::findIrregularT( Bin& bin ) 00723 { 00724 assert( bin.firstarc()->check() != 0 ); 00725 00726 tmbrkpts.grow( bin.numarcs() ); 00727 00728 for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { 00729 REAL *a = jarc->prev->tail(); 00730 REAL *b = jarc->tail(); 00731 REAL *c = jarc->head(); 00732 00733 if( b[0] == a[0] && b[0] == c[0] ) continue; 00734 00735 if( b[0] <= a[0] && b[0] <= c[0] ) { 00736 if( a[1] != b[1] && b[1] != c[1] ) continue; 00737 if( ! ccwTurn_sr( jarc->prev, jarc ) ) 00738 tmbrkpts.add( b[1] ); 00739 } else if ( b[0] >= a[0] && b[0] >= c[0] ) { 00740 if( a[1] != b[1] && b[1] != c[1] ) continue; 00741 if( ! ccwTurn_sl( jarc->prev, jarc ) ) 00742 tmbrkpts.add( b[1] ); 00743 } 00744 } 00745 tmbrkpts.filter( ); 00746 } 00747 00748 /*----------------------------------------------------------------------------- 00749 * makeBorderTrim - if no user input trimming data then create 00750 * a trimming curve around the boundaries of the Quilt. The curve consists of 00751 * four Jordan arcs, one for each side of the Quilt, connected, of course, 00752 * head to tail. 00753 *----------------------------------------------------------------------------- 00754 */ 00755 00756 void 00757 Subdivider::makeBorderTrim( const REAL *from, const REAL *to ) 00758 { 00759 REAL smin = from[0]; 00760 REAL smax = to[0]; 00761 REAL tmin = from[1]; 00762 REAL tmax = to[1]; 00763 00764 pjarc = 0; 00765 00766 Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 ); 00767 arctessellator.bezier( jarc, smin, smax, tmin, tmin ); 00768 initialbin.addarc( jarc ); 00769 pjarc = jarc->append( pjarc ); 00770 00771 jarc = new(arcpool) Arc( arc_right, 0 ); 00772 arctessellator.bezier( jarc, smax, smax, tmin, tmax ); 00773 initialbin.addarc( jarc ); 00774 pjarc = jarc->append( pjarc ); 00775 00776 jarc = new(arcpool) Arc( arc_top, 0 ); 00777 arctessellator.bezier( jarc, smax, smin, tmax, tmax ); 00778 initialbin.addarc( jarc ); 00779 pjarc = jarc->append( pjarc ); 00780 00781 jarc = new(arcpool) Arc( arc_left, 0 ); 00782 arctessellator.bezier( jarc, smin, smin, tmax, tmin ); 00783 initialbin.addarc( jarc ); 00784 jarc->append( pjarc ); 00785 00786 assert( jarc->check() != 0 ); 00787 } 00788 00789 /*---------------------------------------------------------------------------- 00790 * render - renders all monotone regions in a bin and frees the bin 00791 *---------------------------------------------------------------------------- 00792 */ 00793 00794 void 00795 Subdivider::render( Bin& bin ) 00796 { 00797 bin.markall(); 00798 00799 #ifdef N_ISOLINE_S 00800 slicer.setisolines( ( renderhints.display_method == N_ISOLINE_S ) ? 1 : 0 ); 00801 #else 00802 slicer.setisolines( 0 ); 00803 #endif 00804 00805 for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { 00806 if( jarc->ismarked() ) { 00807 assert( jarc->check( ) != 0 ); 00808 Arc_ptr jarchead = jarc; 00809 do { 00810 jarc->clearmark(); 00811 jarc = jarc->next; 00812 } while (jarc != jarchead); 00813 slicer.slice( jarc ); 00814 } 00815 } 00816 } 00817 00818 /*--------------------------------------------------------------------------- 00819 * outline - render the trimmed patch by outlining the boundary 00820 *--------------------------------------------------------------------------- 00821 */ 00822 00823 void 00824 Subdivider::outline( Bin& bin ) 00825 { 00826 bin.markall(); 00827 for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { 00828 if( jarc->ismarked() ) { 00829 assert( jarc->check( ) != 0 ); 00830 Arc_ptr jarchead = jarc; 00831 do { 00832 slicer.outline( jarc ); 00833 jarc->clearmark(); 00834 jarc = jarc->prev; 00835 } while (jarc != jarchead); 00836 } 00837 } 00838 } 00839 00840 /*--------------------------------------------------------------------------- 00841 * freejarcs - free all arcs in a bin 00842 *--------------------------------------------------------------------------- 00843 */ 00844 00845 void 00846 Subdivider::freejarcs( Bin& bin ) 00847 { 00848 bin.adopt(); /* XXX - should not be necessary */ 00849 00850 Arc_ptr jarc; 00851 while( (jarc = bin.removearc()) != NULL ) { 00852 if( jarc->pwlArc ) jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0; 00853 if( jarc->bezierArc) jarc->bezierArc->deleteMe( bezierarcpool ); jarc->bezierArc = 0; 00854 jarc->deleteMe( arcpool ); 00855 } 00856 } 00857 00858 /*---------------------------------------------------------------------------- 00859 * tessellate - tessellate all Bezier arcs in a bin 00860 * 1) only accepts linear Bezier arcs as input 00861 * 2) the Bezier arcs are stored in the pwlArc structure 00862 * 3) only vertical or horizontal lines work 00863 * -- should 00864 * 1) represent Bezier arcs in BezierArc structure 00865 * (this requires a multitude of changes to the code) 00866 * 2) accept high degree Bezier arcs (hard) 00867 * 3) map the curve onto the surface to determine tessellation 00868 * 4) work for curves of arbitrary geometry 00869 *---------------------------------------------------------------------------- 00870 */ 00871 00872 00873 void 00874 Subdivider::tessellate( Bin& bin, REAL rrate, REAL trate, REAL lrate, REAL brate ) 00875 { 00876 for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { 00877 if( jarc->isbezier( ) ) { 00878 assert( jarc->pwlArc->npts == 2 ); 00879 TrimVertex *pts = jarc->pwlArc->pts; 00880 REAL s1 = pts[0].param[0]; 00881 REAL t1 = pts[0].param[1]; 00882 REAL s2 = pts[1].param[0]; 00883 REAL t2 = pts[1].param[1]; 00884 00885 jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0; 00886 00887 switch( jarc->getside() ) { 00888 case arc_left: 00889 assert( s1 == s2 ); 00890 arctessellator.pwl_left( jarc, s1, t1, t2, lrate ); 00891 break; 00892 case arc_right: 00893 assert( s1 == s2 ); 00894 arctessellator.pwl_right( jarc, s1, t1, t2, rrate ); 00895 break; 00896 case arc_top: 00897 assert( t1 == t2 ); 00898 arctessellator.pwl_top( jarc, t1, s1, s2, trate ); 00899 break; 00900 case arc_bottom: 00901 assert( t1 == t2 ); 00902 arctessellator.pwl_bottom( jarc, t1, s1, s2, brate ); 00903 break; 00904 case arc_none: 00905 (void) abort(); 00906 break; 00907 } 00908 assert( ! jarc->isbezier() ); 00909 assert( jarc->check() != 0 ); 00910 } 00911 } 00912 } Generated on Sat May 26 2012 04:22:18 for ReactOS by
1.7.6.1
|