ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

subdivider.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.